Route total distance
Get the total length of a route through several GPS points, leg by leg: the three waypoints in the example add up to 327.98509 km, or 203.800486 miles, as the crow flies. Each leg is listed in kilometres too. Free in your browser.
- Free
- Runs in your browser
- No sign-up
- Your data stays on your device
Run — free
When a path is defined as an ordered list of GPS coordinates — a delivery tour, a hiking track export, a flight plan, or a multi-city road-trip sketch — the first number product teams usually need is the total as-the-crow-flies length of that polyline. Pairwise distance tools only cover two points at a time; closed-ring perimeter tools force you back to the start. This route total distance calculator accepts two or more waypoints, measures the great-circle arc of every consecutive leg with the haversine formula on a fixed spherical Earth, and returns the summed length in kilometres, statute miles, and metres, plus each leg in kilometres.
How multi-waypoint great-circle route distance is computed
A multi-waypoint route is an ordered open polyline on the Earth: point one to point two, point two to point three, and so on until the last coordinate. This capability does not close the path back to the origin; if you need the length of a closed geographic ring such as a parcel or delivery zone, use a polygon perimeter tool instead. Statute miles use the international conversion of 1609.344 metres per mile.
The model is spherical, not WGS84-ellipsoidal Vincenty or Karney geodesics, so results can differ by a small fraction of a percent from survey-grade libraries — usually fine for logistics prefilters, trip planners, sports summaries, and analytics buckets, and not a substitute for cadastral surveying. Antipodal and near-identical points are supported; internal clamping keeps floating-point edge cases from producing NaN, and identical consecutive waypoints contribute zero length.
Where route total distance fits in products and pipelines
Pair with a geocoder only when you start from addresses; once you have lat and lon, avoid re-geocoding just to measure length. For turn-by-turn drive distance, traffic ETAs, or elevation profiles, keep a dedicated routing engine — this tool is great-circle polyline length, not road network cost. For closed boundaries use polygon perimeter; for a single origin–destination pair a two-point haversine call is enough, but multi-city and multi-checkpoint products need the summed route form so one request replaces n−1 pairwise calls and guarantees consistent ordering.
Failed validation does not consume balance. Keep lists modest for interactive UX, pin rounded totals in tests, and you get a small, auditable building block for every channel that KIT already serves.
What you can do with it
Multi-stop delivery and field-service sketches
Sum great-circle legs between depot and customer pins to estimate tour length before spending budget on full road-routing APIs.
GPX and GeoJSON track distance headlines
Reduce an exported hiking, cycling, or flight track to total km, mi, and m plus per-leg segments for dashboards and share cards.
Classroom GIS and bulk itinerary enrichment
Add crow-flies multi-city route totals to lesson data, trip planners, or CSV rows without standing up a GIS stack.
FAQ
Is the path closed back to the first waypoint?
No. This tool measures an open polyline. For a closed geographic ring perimeter, use a polygon perimeter calculator instead.
What is the minimum number of waypoints?
At least two {lat, lon} points are required.
Is this the same as driving or road distance?
No. Results are as-the-crow-flies on a sphere. Road distance, traffic, and elevation require a routing engine; use this for polyline length and prefilters.
Which units does the total come in?
Kilometres by default, or statute miles or metres if you prefer. All three totals are always shown, plus every leg in kilometres, and a mile is counted as 1609.344 metres.
What happens if I swap latitude and longitude?
If both numbers still fall within the valid ranges, the route is measured anyway and the total is meaningless. Check which value is latitude and which is longitude before you measure a long list.
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/geo/route-total-distance \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"waypoints":[{"lat":40.7128,"lon":-74.006},{"lat":39.9526,"lon":-75.1652},{"lat":38.9072,"lon":-77.0369}]}'const res = await fetch("https://api.kit.forhosting.com/geo/route-total-distance", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"waypoints": [
{
"lat": 40.7128,
"lon": -74.006
},
{
"lat": 39.9526,
"lon": -75.1652
},
{
"lat": 38.9072,
"lon": -77.0369
}
]
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/geo/route-total-distance",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"waypoints": [
{
"lat": 40.7128,
"lon": -74.006
},
{
"lat": 39.9526,
"lon": -75.1652
},
{
"lat": 38.9072,
"lon": -77.0369
}
]
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/geo/route-total-distance", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"waypoints":[{"lat":40.7128,"lon":-74.006},{"lat":39.9526,"lon":-75.1652},{"lat":38.9072,"lon":-77.0369}]}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"waypoints":[{"lat":40.7128,"lon":-74.006},{"lat":39.9526,"lon":-75.1652},{"lat":38.9072,"lon":-77.0369}]}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/geo/route-total-distance", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"waypoints": [
{
"lat": 40.7128,
"lon": -74.006
},
{
"lat": 39.9526,
"lon": -75.1652
},
{
"lat": 38.9072,
"lon": -77.0369
}
]
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "geo.route_total_distance",
"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
Input contract, units, aliases, and validation errors
Latitude must lie in the closed interval from −90 to 90; longitude must lie in −180 to 180 inclusive. Optional unit selects which value fills the primary total field: km (default), mi, or m. A single waypoint, an empty array, or more than five thousand points fails validation before any distance is computed. POST a JSON body with a required waypoints array of at least two objects, each carrying latitude and longitude in WGS84-style decimal degrees. Values outside those ranges, non-finite numbers, missing fields, empty strings, or non-object array items are rejected with invalid_input and are never charged. The array accepts the transport aliases points, coordinates, and route; each vertex accepts latitude for lat and longitude or lng for lon so GeoJSON-ish and mobile clients can map fields without a reshape step. Regardless of unit, every successful response always includes total_km, total_mi, and total_m so clients can display multiple units without a second call. The payload also reports waypoint_count, segment_count (always one less than the waypoint count for a valid open route), segments_km as the ordered list of leg lengths, and earth_radius_km equal to 6371 for auditability. Swapping lat and lon is a common client bug: if both numbers still fall inside both ranges the call may succeed with a nonsense path, so always verify north-south versus east-west before bulk jobs. Pricing is a flat $0.002 per successful item on the API; the in-browser tier-A path is designed for interactive checks without wiring a full pipeline first.
Where route total distance fits in products and pipelines
Use this endpoint whenever you already hold ordered coordinates and need a transparent crow-flies tour length: multi-stop delivery sketches before road routing, GPX or GeoJSON track exports reduced to a single headline distance, classroom GIS labs comparing polyline length to planar maps, sports apps summarizing as-the-crow-flies segments between checkpoints, and fraud or risk features that compare claimed itineraries to straight-line bounds. Call it from a Worker, a backend job, or a script: pass the waypoint list, read total and the three unit fields, optionally store segments_km next to each leg for UI breakdowns.
Technical questions
How is route total distance calculated?
Each consecutive waypoint pair is measured with the haversine great-circle formula on a sphere of radius 6371 km; leg lengths are summed to produce total_km, total_mi, and total_m.
How much does the API cost?
Each successful request is priced at $0.002 from your prepaid ForHosting KIT balance. Failed validation is not charged. The browser tool is free.