Map Matching API
The Map Matching API takes a recorded track, a GPX file or a list of coordinates, and snaps it onto the road and path network. A GPS trace that wanders off the trail, jumps between parallel streets or drifts under tree cover comes back as a clean line that follows the ways the recording was actually made on.
It answers the question the Routing API cannot: not “what is the best way from A to B”, but “which ways did this recording actually follow”.
Base URL
https://routing.maptoolkit.net/matchGET and POST are both accepted. Use POST for anything longer than a handful of points,
since a long track will not fit in a query string.
Authentication
Add your API key as ?api_key=YOUR_API_KEY to every request. See
Authentication for details.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
point | lat,lng | One of the two | A coordinate on the track. Repeat the parameter for each point, in recorded order. |
gpx | string | One of the two | URL of a GPX file to fetch and match. |
routeType | string | No | Profile used for matching. Defaults to foot. |
At least one of point or gpx is required. language and points_encoded work as they do
on the Routing API. The full list, with the response codes and a console for
sending live requests, is in the API Reference.
Three things to get right
point is lat,lng. That is latitude first, the opposite of the [lng, lat] order used
by GeoJSON, MapLibre and the map libraries. Sending map coordinates straight through without
swapping them is the most common cause of a match that returns nothing useful.
instructions=false breaks the request. Passing instructions=false or
instructions=0 returns 400 No map-matching possible for your track., which blames the
track rather than the parameter. instructions=true and omitting it both work. A matched
recording is usually drawn rather than navigated, so this is a natural thing to try; leave it
off the request.
The default profile is foot, not car. If you are matching a drive, set routeType=car
explicitly. A car trace matched on the walking network will snap to footpaths that no car
took.
Example
The orange line is a real GPS recording: a 5 km walk along the Inn in Innsbruck, with the error a phone actually produces. It drifts across the river, cuts corners and wanders into buildings. The blue line is what the Map Matching API returns for the same file. Toggle either one to compare.
The recording is at innsbruck-walk.gpx: 511 points at roughly 8-second intervals, a mean error of 10 m and a worst case of 32 m.
Response
The response schema is identical to the Routing API, so a client that already renders a route needs no changes to render a matched track.
curl -X POST "https://routing.maptoolkit.net/match?api_key=YOUR_API_KEY" \
--data-urlencode "gpx=https://example.com/track.gpx" \
--data-urlencode "routeType=foot" \
--data-urlencode "language=en"The api_key goes in the query string. Sent as a form field in the POST body it is not
read, and the request fails with 403 Access denied! as though no key had been supplied.
The URL in gpx is fetched by the service, not by your browser, so it has to be reachable
from the public internet. A URL behind a login, on localhost or on a private network fails.
Track length limit
Tracks are checked against a maximum length before matching, and a track over the limit is
rejected with a 400 rather than truncated. Split a long recording into segments and match
them separately if you hit it.
Matching is heavier than routing. A long track takes noticeably longer than a route request between the same endpoints, so give the call a generous client-side timeout.
What to use instead
- A route between known points. Use the Routing API. Matching a route you just calculated adds nothing.
- An elevation profile or surface tags along an existing track. Use the Route Enhancement API, which does its own matching and returns the enrichment with it.
- Elevation at individual coordinates. Use the Elevation API.
Errors
Errors return the HTTP status code with a plain-text message in the body.
| Status | Meaning |
|---|---|
400 | Neither point nor gpx was supplied, or the track is longer than the allowed maximum. |
400 | No map-matching possible for your track. The file was fetched but holds no usable track, or none of it could be matched to the network. |
400 | Request failed with status code 404 The URL given in gpx could not be fetched. |
403 | The API key is missing (Access denied!), not recognized (Api-key not found!), or has no access to this service (Api-key not authorized!). See First Steps. |
500 | Internal server error. |
Error bodies are text/plain, not JSON.
Rate limits
Limits are monthly request quotas tied to your plan rather than a per-second rate: the service
returns no RateLimit-* or Retry-After headers. Current allowances are on the
pricing page.
The free Basic plan has a hard limit, so requests are refused once it is reached. On Pro and Ultra, requests past the allowance are billed rather than refused. Enterprise plans use a flexible limit.
A match counts as an API request, which is metered separately from tile requests and at a higher rate.
Pricing
Self-service plans (Basic, Pro, and Ultra) are billed through RapidAPI; see RapidAPI for how to subscribe and authenticate. Plan limits and prices are listed on the Maptoolkit pricing page. Enterprise customers call the native hosts directly with a Maptoolkit API key.