Map Matching

Map Matching API version

This documentation is for v5 of the Map Matching API. For information about the earlier version, see the v4 documentation.

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.

Turn-by-turn directions in the Map Matching API

The Map Matching API can also return a full directions response to queries using the optional steps parameter. If you plan use the Map Matching API to return turn-by-turn directions, note that it does not consider all road rules and traffic conditions. To access up-to-date traffic and road conditions for navigation purposes, use the Mapbox Directions API.

For information on how the Map Matching API is billed, visit the Pricing by product guide.

Retrieve a match

get
/matching/v5/{profile}/{coordinates}.json

Return a path on the road and path network that is closest to the input traces.

Required parametersDescription
profileA Mapbox Directions routing profile ID.
Profile IDDescription
mapbox/drivingCar travel times, distances, or both.
mapbox/walkingPedestrian and hiking travel times, distances, or both
mapbox/cyclingBicycle travel times, distances, or both
mapbox/driving-trafficCar travel times, distances, or both as informed by traffic data
coordinatesA semicolon-separated list of {longitude},{latitude} coordinate pairs to visit in order. There can be between 2 and 100 coordinates.

You can further refine the results from this endpoint with the following optional parameters:

Optional parametersDescription
annotationsReturn additional metadata along the route. You can include several annotations as a comma-separated list. Must be used in conjunction with overview=full.
Possible valuesDescription
distanceThe distance between each pair of coordinates in meters.
durationThe duration between each pair of coordinates in seconds.
speedThe speed between each pair of coordinates in meters per second.
maxspeed
Beta
The maximum speed limit between the coordinates of a segment. This annotation is only available for the mapbox/driving and mapbox/driving-traffic profiles.
See the route leg object for more details on what is included with annotations.
approachesA semicolon-separated list indicating the side of the road from which to approach waypoints in a requested route. Accepts unrestricted (default, route can arrive at the waypoint from either side of the road) or curb (route will arrive at the waypoint on the driving_side of the region). If provided, the number of approaches must be the same as the number of waypoints. However, you can skip a coordinate and show its position in the list with the ; separator. If waypoints is not specified (so all coordinates are treated as waypoints), the list of approaches must be the same length as the list of coordinates. Must be used in combination with steps=true.
geometriesThe format of the returned geometry. Allowed values are: geojson (as LineString), polyline (default, a polyline with precision 5), and polyline6 (a polyline with precision 6).
languageThe language of returned turn-by-turn text instructions. See supported languages. The default is en (English). Must be used in combination with steps=true.
overviewThe type of returned overview geometry. Can be full (the most detailed geometry available), simplified (default, a simplified version of the full geometry), or false (no overview geometry).
radiusesA semicolon-separated list indicating the maximum distance a coordinate can be moved to snap to the road network in meters. If provided, the number of radiuses must be the same as the number of coordinates. However, you can skip a coordinate and show its position in the list with the ; separator. Values can be a number between 0.0 and 50.00. Use higher numbers (20-50) for noisy traces and lower numbers (1-10) for clean traces. The default value is 5. A NoSegment error is returned if no routable road is found within the radius.
stepsWhether to return steps and turn-by-turn instructions (true) or not (false, default).
tidyWhether to remove clusters and re-samples traces for improved map matching results (true) or not (false, default).
timestampsA semicolon-separated list of numbers in Unix time (in other words, seconds since 1/1/1970 UTC) that correspond to each input coordinate. If provided, the number of timestamps must be the same as the number of coordinates, no coordinates can be skipped, and the timestamps must occur in ascending order. For best results, timestamps should have a sample rate of about 5 seconds.
waypoint_namesA semicolon-separated list of custom names for waypoints. These names will be used for the arrival instruction in banners and voice instructions. Values can be any string, and the total number of all characters (including semicolons) cannot exceed 500. The list of waypoint_names must be the same length as the list of waypoints, but you can skip a waypoint and show its position with the ; separator. If waypoints is not specified (so all coordinates are treated as waypoints), the list of waypoint_names must be the same length as the list of coordinates.
waypointsA semicolon-separated list indicating which input coordinates should be treated as waypoints. If a coordinate is treated as a waypoint, it receives arrival and departure events in the match object's route. If a list of waypoints is not provided, all coordinates are treated as waypoints. Each item in the list must be the zero-based index of an input coordinate, and the list must include 0 (the index of the first coordinate) and the index of the last coordinate. Waypoints are most useful in combination with steps=true and requests based on traces with high sample rates.
ignoreIgnore certain routing restrictions when map matching. You can include several ignore options as a comma-separated list (for example, ignore=access,oneways,restrictions).
Possible valuesDescription
accessIgnore access restrictions related to mode of travel.
onewaysIgnore one-way restrictions.
restrictionsIgnore other restrictions, such as time-based or turn restrictions.
This option is only available for the mapbox/driving profile.
linear_referencesReturns map-agnostic location identifiers of the roads along a route. When true, a successful response will include a key linear_references, the value of which is an array of base64-encoded OpenLR location references, one for each graph edge of the road network matched by the input trace. This option is only available for the mapbox/driving profile.

