Open Application Platform Docs

Map matching (beta)

Snap a GPS trace to the roads it was driven on and measure the drive.

trace.match Beta point_1k

How to call it

REST

POST /v1/trace/match

GraphQL

query openTraceMatch

MCP

open_trace_match

Snap a GPS trace (2-5000 points with optional times) to the roads it was driven on. Returns each point placed on its road with how far it moved, the roads driven with their lengths, the total distance and the driven line as GeoJSON. Billed per point.

Request schema

Generated from the same validation rules the endpoint runs, so a field cannot be documented without being validated.

POST /v1/trace/match

{
    "type": "object",
    "properties": {
        "geometry": {
            "type": [
                "boolean",
                "null"
            ]
        },
        "points": {
            "type": "array",
            "minItems": 2,
            "maxItems": 5000,
            "items": {
                "type": "object",
                "properties": {
                    "id": {
                        "type": [
                            "string",
                            "null"
                        ],
                        "maxLength": 128
                    },
                    "lat": {
                        "type": "number",
                        "minimum": -90,
                        "maximum": 90
                    },
                    "lng": {
                        "type": "number",
                        "minimum": -180,
                        "maximum": 180
                    },
                    "time": []
                },
                "required": [
                    "lat",
                    "lng"
                ]
            }
        },
        "profile": {
            "type": [
                "string",
                "null"
            ],
            "enum": [
                "car",
                "van",
                "truck",
                "bike",
                "foot",
                "motorcycle"
            ]
        },
        "search_radius_meters": {
            "type": [
                "integer",
                "null"
            ],
            "minimum": 1,
            "maximum": 200
        }
    },
    "additionalProperties": false,
    "required": [
        "points"
    ]
}

Request example

{
    "points": [
        {
            "id": "fix-1",
            "lat": 45.498348,
            "lng": -73.571617,
            "time": "2026-11-02T08:00:00-05:00"
        },
        {
            "id": "fix-2",
            "lat": 45.499071,
            "lng": -73.569882,
            "time": "2026-11-02T08:00:21-05:00"
        },
        {
            "id": "fix-3",
            "lat": 45.501306,
            "lng": -73.567881,
            "time": "2026-11-02T08:00:42-05:00"
        },
        {
            "id": "fix-4",
            "lat": 45.502841,
            "lng": -73.566375,
            "time": "2026-11-02T08:01:03-05:00"
        },
        {
            "id": "fix-5",
            "lat": 45.502257,
            "lng": -73.564575,
            "time": "2026-11-02T08:01:24-05:00"
        },
        {
            "id": "fix-6",
            "lat": 45.502093,
            "lng": -73.563383,
            "time": "2026-11-02T08:01:45-05:00"
        },
        {
            "id": "fix-7",
            "lat": 45.502914,
            "lng": -73.560675,
            "time": "2026-11-02T08:02:07-05:00"
        },
        {
            "id": "fix-8",
            "lat": 45.504991,
            "lng": -73.558915,
            "time": "2026-11-02T08:02:28-05:00"
        }
    ],
    "profile": "car"
}

Response

What a successful call returns: the schema of `data` and `meta`, with a description of each field, followed by an example response from a real call.

POST /v1/trace/match

Response schema

