User types "123 Main St" — you need latitude and longitude. GPS tracker sends coordinates — you need a readable address. Both are geocoding. One forward, one reverse.
Forward Geocoding
Address in, coordinates out.
const response = await fetch(
`https://api.apiverve.com/v1/geocoding?address=${encodeURIComponent('350 5th Ave, New York')}`,
{ headers: { 'x-api-key': 'YOUR_API_KEY' } }
);
const { data } = await response.json();
// { lat: 40.7484, lng: -73.9857, formatted: "350 5th Ave, New York, NY 10118" }
The API also cleans up the address. Partial input, full output.
Reverse Geocoding
Coordinates in, address out.
const response = await fetch(
`https://api.apiverve.com/v1/geocoding/reverse?lat=51.5074&lng=-0.1278`,
{ headers: { 'x-api-key': 'YOUR_API_KEY' } }
);
const { data } = await response.json();
// { formatted: "10 Downing St, London SW1A 2AA, UK" }
Mobile apps do this constantly. User taps a spot on the map, you show them what's there.
The "Main Street" Problem
"123 Main Street" exists in basically every American city. Without context, the API picks one — probably not the one you wanted.
Add constraints:
const params = new URLSearchParams({
address: '123 Main Street',
city: 'Boston',
state: 'MA',
country: 'US'
});
const url = `https://api.apiverve.com/v1/geocoding?${params}`;
More context = better results. If your app serves one country, hardcode the country. If it's regional, pass the region.
Multiple Results
Sometimes the API finds several matches. "Springfield" returns about 30 in the US alone.
const { data } = await response.json();
if (data.results.length > 1) {
// Let user pick, or take the first (highest confidence)
console.log('Multiple matches:', data.results.map(r => r.formatted));
}
Don't just grab the first one silently. Either show options or tell the user to be more specific.
Caching (Do This)
Addresses don't move. Once you've geocoded "350 5th Ave, New York" there's zero reason to geocode it again tomorrow.
// Redis example
const cacheKey = `geo:${address.toLowerCase().trim()}`;
const cached = await redis.get(cacheKey);
if (cached) return JSON.parse(cached);
const result = await geocodeAddress(address);
await redis.setex(cacheKey, 60 * 60 * 24 * 30, JSON.stringify(result)); // 30 days
return result;
30-day cache is conservative. Addresses change less often than you'd think.
Distance Between Two Points
Once you have coordinates, you probably want distance:
function haversine(lat1, lon1, lat2, lon2) {
const R = 6371; // Earth radius in km
const dLat = (lat2 - lat1) * Math.PI / 180;
const dLon = (lon2 - lon1) * Math.PI / 180;
const a = Math.sin(dLat/2) ** 2 +
Math.cos(lat1 * Math.PI/180) * Math.cos(lat2 * Math.PI/180) *
Math.sin(dLon/2) ** 2;
return R * 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1-a));
}
// NYC to LA
haversine(40.7128, -74.0060, 34.0522, -118.2437); // ~3936 km
That's straight-line distance. Driving distance requires a routing API — different beast entirely.
Real Uses
Store locator: Geocode all store addresses once, cache forever. When user searches, geocode their input, calculate distances, return sorted list.
Address validation: User enters address → geocode it → if it fails or returns low confidence, flag for review.
Delivery zones: Geocode destination, check if coordinates fall within your polygon. Simple point-in-polygon math.
Form autofill: User starts typing, you call geocoding autocomplete, they pick from suggestions. Cleaner data, fewer typos.
What Can Go Wrong
Ambiguous addresses: "Airport Road" exists everywhere. Add context or expect wrong results.
New construction: Brand new addresses might not exist in the geocoding database yet. Usually takes a few months.
International formats: Japanese addresses work differently than American ones. The API handles this, but your UI might not display it correctly.
Typos: "123 Main Stret" might work (fuzzy matching) or might fail completely. Depends on the provider.
That covers 90% of geocoding use cases. Grab an API key and try it — the free tier handles plenty of testing. For the other location APIs, check out IP Lookup (geolocate by IP, no address needed) and Timezone (get timezone from coordinates).
Originally published at APIVerve Blog
Top comments (0)