Some pre-processing tips to achieve the best results:

  • Timestamps improve the quality of the matching and are highly recommended.
  • 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 can negatively impact map-matching quality. We recommend that you tidy the trace (remove clusters and provide a uniform sample rate). You can use the tidy=true query parameter or pre-process your traces with external tools like geojson-tidy.
  • 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.
  • With the waypoints parameter specified, traces that would normally return with sub-matches will error. We recommend tidying traces before using them with the waypoints parameter.

Example request: Retrieve a match

# Basic request that returns a match object with route legs between each waypoint

$ curl "https://api.mapbox.com/matching/v5/mapbox/driving/-117.17282,32.71204;-117.17288,32.71225;-117.17293,32.71244;-117.17292,32.71256;-117.17298,32.712603;-117.17314,32.71259;-117.17334,32.71254?access_token=YOUR_MAPBOX_ACCESS_TOKEN"

# Request to access speed limit information using the maxspeed annotation

$ curl "https://api.mapbox.com/matching/v5/mapbox/driving/-122.39636,37.79129;-122.39732,37.79283;-122.39606,37.79349?annotations=maxspeed&overview=full&geometries=geojson&access_token=YOUR_MAPBOX_ACCESS_TOKEN"

# Request with the approaches parameter set to 'curb' for each waypoint

$ curl "https://api.mapbox.com/matching/v5/mapbox/driving/-117.17282,32.71204;-117.17288,32.71225;-117.17293,32.71244;-117.17292,32.71256?approaches=curb;curb;curb;curb&access_token=YOUR_MAPBOX_ACCESS_TOKEN"


# Request with various parameters, returns a match object with one route leg between the first and last waypoints

$ curl "https://api.mapbox.com/matching/v5/mapbox/driving/2.344003,48.85805;2.34675,48.85727;2.34868,48.85936;2.34955,48.86084;2.34955,48.86088;2.34962,48.86102;2.34982,48.86125?steps=true&tidy=true&waypoints=0;6&waypoint_names=Home;Work&banner_instructions=true&access_token=YOUR_MAPBOX_ACCESS_TOKEN"
Endpoint support

Mapbox wrapper libraries help you integrate Mapbox APIs into your existing application. The following SDKs support this endpoint:

See the SDK documentation for details and examples of how to use the relevant methods to query this endpoint.

Use HTTP POST to retrieve a match

The Map Matching API also supports access using the HTTP POST method. HTTP POST should be used for large requests, since the Map Matching API has a size limit of approximately 8100 bytes on GET request URLs. POST requests are still subject to your account's request size limits.

Learn more about this process in the Using HTTP POST section.

Response: Retrieve a match

The match response object contains one or more match objects, as well as one or more tracepoint objects.

PropertyDescription
codeA string indicating the state of the response. The potential values are listed in the Map Matching status codes section.
matchingsAn array of match objects.
tracepointsAn array of tracepoint objects that represent the location an input point was matched with, in the order in which they were matched. If a trace point is omitted by the Map Matching API because it is an outlier, the entry will be null.

With clean matches, only one match object is returned. When the algorithm cannot decide the correct match between two points, it will omit that line and return several sub-matches as match objects. The higher the number of sub-match match objects, the more likely it is that the input traces are poorly aligned to the road network.

Example response: Retrieve a match

