Routing
The routing queries: directions between waypoints, suggestions shaped to a target distance, isochrones for reachable area, and matrix for travel-time and distance grids. Every routing query takes an activity that selects a routing profile tuned to its terrain and movement style.
Each activity routes on a profile tuned to its terrain and movement style. Directions availability varies: most activities support turn-by-turn routing, backcountry skiing is freehand-line only, and cycling activities are not yet available for routing. The GraphQL ActivitySlug enum uses the uppercase value; the Map Studio and Tile APIs use the lowercase, underscore-free wire form.
All coordinates are [longitude, latitude] in WGS 84. Distances are in meters, durations in seconds, elevations in meters above sea level, and gradients in degrees.
How activities route
Each activity selects a routing profile tuned to its terrain, together with a preference and a waypoint snapping tolerance:
- Preference. Most activities use balanced routing that favors pleasant, terrain-appropriate ways. Running and road cycling favor the fastest way. Professional trail takes the most-direct line, with no scenic bias.
- Waypoint snapping. A waypoint must lie within a snapping distance of a routable way, or the query is rejected. Most activities use the standard ~400 m tolerance; snowshoe walking relaxes it to a few kilometers for off-trail points; ski touring and professional trail remove the limit entirely, snapping each waypoint to the nearest way at any distance, so routes can start or end far off-network.
- Default speed. Each activity has a default speed used to estimate duration (for example ~4.5 km/h hiking, ~8 km/h professional trail, ~25 km/h road cycling). Override it per request with
speed.
Backcountry skiing is freehand-only: it has no routing profile, so directions, suggestions, isochrones, and matrix are not available for it. Cycling activities (gravel, mountain, road) are not yet available for routing.
directions
Compute a route between an ordered list of waypoints for a given activity. Returns one or more routes with distance, duration, elevation, geometry, and a surface and way type analysis.
Input
directions(input: DirectionsInput!)
activityActivitySlug!
Activity to use for routing. Selects the routing profile and default speed.
waypoints[[Float!]!]!
Ordered list of waypoints as [longitude, latitude] pairs. At least two are required, and at most 45 are accepted.
speedFloat
Travel speed in km/h. Overrides the activity's default speed and adjusts the estimated duration.
avoid[RouteHazard!]
Hazards to route around: TOLLWAY, RESTRICTED_ACCESS, or both. Omitted or empty routes normally. Naming a hazard costs a second routing pass only when the first route actually crosses one. Avoidance is best-effort — read avoidance on each route to learn whether it was applied.
Example
Response
DirectionsResult.routes is a list of DirectionsRoute. Each route carries:
distanceFloat!
Total route distance in meters.
durationFloat!
Estimated route duration in seconds.
elevationElevationSummary!
Altitude bounds, total ascent and descent, and the gradient range in degrees.
geometryGeoJSON!
Route path as a GeoJSON LineString. Coordinates are [longitude, latitude, altitude].
analysisGeometryAnalysis!
Surface, way type, and slope segments along the route. Always present, but the segment lists are empty for activities that do not support analysis: only hiking and trail running, professional trail, and running populate them. See analysis.
avoidanceAvoidanceOutcome!
What the request's avoid list achieved. See hazards and avoidance below.
summaryString!
Human-readable one-line summary, for example 10.8 km, ~3h10m, +1138m / -579m elevation, 49% path, 30% road, 9% street.
Run this query live: open it in the playground and try it against the schema.
Hazards and avoidance
Some ways carry a toll, and some carry an access restriction — private, destination-only, customers, delivery, permit, or forbidden outright. Every routed result reports what it crosses on analysis.advisories:
tollwayBoolean!
The route crosses at least one way that charges a toll for this activity's mode of travel.
restrictedAccessBoolean!
The route crosses at least one way carrying a genuine access restriction. Permissive ways — where the owner tolerates passage — do not raise this.
tollwayInfo[TollwayInfo!]!
Where, as coordinate index ranges. Empty when the routing graph carries no toll data.
roadAccessInfo[RoadAccessRestrictionInfo!]!
Where, as coordinate index ranges, each with the restrictions that apply. A way can carry several at once, so this one is a list per range.
suggestions never proposes a route through either. There is no avoid input and no opt-out: when no hazard-free candidate can be generated from the given points, the query fails with a validation error rather than returning one that crosses something. Proposing somewhere to go is a different act from a user deliberately routing across a private track.
directions can return one, because sometimes that is exactly what the user wants — a right of way they hold, a toll they will pay. It is the only query that does, so read advisories before you present the result. Pass avoid to route around them, and read avoidance to learn what happened:
suggestions
Generate route candidates that match a target distance for a given activity. Each candidate uses a different seed, producing a different route shape, so a client can offer the user several options ranked by proximity to the target.
No candidate crosses a tollway or an access-restricted way — see hazards and avoidance.
Input
suggestions(input: SuggestionsInput!)
activityActivitySlug!
Activity to use for routing.
start[Float!]!
Starting point as [longitude, latitude].
distanceFloat!
Target total distance for the route in meters, up to 200000. For a point-to-point route it must also be at least the straight-line distance between start and end.
candidatesInt!
Number of candidates to generate (1 to 10). Each uses a different random seed.
ascentFloat
Target elevation gain in meters. When set, candidates are also ranked by proximity to this value.
end[Float!]
End point as [longitude, latitude]. Omit to loop back to start; provide a different point for a point-to-point route shaped to the target distance.
pointsInt
default: 5
Number of shaping points (2 to 10). Higher values produce rounder loops. Only applies to loop routes.
speedFloat
Travel speed in km/h, overriding the activity default.
seedsSuggestionSeeds
Pin specific seeds into the result (include) and avoid others in the fresh candidate pool (exclude). Useful to reproduce or vary previously returned routes. A seed in both lists is a validation error.
Example
Response
SuggestionsResult.routes is a list of SuggestionRoute, sorted by proximity to the target distance. Each carries the same distance, duration, elevation, geometry, analysis, and summary as a directions route, plus:
seedInt!
The seed used to generate this candidate. Pass it back in seeds.include to reproduce the route or seeds.exclude to filter it out of fresh candidates. Reproducing a route also requires the same start, end, distance, and points.
isochrones
Compute reachability polygons from one or more origins for a given activity. Each range value yields one isochrone, so several ranges produce concentric polygons.
Input
isochrones(input: IsochronesInput!)
activityActivitySlug!
Activity to use for routing.
locations[[Float!]!]!
Origin points as [longitude, latitude] pairs.
range[Float!]!
Range values, in seconds for TIME or meters for DISTANCE. Multiple values produce concentric isochrones.
rangeTypeIsochronesRangeType!
Whether range is expressed in TIME (seconds) or DISTANCE (meters).
Example
Response
IsochronesResult.isochrones is a list of Isochrone, one per range value:
valueFloat!
Range value in seconds or meters, matching the input range type.
areaFloat
Area of the polygon in square meters.
reachFactorFloat
Ratio of the isochrone area to the theoretical area (0 to 1).
center[Float!]
Center point as [longitude, latitude]. Null when the routing provider reports no center for this isochrone: the value is forwarded verbatim from the provider, never reconstructed from the input location.
geometryGeoJSON!
Polygon geometry of the isochrone.
matrix
Compute a grid of travel durations and/or distances between locations for a given activity. Limit the grid to specific origins or destinations with the sources and destinations index lists.
Input
matrix(input: MatrixInput!)
activityActivitySlug!
Activity to use for routing.
locations[[Float!]!]!
Locations as [longitude, latitude] pairs.
metrics[MatrixMetric!]!
Metrics to compute. At least one of DISTANCE (meters) or DURATION (seconds).
sources[Int!]
Indices of locations to use as sources. When omitted, all locations are used.
destinations[Int!]
Indices of locations to use as destinations. When omitted, all locations are used.
Example
Response
MatrixResult carries a grid per requested metric. Each grid is a row-per-source array of values, with inner null entries marking unreachable pairs:
durations[[Float]!]
Duration grid in seconds. Present only when the DURATION metric was requested.
distances[[Float]!]
Distance grid in meters. Present only when the DISTANCE metric was requested.