{
    "description": "The trace matched to roads: every point placed, the roads driven and the drive's length. Billed per point.",
    "data": {
        "type": "object",
        "properties": {
            "points": {
                "type": "array",
                "description": "Every point of the trace, in the order given.",
                "items": {
                    "type": "object",
                    "properties": {
                        "index": {
                            "type": "integer",
                            "description": "The point's place in `points`, from 0."
                        },
                        "id": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "description": "The point's id, when given."
                        },
                        "type": {
                            "type": "string",
                            "enum": [
                                "matched",
                                "interpolated",
                                "unmatched"
                            ],
                            "description": "`matched`: placed on a road; `interpolated`: placed between matched points; `unmatched`: no road found."
                        },
                        "lat": {
                            "type": [
                                "number",
                                "null"
                            ],
                            "description": "Where the point lies on the road."
                        },
                        "lng": {
                            "type": [
                                "number",
                                "null"
                            ],
                            "description": "Where the point lies on the road."
                        },
                        "moved_meters": {
                            "type": [
                                "number",
                                "null"
                            ],
                            "description": "How far the point was moved onto the road."
                        },
                        "road": {
                            "type": [
                                "string",
                                "null"
                            ],
                            "description": "The name of the road, when it has one."
                        }
                    }
                }
            },
            "roads": {
                "type": "array",
                "description": "The roads driven, in order; consecutive stretches of one road are one entry.",
                "items": {
                    "type": "object",
                    "properties": {
                        "names": {
                            "type": "array",
                            "items": {
                                "type": "string"
                            },
                            "description": "The road's names; empty for an unnamed road."
                        },
                        "road_class": {
                            "type": "string",
                            "description": "The road's class: motorway, trunk, primary, secondary, tertiary, unclassified, residential, service_other."
                        },
                        "speed_kmh": {
                            "type": [
                                "integer",
                                "null"
                            ],
                            "description": "The road's typical speed."
                        },
                        "distance_meters": {
                            "type": "integer",
                            "description": "Distance driven on it."
                        }
                    }
                }
            },
            "summary": {
                "type": "object",
                "properties": {
                    "points": {
                        "type": "integer",
                        "description": "Points submitted."
                    },
                    "matched": {
                        "type": "integer",
                        "description": "Points placed on a road."
                    },
                    "interpolated": {
                        "type": "integer",
                        "description": "Points placed between matched points."
                    },
                    "unmatched": {
                        "type": "integer",
                        "description": "Points no road was found for."
                    },
                    "distance_meters": {
                        "type": "integer",
                        "description": "The length of the drive."
                    }
                }
            },
            "geometry": {
                "type": "object",
                "description": "The driven line as a GeoJSON LineString ([lng, lat]). Absent when `geometry` is false."
            }
        },
        "required": [
            "points",
            "roads",
            "summary"
        ]
    },
    "meta": {
        "type": "object",
        "properties": {},
        "additionalProperties": true
    }
}

Response example