{
  "matchings": [{
    "confidence": 4.615758886217236e-10,
    "geometry": {
      "coordinates": [
        [
          -122.397484,
          37.792809
        ],
        [
          -122.39746,
          37.792693
        ],
        [
          -122.39745,
          37.792645
        ],
        [
          -122.397437,
          37.792586
        ],
        [
          -122.397431,
          37.792558
        ],
        [
          -122.39741,
          37.792466
        ],
        [
          -122.397404,
          37.79244
        ],
        [
          -122.397225,
          37.792579
        ],
        [
          -122.396623,
          37.793057
        ],
        [
          -122.39636,
          37.793276
        ],
        [
          -122.396075,
          37.793502
        ]
      ],
      "type": "LineString"
    },
    "legs": [{
      "annotation": {
        "maxspeed": [{
            "speed": 48,
            "unit": "km/h"
          },
          {
            "speed": 48,
            "unit": "km/h"
          },
          {
            "speed": 48,
            "unit": "km/h"
          },
          {
            "speed": 48,
            "unit": "km/h"
          },
          {
            "speed": 48,
            "unit": "km/h"
          },
          {
            "speed": 48,
            "unit": "km/h"
          },
          {
            "unknown": true
          },
          {
            "unknown": true
          },
          {
            "unknown": true
          },
          {
            "unknown": true
          }
        ]
      },
      "summary": "",
      "weight": 153.6,
      "duration": 73.6,
      "steps": [],
      "distance": 207.8
    }],
    "weight_name": "routability",
    "weight": 153.6,
    "duration": 73.6,
    "distance": 207.8
  }],
  "tracepoints": [
    null,
    {
      "alternatives_count": 0,
      "waypoint_index": 0,
      "matchings_index": 0,
      "distance": 14.635568381812668,
      "name": "Davis Street",
      "location": [
        -122.397484,
        37.792809
      ],
      "maxspeed": {
        "speed": 48,
        "unit": "km/h"
      }
    },
    {
      "alternatives_count": 1,
      "waypoint_index": 1,
      "matchings_index": 0,
      "distance": 1.8762601659793365,
      "name": "Market Street",
      "location": [
        -122.396075,
        37.793502
      ],
      "maxspeed": {
        "unknown": true
      }
    }
  ],
  "code": "Ok"
}

Match object

A match object is a route object with an additional confidence field:

PropertyDescription
confidenceA float indicating the level of confidence in the returned match, from 0 (low) to 1 (high).
distanceA float indicating the distance traveled in meters.
durationA float indicating the estimated travel time in seconds.
weightA string indicating the weight in the units described by weight_name.
weight_nameA string indicating the weight that was used. The default is routability, which is duration-based with additional penalties for less desirable maneuvers.
geometryDepending on the geometries parameter in the request, this is a GeoJSON LineString or a Polyline string. Depending on the overview parameter in the request, this is the complete route geometry (full), a simplified geometry to the zoom level at which the route can be displayed in full (simplified), or is not included (false).
legsAn array of route leg objects.
voice_locale

(Requires steps=true)
The locale used for voice instructions. Defaults to en (English). See supported languages.
linear_referencesAn array of base64-encoded OpenLR location references, one for each graph edge of the road network matched by the input trace. This key is optional, and present only when linear_references=true in the request.

Example match object

{
    "confidence": 0.9548844020537051,
    "distance": 103.7,
    "duration": 16.4,
    "geometry": "gatfEfidjUi@Le@@Y?E??J?^Hf@",
    "legs": []
}

Tracepoint object

A tracepoint object is a waypoint object with three additional fields: matchings_index, waypoint_index, and alternatives_count.

PropertyDescription
matchings_indexThe index of the match object in matchings that the sub-trace was matched to.
waypoint_indexThe index of the waypoint inside the matched route.
alternatives_countThe number of probable alternative matchings for this trace point. A value of 0 indicates that this point was matched unambiguously. Split the trace at these points for incremental map matching.
nameThe name of the road or path the coordinate snapped to.
locationAn array that contains the location of the snapped coordinate, in the format [longitude, latitude].

Example tracepoint object

{
    "waypoint_index": 0,
    "location": [-117.172836, 32.71204],
    "name": "North Harbor Drive",
    "matchings_index": 0,
    "alternatives_count": 0
}

Map Matching API errors

On error, the server responds with different HTTP status codes.

  • For responses with HTTP status codes lower than 500, the JSON response body includes the code property, which may be used by client programs to manage control flow. The response body may also include a message property, with a human-readable explanation of the error.
  • If a server error occurs, the HTTP status code will be 500 or higher and the response will not include a code property.
Response body codeHTTP status codeDescription
Ok200Normal case
NoMatch200The input did not produce any matches, or the waypoints requested were not found in the resulting match. features will be an empty array.
NoSegment200No road segment could be matched for one or more coordinates within the supplied radiuses. Check for coordinates that are too far away from a road.
TooManyCoordinates200There are more than 100 points in the request.
ProfileNotFound404Needs to be a valid profile (mapbox/driving, mapbox/driving-traffic, mapbox/walking, or mapbox/cycling).
InvalidInput422message will hold an explanation of the invalid input.

Map Matching API restrictions and limits

  • The Map Matching API is limited to 300 requests per minute.
  • Each request can have a maximum of 100 coordinates.
  • Results must be displayed on a Mapbox map using one of the Mapbox libraries or SDKs.
If you require a higher rate limit, contact us.