Skip to main content

Map Matching V4


v4 of the Map Matching API is a legacy product. It is no longer in active development. To learn more about Mapbox's newer web services APIs see the Map Matching v5 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.


  • 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

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 indicating the assumed precision of the used tracking device, in meters. 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 you know the provided traces are of poor quality, you must do some GeoJSON tidying. 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 the geometry option in request was 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.