Check whether an address is within a delivery zone radius
Decide in one step whether an address is in your delivery zone: one measured 6.283267 km from the hub in a straight line falls inside a 10 km radius. Enter both coordinate pairs and the radius. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
Worked example
- Hub lat
- 40.7128
- Hub lon
- -74.006
- Address lat
- 40.73061
- Address lon
- -73.935242
- Max radius km
- 10
- Distance km
- 6.283267
A delivery promise often begins with one practical question: is this address close enough to the assigned hub to receive service? Supply the hub latitude and longitude, the delivery address latitude and longitude, and the maximum radius in kilometres. The capability validates both coordinate pairs, calculates their straight-line great-circle distance, and returns a clear within-zone decision alongside the measured distance. It is deterministic, requires no map provider, and is suitable for checkout checks, dispatch prefilters, and repeatable operational rules.
How the delivery zone decision is calculated
The capability treats the hub as the centre of a circular service zone and the submitted maximum radius as its boundary. It calculates the shortest surface distance between the hub and address with the haversine formula and a fixed mean Earth radius of 6371.0088 kilometres. The result is a great-circle distance, sometimes described as straight-line or as-the-crow-flies distance.
Boundary comparisons use the full internal value rather than the displayed rounded number, which prevents presentation rounding from changing eligibility. This model is intentionally simple and auditable. It does not inspect streets, bridges, rivers, traffic, driving restrictions, or a hand-drawn delivery polygon.
Use it when the commercial rule is genuinely radial, or as an inexpensive first filter before sending eligible candidates to a more costly road-routing or territory system.
Preparing coordinates and interpreting validation errors
Latitudes are decimal degrees from -90 through 90, while longitudes are decimal degrees from -180 through 180. The service radius must be zero or greater; a zero radius permits only an address at the same coordinate as the hub. A common integration mistake is reversing latitude and longitude.
Because many valid longitudes fall inside the latitude range, a reversed pair can occasionally pass validation yet describe a different place, so establish one field order across geocoding, storage, and this request. Coordinates should represent decimal-degree geographic positions, not projected map metres, postal codes, or raw address text. Geocode addresses before this check and retain enough decimal precision for your operational scale.
The capability validates coordinates, but it cannot confirm that a syntactically valid point corresponds to the intended building, entrance, or delivery pin.
Using radius checks safely in checkout and dispatch
For multi-hub operations, evaluate the address against each active hub, discard false results, and rank the remaining candidates by distance, inventory, workload, or promised time. A radius match does not guarantee a drivable route or a successful delivery. Coastal geography, restricted roads, toll boundaries, ferries, gated facilities, and local operating territories can all make a nearby point impractical.
For those cases, follow the radial prefilter with routing or polygon checks. Validation failures should be corrected at the data source, especially when they reveal swapped fields or incomplete geocoding, rather than being treated as automatically outside the zone.
What you can do with it
Checkout delivery eligibility
Decide whether a geocoded customer address is close enough to a fulfilment hub before displaying a same-day or local-delivery option.
Nearest eligible hub selection
Check one address against multiple hubs, remove candidates beyond their service radii, and pass the remaining hubs to inventory and workload ranking.
Dispatch data quality control
Validate stored hub and stop coordinates while recording a repeatable distance and zone result for operational review or exception handling.
FAQ
Does the distance follow roads?
No. It is the great-circle distance over the Earth's surface. Road length, traffic, barriers, and access restrictions require a routing service.
Can I submit a street address instead of coordinates?
No. Geocode the address first, then submit its decimal-degree latitude and longitude together with the hub coordinates.
How much does one check cost?
The calculation is deterministic and does not call a third-party maps provider.
Does an address exactly on the radius count as inside the zone?
Yes. The address is in the zone when its distance is less than or equal to the radius, and the comparison uses the full, unrounded distance, so the rounding shown on screen never changes the decision.
What happens if I swap latitude and longitude?
Many swapped pairs still look valid, because most longitudes also fit the latitude range, yet they describe a different place. Keep one fixed order everywhere, from geocoding to storage to this check.
Related tools
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/ecom/last-mile-delivery-zone-check \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"hub_lat":40.7128,"hub_lon":-74.006,"address_lat":40.73061,"address_lon":-73.935242,"max_radius_km":10}'const res = await fetch("https://api.kit.forhosting.com/ecom/last-mile-delivery-zone-check", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"hub_lat": 40.7128,
"hub_lon": -74.006,
"address_lat": 40.73061,
"address_lon": -73.935242,
"max_radius_km": 10
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/ecom/last-mile-delivery-zone-check",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"hub_lat": 40.7128,
"hub_lon": -74.006,
"address_lat": 40.73061,
"address_lon": -73.935242,
"max_radius_km": 10
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/ecom/last-mile-delivery-zone-check", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"hub_lat":40.7128,"hub_lon":-74.006,"address_lat":40.73061,"address_lon":-73.935242,"max_radius_km":10}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"hub_lat":40.7128,"hub_lon":-74.006,"address_lat":40.73061,"address_lon":-73.935242,"max_radius_km":10}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/ecom/last-mile-delivery-zone-check", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"hub_lat": 40.7128,
"hub_lon": -74.006,
"address_lat": 40.73061,
"address_lon": -73.935242,
"max_radius_km": 10
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "ecom.last_mile_delivery_zone_check",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |
Technical notes
How the delivery zone decision is calculated
If the unrounded calculated distance is less than or exactly equal to the maximum radius, within_zone is true; otherwise it is false. The response also includes distance_km, rounded to six decimal places, and echoes max_radius_km so downstream logs and decisions remain self-explanatory.
Preparing coordinates and interpreting validation errors
Provide five finite numeric values: hub_lat, hub_lon, address_lat, address_lon, and max_radius_km. Both endpoints are accepted. Missing values, non-numeric text, infinities, and out-of-range coordinates return invalid_input instead of a misleading zone decision.
Using radius checks safely in checkout and dispatch
At checkout, call the capability after an address has been resolved to coordinates, then use within_zone as one input to the delivery offer. Keep distance_km in the order audit record so customer support can reconstruct why an option was shown. Also choose the radius from an explicit business policy rather than silently changing it per request. Each successful API item costs $0.002.
Technical questions
Is an address exactly on the radius boundary included?
Yes. within_zone is true when the full calculated distance is less than or equal to max_radius_km.
What happens when a coordinate pair is invalid?
Missing, non-finite, or out-of-range latitude or longitude values return an invalid_input error rather than a distance or zone decision.