Map Matching V4

This documentation is for the legacy v4 API. See the documentation for the v5 API.

The Mapbox Map Matching API snaps fuzzy, inaccurate traces from a GPS unit or a phone to the OpenStreetMap road and path network using the Directions API. This produces clean paths that can be displayed on a map or used for other analysis.


  • Maximum 60 requests per minute
  • Maximum 100 coordinates per request
  • Results must be displayed on a Mapbox map using one of our libraries or SDKs

For high volume or other use cases, contact us.

Retrieve a match

Returns a path on the road and path network closest to the input traces.

URL ParameterDescription
profileA directions profile ID; either mapbox.driving, mapbox.walking, or mapbox.cycling
Query ParameterDescription
Format of the returned geometry. Allowed values are: geojson (default, as LineString), polyline (documentation) with precision 6, false (no geometry, but matched points)
An integer in meters indicating the assumed precision of the used tracking device. Use higher numbers (5-10) for noisy traces and lower numbers (1-3) for clean traces. The default value is 4.

NOTE: the polyline coordinates in the Map Matching V4 are incorrectly returned as longitude,latitude pairs, they should be latitude,longitude. The Map Matching V5 API corrects this bug, but it is maintained here for backward compatibility for existing customers.

Example request

$ curl -X POST \
  --header "Content-Type:application/json" \
  -d @trace.json \
>>> from mapbox import MapMatcher
>>> service = MapMatcher()
>>> response = service.match(line, profile='mapbox.driving')
var mapboxClient = new MapboxClient('{your_access_token}');

    type: 'Feature',
    properties: {
      coordTimes: [
    geometry: {
      type: 'LineString',
      coordinates: [
        [13.419756889343262, 52.50171780290061],
        [13.419885635375975, 52.50237416816131],
        [13.420631289482117, 52.50294888790448]
  function(err, res) {
    // res is a document with directions
mapbox mapmatching trace.geojson
MapboxMapMatching client = new MapboxMapMatching.Builder()
// This API cannot be accessed with the Mapbox Objective-C libraries
// This API cannot be accessed with the Mapbox Swift libraries

Example request body

Request body must be one GeoJSON Feature with a LineString geometry. The LineString may have up to 100 positions.

If your traces are in GPX or KML format, you can use toGeoJSON to transform them to GeoJSON.

  "type": "Feature",
  "properties": {
    "coordTimes": [
  "geometry": {
    "type": "LineString",
    "coordinates": [
      [13.418946862220764, 52.50055852688439],
      [13.419011235237122, 52.50113000479732],
      [13.419756889343262, 52.50171780290061],
      [13.419885635375975, 52.50237416816131],
      [13.420631289482117, 52.50294888790448]
an array of timestamps corresponding to positions in the LineString; can be numbers in Unix time (seconds since the Unix epoch) or strings in RFC 3339 format.

It is recommended to include timestamps, since they help improve the quality of the matching. The timestamps must be ascending. For best results, your timestamps should have a sample rate of about 5 seconds.

Some pre-processing tips to achieve the best results:

  • The Map Matching API is limited to processing traces with up to 100 coordinates. If you need to process longer traces, you can split the trace and make multiple requests.
  • Clusters of points (like a person waiting at a train crossing for a few minutes) often don't add more information to a trace and should be removed.
  • Map matching works best with a sample rate of 5 seconds between points. If your trace has a higher sample rate, you may want to downsample your trace.
  • geojson-tidy removes clusters and re-samples traces. If provided traces are known to be of poor quality, GeoJSON tidying must be done otherwise map matching results can also expected to be poor.

Example response

The response is a GeoJSON FeatureCollection aligned with the OpenStreetMap road/path network. It may include one or more GeoJSON Features; on clean matches, only one feature is returned, but when the matching algorithm cannot decide the correct match between two points, it will omit that line and create several sub-matches, each as a feature. The higher the number of features, the more likely that the input traces are poorly aligned to the road network.

  "code": "Ok",
  "type": "FeatureCollection",
  "features": [
      "type": "Feature",
      "geometry": {
        "type": "LineString",
        "coordinates": [
          [13.418805, 52.500599],
          [13.418851, 52.500659],
          [13.419145, 52.501095],
          [13.419276, 52.501286],
          [13.419618, 52.501754],
          [13.419981, 52.502249],
          [13.420042, 52.502335],
          [13.420494, 52.502984]
      "properties": {
        "confidence": 0.8165256193474186,
        "distance": 120,
        "duration": 31,
        "matchedPoints": [
          [13.418805122375488, 52.50059890747071],
          [13.419144630432129, 52.50109481811523],
          [13.419617652893066, 52.50175094604492],
          [13.420042037963867, 52.50233459472656],
          [13.420494079589844, 52.50298309326172]
        "indices": [0, 1, 2, 3, 4]
codea string depicting the state of the response; see below for options
geometrygeometry type for returned line; will be a GeoJSON LineString. If geometry option in request was set to polyline, will be an encoded polyline
confidencea number between 0 (low) and 1 (high) indicating level of confidence in match
distancethe total distance traveled in the matching in meters
durationthe expected travel time in the matching in seconds
matchedPointsan array of coordinate pairs denoting the location an input point was matched with
indicesa list of indices connecting matchedPoints with input points

All routing responses will include a code property that describes the type of result. If a server error occurs, the HTTP status code will be 500 or higher and the response will not include a code property.

Code optionDescription
OkNormal case
NoMatchThe input did not produce any matches. features will be an empty array.
TooManyCoordinatesThere are more than 100 points in the request.
InvalidInputmessage will hold an explanation of the invalid input.
ProfileNotFoundProfile should be mapbox.driving, mapbox.walking, or mapbox.cycling.