{
    "request_id": "req_01k8zq3m5n7p9r1t3v5x7z9b2d",
    "capability": "trace.match",
    "billing": {
        "unit": "point_1k",
        "quantity": 8,
        "counted": true
    },
    "data": {
        "points": [
            {
                "index": 0,
                "id": "fix-1",
                "type": "matched",
                "lat": 45.498367,
                "lng": -73.571597,
                "moved_meters": 2.6,
                "road": "Rue Stanley"
            },
            {
                "index": 1,
                "id": "fix-2",
                "type": "matched",
                "lat": 45.499086,
                "lng": -73.569893,
                "moved_meters": 2,
                "road": "Boulevard René-Lévesque Ouest"
            },
            {
                "index": 2,
                "id": "fix-3",
                "type": "matched",
                "lat": 45.50129,
                "lng": -73.567829,
                "moved_meters": 4.4,
                "road": "Boulevard René-Lévesque Ouest"
            },
            {
                "index": 3,
                "id": "fix-4",
                "type": "matched",
                "lat": 45.502922,
                "lng": -73.566398,
                "moved_meters": 9.3,
                "road": "Boulevard René-Lévesque Ouest"
            },
            {
                "index": 4,
                "id": "fix-5",
                "type": "matched",
                "lat": 45.502289,
                "lng": -73.564558,
                "moved_meters": 3.8,
                "road": "Côte du Beaver Hall"
            },
            {
                "index": 5,
                "id": "fix-6",
                "type": "matched",
                "lat": 45.502045,
                "lng": -73.563414,
                "moved_meters": 5.8,
                "road": "Côte du Beaver Hall"
            },
            {
                "index": 6,
                "id": "fix-7",
                "type": "matched",
                "lat": 45.502874,
                "lng": -73.560672,
                "moved_meters": 4.4,
                "road": "Rue Saint-Antoine Ouest"
            },
            {
                "index": 7,
                "id": "fix-8",
                "type": "matched",
                "lat": 45.504973,
                "lng": -73.558873,
                "moved_meters": 3.8,
                "road": "Rue Saint-Antoine Ouest"
            }
        ],
        "roads": [
            {
                "names": [
                    "Rue Stanley"
                ],
                "road_class": "residential",
                "speed_kmh": 30,
                "distance_meters": 67
            },
            {
                "names": [
                    "Boulevard René-Lévesque Ouest"
                ],
                "road_class": "secondary",
                "speed_kmh": 50,
                "distance_meters": 662
            },
            {
                "names": [
                    "Côte du Beaver Hall"
                ],
                "road_class": "tertiary",
                "speed_kmh": 40,
                "distance_meters": 280
            },
            {
                "names": [
                    "Rue du Square Victoria"
                ],
                "road_class": "tertiary",
                "speed_kmh": 30,
                "distance_meters": 113
            },
            {
                "names": [
                    "Rue Saint-Antoine Ouest"
                ],
                "road_class": "secondary",
                "speed_kmh": 49,
                "distance_meters": 463
            }
        ],
        "summary": {
            "points": 8,
            "matched": 8,
            "interpolated": 0,
            "unmatched": 0,
            "distance_meters": 1585
        },
        "geometry": {
            "type": "LineString",
            "coordinates": [
                [
                    -73.571598,
                    45.498367
                ],
                [
                    -73.571479,
                    45.498308
                ],
                [
                    -73.571149,
                    45.498132
                ],
                [
                    -73.57112,
                    45.498116
                ],
                [
                    -73.571049,
                    45.498079
                ],
                [
                    -73.570902,
                    45.498007
                ],
                [
                    -73.57085,
                    45.498061
                ],
                [
                    -73.570706,
                    45.498216
                ],
                [
                    -73.570579,
                    45.498355
                ],
                [
                    -73.570424,
                    45.498523
                ],
                [
                    -73.570397,
                    45.498553
                ],
                [
                    -73.570284,
                    45.498673
                ],
                [
                    -73.570199,
                    45.498762
                ],
                [
                    -73.57015,
                    45.498813
                ],
                [
                    -73.570117,
                    45.498849
                ],
                [
                    -73.569971,
                    45.499004
                ],
                [
                    -73.569894,
                    45.499087
                ],
                [
                    -73.56974,
                    45.49925
                ],
                [
                    -73.569719,
                    45.499274
                ],
                [
                    -73.569664,
                    45.499334
                ],
                [
                    -73.569541,
                    45.499463
                ],
                [
                    -73.56949,
                    45.499517
                ],
                [
                    -73.569244,
                    45.499785
                ],
                [
                    -73.56917,
                    45.49986
                ],
                [
                    -73.569046,
                    45.49999
                ],
                [
                    -73.569027,
                    45.500011
                ],
                [
                    -73.568971,
                    45.500073
                ],
                [
                    -73.568916,
                    45.500131
                ],
                [
                    -73.568903,
                    45.500144
                ],
                [
                    -73.568534,
                    45.500536
                ],
                [
                    -73.568133,
                    45.500966
                ],
                [
                    -73.568076,
                    45.501026
                ],
                [
                    -73.567829,
                    45.501291
                ],
                [
                    -73.567507,
                    45.501639
                ],
                [
                    -73.567451,
                    45.501698
                ],
                [
                    -73.567428,
                    45.50172
                ],
                [
                    -73.567354,
                    45.501796
                ],
                [
                    -73.567236,
                    45.501928
                ],
                [
                    -73.567174,
                    45.501996
                ],
                [
                    -73.566956,
                    45.502222
                ],
                [
                    -73.566784,
                    45.502408
                ],
                [
                    -73.566768,
                    45.502425
                ],
                [
                    -73.566724,
                    45.502472
                ],
                [
                    -73.566681,
                    45.502519
                ],
                [
                    -73.566667,
                    45.502534
                ],
                [
                    -73.566643,
                    45.502565
                ],
                [
                    -73.566585,
                    45.502648
                ],
                [
                    -73.566541,
                    45.502711
                ],
                [
                    -73.566415,
                    45.502899
                ],
                [
                    -73.566399,
                    45.502923
                ],
                [
                    -73.566333,
                    45.503032
                ],
                [
                    -73.56619,
                    45.502991
                ],
                [
                    -73.566159,
                    45.50298
                ],
                [
                    -73.565696,
                    45.502759
                ],
                [
                    -73.565468,
                    45.502653
                ],
                [
                    -73.565065,
                    45.502461
                ],
                [
                    -73.565035,
                    45.502448
                ],
                [
                    -73.564962,
                    45.502418
                ],
                [
                    -73.564879,
                    45.502387
                ],
                [
                    -73.564846,
                    45.502376
                ],
                [
                    -73.564782,
                    45.502354
                ],
                [
                    -73.56471,
                    45.502331
                ],
                [
                    -73.564633,
                    45.502308
                ],
                [
                    -73.564543,
                    45.502286
                ],
                [
                    -73.564463,
                    45.502269
                ],
                [
                    -73.564401,
                    45.502257
                ],
                [
                    -73.564333,
                    45.502243
                ],
                [
                    -73.56429,
                    45.502236
                ],
                [
                    -73.564205,
                    45.502225
                ],
                [
                    -73.564119,
                    45.502213
                ],
                [
                    -73.56408,
                    45.502208
                ],
                [
                    -73.564013,
                    45.502196
                ],
                [
                    -73.563923,
                    45.50218
                ],
                [
                    -73.563849,
                    45.502165
                ],
                [
                    -73.563775,
                    45.502149
                ],
                [
                    -73.563712,
                    45.502133
                ],
                [
                    -73.563632,
                    45.502112
                ],
                [
                    -73.563552,
                    45.502088
                ],
                [
                    -73.563477,
                    45.502066
                ],
                [
                    -73.563379,
                    45.502034
                ],
                [
                    -73.563277,
                    45.502
                ],
                [
                    -73.563235,
                    45.501983
                ],
                [
                    -73.563188,
                    45.501961
                ],
                [
                    -73.56315,
                    45.50194
                ],
                [
                    -73.563069,
                    45.501894
                ],
                [
                    -73.562052,
                    45.50145
                ],
                [
                    -73.56202,
                    45.501435
                ],
                [
                    -73.561934,
                    45.501394
                ],
                [
                    -73.561903,
                    45.50143
                ],
                [
                    -73.561881,
                    45.501457
                ],
                [
                    -73.561722,
                    45.501634
                ],
                [
                    -73.561697,
                    45.501663
                ],
                [
                    -73.561641,
                    45.501726
                ],
                [
                    -73.561589,
                    45.501786
                ],
                [
                    -73.561222,
                    45.50223
                ],
                [
                    -73.560672,
                    45.502874
                ],
                [
                    -73.560443,
                    45.503122
                ],
                [
                    -73.560422,
                    45.503145
                ],
                [
                    -73.56037,
                    45.503204
                ],
                [
                    -73.560308,
                    45.503277
                ],
                [
                    -73.559974,
                    45.50368
                ],
                [
                    -73.559757,
                    45.503939
                ],
                [
                    -73.559708,
                    45.503996
                ],
                [
                    -73.559662,
                    45.504051
                ],
                [
                    -73.559594,
                    45.504126
                ],
                [
                    -73.559294,
                    45.504485
                ],
                [
                    -73.559215,
                    45.504579
                ],
                [
                    -73.559195,
                    45.504603
                ],
                [
                    -73.559164,
                    45.50464
                ],
                [
                    -73.559129,
                    45.504678
                ],
                [
                    -73.558989,
                    45.50484
                ],
                [
                    -73.558874,
                    45.504973
                ]
            ]
        }
    },
    "meta": {
        "profile": "car",
        "geometry_format": "geojson"
    }
}

What it costs

Thousands of points, charged fractionally.

Every billable response carries a billing block with the unit, the quantity and how the quantity was derived.

Errors it can return

Status Code Description
401 TOKEN_INVALID Unknown or revoked API token.
401 TOKEN_MISSING No API token. Send Authorization: Bearer <your token>.
402 QUOTA_EXHAUSTED The included allowance for this capability is used up for the current period.
403 CAPABILITY_NOT_ENABLED This capability is not enabled for your account. See :doc to enable it.
403 CAPABILITY_NOT_GRANTED_TO_KEY Your account has this capability, but this API key was not granted it.
403 OPEN_API_DISABLED Open Platform access is not enabled for this account.
422 VALIDATION_FAILED The request failed validation. See details.
429 RATE_LIMITED Too many requests. Please retry after the indicated delay.
500 INTERNAL_ERROR An unexpected error occurred. Quote the request_id when contacting support.
502 ENGINE_UNAVAILABLE The routing engine is temporarily unreachable. Please retry.