Free geocoding API: forward, reverse, and distance in one REST call
Your delivery app needs to convert a street address into latitude and longitude for routing. Google Maps Geocoding API costs $5 per 1,000 requests. For a startup doing 10,000 deliveries a day, that's $50/day on geocoding alone.
The botoi geo API covers forward geocoding, reverse geocoding, and distance calculation with three REST endpoints. Anonymous access handles 100 requests per day at no cost. Paid plans start at $9/month and cover all 150+ endpoints in the platform, not geocoding alone.
Forward geocoding: address to coordinates
The /v1/geo/geocode endpoint takes a street address and returns latitude,
longitude, and a standardized formatted address. One POST request:
curl -X POST https://api.botoi.com/v1/geo/geocode \
-H "Content-Type: application/json" \
-d '{"address": "1600 Amphitheatre Parkway, Mountain View, CA"}' Response:
{
"success": true,
"data": {
"latitude": 37.4224764,
"longitude": -122.0842499,
"formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
"place_name": "Googleplex",
"country": "United States",
"country_code": "US"
}
}
The response includes the country code, place name (when available), and a
formatted_address string you can store as the canonical version. Partial
addresses work too; the API resolves "Mountain View, CA" to coordinates for the city center.
Reverse geocoding: coordinates to address
A mobile app captures a GPS pin drop. You need a human-readable address for the receipt.
The /v1/geo/reverse endpoint takes latitude and longitude and breaks the
result into structured components:
curl -X POST https://api.botoi.com/v1/geo/reverse \
-H "Content-Type: application/json" \
-d '{"latitude": 37.4224, "longitude": -122.0842}' Response:
{
"success": true,
"data": {
"formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
"street": "Amphitheatre Pkwy",
"house_number": "1600",
"city": "Mountain View",
"state": "California",
"postal_code": "94043",
"country": "United States",
"country_code": "US"
}
} Every field is separated: street, house number, city, state, postal code, and country. You don't need to parse a single string to extract the city or zip code.
Distance calculation between two points
The /v1/geo/distance endpoint calculates the great-circle distance between
two coordinate pairs. It returns both kilometers and miles:
curl -X POST https://api.botoi.com/v1/geo/distance \
-H "Content-Type: application/json" \
-d '{"from": {"lat": 37.7749, "lng": -122.4194}, "to": {"lat": 34.0522, "lng": -118.2437}}' Response:
{
"success": true,
"data": {
"distance_km": 559.12,
"distance_miles": 347.42,
"from": { "lat": 37.7749, "lng": -122.4194 },
"to": { "lat": 34.0522, "lng": -118.2437 }
}
} San Francisco to Los Angeles: 559 km. The calculation uses the Haversine formula, which gives you straight-line distance across the Earth's surface. For proximity filters, delivery radius checks, and store locator features, this is the right metric.
Practical example: address validation at checkout
A customer types "123 Fake Stret, Nowhereville" into your checkout form. Syntax validation passes because it looks like an address. Geocoding catches the problem. If the API can't resolve the address to coordinates, the address is likely invalid.
async function validateAddress(address) {
const res = await fetch("https://api.botoi.com/v1/geo/geocode", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": process.env.BOTOI_API_KEY,
},
body: JSON.stringify({ address }),
});
const { success, data } = await res.json();
if (!success || !data.latitude) {
return { valid: false, suggestion: null };
}
return {
valid: true,
formatted: data.formatted_address,
coordinates: {
lat: data.latitude,
lng: data.longitude,
},
};
}
// Usage in a checkout form handler
const result = await validateAddress("1600 Amphitheatre Parkway, Mountain View");
if (!result.valid) {
// Show error: "We couldn't verify this address. Check for typos."
}
// Use result.formatted as the canonical address
// Use result.coordinates for delivery routing
This approach catches typos, nonexistent street names, and incomplete addresses before you
ship a package to nowhere. The formatted_address field gives you the
standardized version to store in your database.
Practical example: store locator
Given a user's coordinates (from browser geolocation or a geocoded address), find the three closest stores:
async function findNearestStore(userLat, userLng, stores) {
// Calculate distance from user to each store in parallel
const distances = await Promise.all(
stores.map(async (store) => {
const res = await fetch("https://api.botoi.com/v1/geo/distance", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": process.env.BOTOI_API_KEY,
},
body: JSON.stringify({
from: { lat: userLat, lng: userLng },
to: { lat: store.lat, lng: store.lng },
}),
});
const { data } = await res.json();
return { ...store, distance_km: data.distance_km };
})
);
// Sort by distance and return the closest 3
return distances
.sort((a, b) => a.distance_km - b.distance_km)
.slice(0, 3);
}
const stores = [
{ name: "Downtown", lat: 37.7849, lng: -122.4094 },
{ name: "Mission Bay", lat: 37.7699, lng: -122.3894 },
{ name: "Sunset", lat: 37.7549, lng: -122.4894 },
];
const nearest = await findNearestStore(37.7749, -122.4194, stores);
// Returns stores sorted by distance from the user For a small number of stores (under 50), parallel API calls work well. For hundreds of locations, do the Haversine calculation client-side and use the API only for the geocoding step.
Practical example: delivery radius check
A food delivery app needs to reject orders outside a 25 km radius from the kitchen. Check the distance before accepting the order:
async function isWithinDeliveryRadius(
warehouseLat, warehouseLng,
customerLat, customerLng,
maxRadiusKm
) {
const res = await fetch("https://api.botoi.com/v1/geo/distance", {
method: "POST",
headers: {
"Content-Type": "application/json",
"X-Api-Key": process.env.BOTOI_API_KEY,
},
body: JSON.stringify({
from: { lat: warehouseLat, lng: warehouseLng },
to: { lat: customerLat, lng: customerLng },
}),
});
const { data } = await res.json();
return {
eligible: data.distance_km <= maxRadiusKm,
distance_km: data.distance_km,
};
}
// Check if a customer is within 25 km of the warehouse
const check = await isWithinDeliveryRadius(
37.7749, -122.4194, // warehouse
37.3382, -121.8863, // customer in San Jose
25 // 25 km radius
);
if (!check.eligible) {
console.log(
`Customer is \${check.distance_km.toFixed(1)} km away. Outside delivery zone.`
);
} The check takes one API call and returns in under 100ms. Combine it with forward geocoding to go from a typed address to a delivery eligibility decision in two sequential requests.
Key points
-
/v1/geo/geocodeconverts street addresses to latitude/longitude with a standardized formatted address. Works with partial addresses and place names. -
/v1/geo/reverseconverts coordinates to a structured address with separate fields for street, city, state, postal code, and country. -
/v1/geo/distancecalculates great-circle distance between two points using the Haversine formula. Returns both km and miles. - Anonymous access allows 5 requests per minute and 100 per day. No API key required for testing or low-volume use.
- All three endpoints accept and return JSON. No query-string encoding, no XML parsing, no SDK installation. Any language with an HTTP client works.
Frequently asked questions
- Is the geocoding API free?
- Anonymous access is available at 5 requests per minute and 100 requests per day with IP-based rate limiting. No API key or account required. For higher throughput, paid plans start at $9/month with a single API key covering all 150+ endpoints.
- What is the difference between forward and reverse geocoding?
- Forward geocoding converts a street address or place name into latitude and longitude coordinates. Reverse geocoding does the opposite: it takes latitude and longitude coordinates and returns the nearest street address. The botoi API supports both via /v1/geo/geocode and /v1/geo/reverse.
- Does the distance endpoint return driving distance or straight-line distance?
- The /v1/geo/distance endpoint returns the great-circle (straight-line) distance between two points using the Haversine formula. It does not account for roads or driving routes. For delivery radius checks and proximity filters, straight-line distance is typically sufficient.
- What coordinate system does the API use?
- The API uses WGS 84 (EPSG:4326), the same coordinate system used by GPS devices, Google Maps, and OpenStreetMap. Latitude ranges from -90 to 90, longitude from -180 to 180.
- Can I use the geocoding API for batch processing?
- The API processes one address or coordinate pair per request. For batch geocoding, send multiple requests in parallel. On the free tier you can send 5 per minute. Paid plans support higher concurrency for processing thousands of addresses.
Try this API
Geocoding API — interactive playground and code examples
More tutorial posts
Start building with botoi
150+ API endpoints for lookup, text processing, image generation, and developer utilities. Free tier, no credit card.