Match a GPS trace to the road network
Signed in? Open this endpoint in the dashboard playground, which uses your organization automatically. Signed out, use Try in Playground below with your API key.
Snaps an ordered GPS trace to a plausible route on the road network (Valhalla Meili).
- Send
modeand 2 to 1,000waypointsin a JSON body; eachlocationis[longitude, latitude]. - Timestamps are used only when every waypoint has one and they are strictly increasing. Bearings are passed through when given.
- Waypoint order is preserved; each point is
matched,unmatched,interpolatedormerged. - The response is a GeoJSON
FeatureCollectionwith oneMultiLineStringfeature, per-waypoint match metadata (waypoints), one leg and road-levelsteps.
Deviation (unsupported): at least 2 waypoints are required (1 returns 400); transit and approximated_transit modes are not accepted.
Deviation (approximated): geocode_step_address returns only street, state, country and country_code; step instruction carries only text.
Deviation (empty): lookup_step_osmtags yields osmtags: {} and lookup_osm_overlap yields overlaps: [] on every step.
Deviation (extra): a trace that cannot be matched to any road returns 400 ("The trace could not be matched to the road network").
This response has no place_id or datasource fields.
Not supported (not read by the gateway): step fields elevation, elevation_gain, max_elevation, min_elevation, admin_area, rightside, traversability, from_stop_*, to_stop_*; instruction fields other than text; application/geo+json and XML output.
apiKey<token>Your API key from the dashboard, sent as ?apiKey=<key>.
GPS trace and matching options. Must be a JSON object.
application/json- body
mode*stringTravel profile used to decide which roads can plausibly connect the GPS measurements. drive represents a passenger car.
"walk""hike""scooter""motorcycle""drive""light_truck""bicycle""mountain_bike""road_bike""bus""medium_truck""truck""truck_dangerous_goods""heavy_truck""long_truck"waypoints*array<>Ordered GPS measurements to match. Input order is preserved; the API does not optimize or reorder these points.
Deviation (unsupported): at least 2 waypoints are required (Geoapify's schema allows 1; a single point cannot be matched and returns 400).
2 <= items <= 1000geocode_step_address?booleanWhen true, adds an address object to each matched step.
Deviation (approximated): the address is derived without a geocoder: street (the way name), state, country and country_code (lower case, from the routing tiles' admin data). suburb, city, county and postcode are never returned.
falselookup_step_osmtags?booleanWhen true, adds osmtags to each matched step.
Deviation (empty): osmtags is always an empty object {}; there is no OSM tag store behind the engines.
falselookup_osm_overlap?booleanWhen true, adds overlaps to each matched step.
Deviation (empty): overlaps is always an empty array [].
falselang?stringLanguage code for the step instruction text.
"en""en""de""es""fr""hi""it""pt""ru""sl""sv""ca""cs"Matched route as a GeoJSON FeatureCollection.
application/json- response
type*unknownfeatures*array<>Exactly one feature with the matched route.
bbox?array<number>[minLon, minLat, maxLon, maxLat] of the matched route.
4 <= items <= 4curl -X POST 'https://api.data.graphitelab.ai/v1/mapmatching' \ -H 'Content-Type: application/json' \ -d '{ "mode": "drive", "waypoints": [ { "location": [ -86.15813, 39.769 ] }, { "location": [ -86.15813, 39.7705 ] }, { "location": [ -86.15813, 39.772 ] }, { "location": [ -86.15813, 39.7735 ] }, { "location": [ -86.15813, 39.775 ] }, { "location": [ -86.15813, 39.7765 ] } ]}'{ "type": "FeatureCollection", "features": [ { "type": "Feature", "properties": { "mode": "drive", "distance": 827, "time": 74.43, "legs": [ { "time": 74.43, "distance": 827, "steps": [ { "from_index": 0, "to_index": 1, "time": 1.17, "distance": 13, "osm_way_id": 113084204, "instruction": { "text": "Drive north on North Meridian Street." }, "toll": false, "ferry": false, "bridge": false, "tunnel": false, "roundabout": false, "speed": 40, "speed_limit": 40, "surface": "paved", "lane_count": 2, "road_class": "tertiary", "name": "North Meridian Street", "begin_bearing": 2, "end_bearing": 2 }, { "from_index": 1, "to_index": 2, "time": 2.79, "distance": 31, "osm_way_id": 113084204, "toll": false, "ferry": false, "bridge": false, "tunnel": false, "roundabout": false, "speed": 40, "speed_limit": 40, "surface": "paved", "lane_count": 2, "road_class": "tertiary", "name": "North Meridian Street", "begin_bearing": 2, "end_bearing": 2 }, { "from_index": 2, "to_index": 3, "time": 3.78, "distance": 42, "osm_way_id": 113084204, "toll": false, "ferry": false, "bridge": false, "tunnel": false, "roundabout": false, "speed": 40, "speed_limit": 40, "surface": "paved", "lane_count": 2, "road_class": "tertiary", "name": "North Meridian Street", "begin_bearing": 1, "end_bearing": 1 } ] } ], "waypoints": [ { "original_index": 0, "location": [ -86.15802, 39.769051 ], "original_location": [ -86.15813, 39.769 ], "match_type": "matched", "match_distance": 10.917381, "leg_index": 0, "step_index": 0 }, { "original_index": 1, "location": [ -86.157968, 39.770495 ], "original_location": [ -86.15813, 39.7705 ], "match_type": "matched", "match_distance": 13.773137, "leg_index": 0, "step_index": 7 } ] }, "geometry": { "type": "MultiLineString", "coordinates": [ [ [ -86.15802, 39.769051 ], [ -86.158016, 39.769167 ], [ -86.158003, 39.769441 ], [ -86.157723, 39.776491 ] ] ] } } ], "bbox": [ -86.15802, 39.769051, -86.157723, 39.776491 ]}