Calculate Sea Route
Get the sailing route between two or more points, navigating around land
Endpoint
Description
Calculates the actual sea route between coordinates, navigating around coastlines and islands. Uses OSM-derived land/water rasters at 25 m resolution with A* pathfinding for accurate maritime routing.
Supports both simple point-to-point routes and multi-waypoint routes. Long routes are automatically split into segments and stitched together.
Responses are cached for 24 hours.
Authentication
Send X-API-Key: YOUR_API_KEY on every call from outside charter.boats — without it Cloudflare bot protection answers with an HTML 403 page, not JSON. Call it from your server: this route sends no CORS headers. See Authentication.
Query Parameters
Use either from+to or waypoints, not both.
| Parameter | Type | Required | Description |
|---|---|---|---|
from | string | Yes* | Origin as longitude,latitude |
to | string | Yes* | Destination as longitude,latitude |
waypoints | string | Yes* | Multiple points as lon,lat|lon,lat|... (min 2) |
draught | number | No | Boat draught in metres (alias: draft). When set, water shallower than the boat can safely use is penalised — the route prefers deeper water and only crosses shallows when no reasonable alternative exists. Omitted = all water costs the same. |
* Provide either from+to or waypoints.
Shallow water is avoided, never forbidden: a 25 m grid cannot see individual rocks, so depth influences route preference and is not a depth guarantee. Charts and local knowledge remain the authority on where a hull may actually go.
Example Requests
Point to Point
Multi-Waypoint
With Draught
Example Response
Returns a GeoJSON Feature with a LineString geometry. The coordinates array is [longitude, latitude] pairs (truncated above for readability).
Response Properties
| Property | Type | Description |
|---|---|---|
distance_km | number | Total route distance in kilometers |
distance_nm | number | Total route distance in nautical miles |
waypoints | number | Number of coordinates in the route geometry |
tiles_used | string[] | Coastline raster tiles used for pathfinding (e.g. raster_20.4_38.8) |
total_iterations | number | A* algorithm iterations |
segments | number | Number of route segments (always present; 1 for direct routes) |
fallback_segments | number|undefined | Count of segments the router could not route and replaced with a straight line (e.g. an endpoint on land). Any value above 0 means part of the geometry may cross land. Omitted on multi-segment routes when zero |
compute_ms | number | Computation time in milliseconds |
fallback | boolean|undefined | true only when nothing was routed — no coverage tile was touched and the solver never iterated — so the whole route is one straight line. Emitted on both single- and multi-segment routes; omitted otherwise. distance_km/distance_nm are great-circle in that case. A segment that was attempted and failed is counted in fallback_segments instead and does not necessarily set this flag, so check both. |
shallowest_band | number|undefined | Shallowest depth band the route crosses: 1 deeper than 3 m, 2 = 2–3 m, 3 = 1–2 m, 4 = under 1 m |
band_km | number[]|undefined | Kilometres of the route spent in each band, indexed by band number (index 0 unused) |
depth_data | boolean|undefined | true when at least one tile on the route carries surveyed depth bands. When false or absent, every water pixel reads as deep by default — treat shallowest_band: 1 as "not surveyed", not "sounded and clear". |
draught_m, max_safe_band | number|undefined | Echo of the requested draught and the deepest band it may safely use (single-segment routes only) |
Coverage
Land/water routing covers the Mediterranean and all charter regions at 25 m resolution, with worldwide coverage rolling out. Depth bands are being added progressively, starting with the Ionian; depth_data in the response says whether the route you asked for has them.
Requests outside coverage do not error — they return 200 with a straight-line
route and properties.fallback: true. Always check fallback and fallback_segments
rather than assuming a 200 means the path avoided land.
Fallback Behavior
The API falls back to a straight line in two distinct situations, reported differently:
- Nothing routed — no coastline tile covers the area (outside coverage, or open water
with no land in the way), so the solver never ran:
tiles_used: [],total_iterations: 0, and top-levelfallback: true. - A segment could not be routed — e.g. an endpoint on land or in an enclosed body of
water. That segment is a straight line and is counted in
fallback_segments. The top-levelfallbackis set only if nothing else on the route was routed either.
Either way the straight part is a great-circle line, so distance_km / distance_nm
ignore any land it crosses.