Routing

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.

POST
/mapmatching

Snaps an ordered GPS trace to a plausible route on the road network (Valhalla Meili).

  • Send mode and 2 to 1,000 waypoints in a JSON body; each location is [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, interpolated or merged.
  • The response is a GeoJSON FeatureCollection with one MultiLineString feature, per-waypoint match metadata (waypoints), one leg and road-level steps.

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.

Authorization

queryapiKey<token>

Your API key from the dashboard, sent as ?apiKey=<key>.

Request Body

GPS trace and matching options. Must be a JSON object.

application/json
  1. body
mode*string

Travel profile used to decide which roads can plausibly connect the GPS measurements. drive represents a passenger car.

Value in"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).

Items2 <= items <= 1000
geocode_step_address?boolean

When 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.

Defaultfalse
lookup_step_osmtags?boolean

When true, adds osmtags to each matched step.

Deviation (empty): osmtags is always an empty object {}; there is no OSM tag store behind the engines.

Defaultfalse
lookup_osm_overlap?boolean

When true, adds overlaps to each matched step.

Deviation (empty): overlaps is always an empty array [].

Defaultfalse
lang?string

Language code for the step instruction text.

Default"en"
Value in"en""de""es""fr""hi""it""pt""ru""sl""sv""ca""cs"

Response Body

Matched route as a GeoJSON FeatureCollection.

application/json
  1. response
type*unknown
features*array<>

Exactly one feature with the matched route.

bbox?array<number>

[minLon, minLat, maxLon, maxLat] of the matched route.

Items4 <= items <= 4
Example Request
curl -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      ]    }  ]}'
Example Response
{  "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  ]}