Skip to content
Documentation menu
docs / mapbox-compatible-api · raw .md

Mapbox-compatible API

If your code calls Mapbox's Directions, Matrix, Isochrone, Optimization v1 or Geocoding APIs over HTTP, you can point it at MapMap by changing the base URL and the token. The paths, the query parameters and the response shapes stay Mapbox's. Each path is an alias of a MapMap endpoint that already exists, it is served by that endpoint, and it is billed exactly as that endpoint is.

text
https://api.mapbox.com      ->  https://api.mapmap.ai
access_token=pk.…           ->  access_token=snk_…

Get a key with one call, no card:

sh
curl -fsS -X POST "https://api.mapmap.ai/v1/keys" \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.com", "accept_tos": true}'

The rules every alias follows

  • The key. access_token is accepted as your MapMap key on these paths only. ?api_key= and Authorization: Bearer snk_… work too. A Mapbox pk. token is refused with a 401. These paths are not in the keyless demo lane: every call needs a key.
  • {user} is mapbox or mapmap. Profiles are driving, driving-traffic, walking, cycling, and truck, MapMap's extension (premium class, with lorry dimensions and ADR tunnel codes). Any other profile answers 404 ProfileNotFound.
  • driving-traffic is served as driving. There is no separate traffic profile. MapMap's traffic-aware car times come from National Highways data on England's strategic road network only; outside it, car times are the routing engine's own. This is not live traffic everywhere, and annotations=congestion is refused rather than faked.
  • An option is honoured or refused, never dropped. Mapbox refuses a query option it does not recognise, and so do these aliases. A Mapbox option MapMap cannot honour (bearings, radiuses, annotations=congestion, continue_straight=true and the others listed below) is a 400 whose message names the options or values that are supported. A refusal is not billed.
  • Errors keep Mapbox's body, with MapMap's statuses. Routing errors are {"code": …, "message": …}. Where Mapbox answers 422 InvalidInput, MapMap answers 400 InvalidValue or InvalidQuery. NoRoute, NoSegment and Optimization's NotImplemented answer HTTP 200 with that code, as Mapbox documents. Geocoding errors are {"message": …}. Authentication, scope and quota errors (401, 403, 429) are MapMap's problem+json, the same on every endpoint.
  • Billing. Each alias is metered as the endpoint it wraps, and counted on its own usage row (/directions/v5, /directions-matrix/v1, /isochrone/v1, /optimized-trips/v1, /search/geocode/v6, /geocoding/v5) so you can see switched traffic on its own. Prices are on the pricing page.
  • Key scope. A browser (maps) key may call the geocoding aliases, as it may call /geocode. The routing aliases need a full key.

Directions

GET /directions/v5/{user}/{profile}/{coordinates}, served by the OSRM-compatible route service (GET /route/v1), whose responses were already Mapbox-shaped: routes, legs, steps, voiceInstructions, bannerInstructions and waypoints. The response adds uuid (the request id), and every route carries weight and weight_name: "duration".

What maps:

Mapbox optionOn MapMap
alternatives, geometries, overview, steps, languagePassed through
voice_instructions, banner_instructionsPassed through. Voice text is metric, so voice_units=metric is accepted and imperial is refused
annotationsdistance, duration, speed and maxspeed. The first three are each manoeuvre's engine length and time spread over its segments by length, so they sum to the step totals and speed is the manoeuvre's average
excludetoll, motorway, ferry, tunnel, as hard exclusions
depart_at, arrive_byLocal time, YYYY-MM-DDThh:mm
approachescurb or unrestricted, one per coordinate
continue_straight, roundabout_exits, waypointsAccepted only where they describe what MapMap does: false, false, and a list naming every coordinate

What is refused, and why:

  • annotations=congestion, congestion_numeric, closure, state_of_charge: MapMap has no live congestion feed to annotate with.
  • bearings, radiuses: coordinates snap to the nearest suitable road.
  • max_height, max_width, max_weight: use the truck profile with height, width, length and weight (metres and tonnes), which also takes hazmat and an ADR tunnel_code.
  • exclude=unpaved, cash_only_tolls, borders and point(…).
  • continue_straight=true: every coordinate may be left in either direction. Mapbox defaults to true for driving, so a route through intermediate waypoints can differ from Mapbox's there.
  • waypoint_names, waypoint_targets, waypoints_per_route, engine, EV options and the rest of Mapbox's list.

One difference worth knowing: Mapbox's exclusions are best effort, and MapMap's are hard. Where an excluded road cannot be avoided, MapMap answers NoRoute rather than a route that uses it.

Billing: as GET /route/v1, one call per started block of 20 waypoints; premium on the truck profile.

sh
# Before
curl "https://api.mapbox.com/directions/v5/mapbox/driving/-0.1410,50.8290;-0.1370,50.8220?steps=true&geometries=geojson&access_token=$MAPBOX_TOKEN"

# After
curl "https://api.mapmap.ai/directions/v5/mapbox/driving/-0.1410,50.8290;-0.1370,50.8220?steps=true&geometries=geojson&access_token=$MAPMAP_KEY"

Matrix

GET /directions-matrix/v1/{user}/{profile}/{coordinates}, served by POST /matrix.

What maps: sources and destinations (;-separated coordinate indices, or all, the default); annotations (duration, the default, distance, or both); depart_at.

What is refused: approaches, bearings and fallback_speed. An unreachable pair is null, as on Mapbox, never a straight-line guess.

Waypoints in sources and destinations carry the coordinate you sent as location and an empty name: the matrix engine does not report where it snapped each point, so no snapped position or snap distance is made up. Car durations in Great Britain include typical junction delay, as on POST /matrix, and the response says so in eta_calibration.

Billing: as POST /matrix, sources × destinations elements at one call per started block of 25 elements (up to 10,000 elements); premium on truck.

sh
# Before
curl "https://api.mapbox.com/directions-matrix/v1/mapbox/driving/-0.14,50.82;-0.13,50.83;-0.12,50.84?sources=0;2&annotations=duration,distance&access_token=$MAPBOX_TOKEN"

# After
curl "https://api.mapmap.ai/directions-matrix/v1/mapbox/driving/-0.14,50.82;-0.13,50.83;-0.12,50.84?sources=0;2&annotations=duration,distance&access_token=$MAPMAP_KEY"

Isochrone

GET /isochrone/v1/{user}/{profile}/{lon},{lat}, served by POST /isochrone.

What maps: contours_minutes or contours_meters (one or the other, up to 10 contours where Mapbox allows four, each within 120 minutes or 200 km); contours_colors; polygons; denoise; generalize; depart_at.

The GeoJSON features carry Mapbox's properties: contour (minutes, or metres for a distance contour), metric (time or distance) and color, with fill and fillColor on polygons.

What is refused: exclude. Car contours are the engine's free-flowing times, because a typical delay that differs by road type cannot honestly be scaled onto a shape; the response says so in eta_calibration.

Billing: as POST /isochrone, one call per contour; premium on truck.

sh
# Before
curl "https://api.mapbox.com/isochrone/v1/mapbox/walking/-0.1410,50.8290?contours_minutes=5,10&polygons=true&access_token=$MAPBOX_TOKEN"

# After
curl "https://api.mapmap.ai/isochrone/v1/mapbox/walking/-0.1410,50.8290?contours_minutes=5,10&polygons=true&access_token=$MAPMAP_KEY"

Optimization (v1)

GET /optimized-trips/v1/{user}/{profile}/{coordinates}, 2 to 12 coordinates. Served in two steps: a one-vehicle solve on POST /optimise (the vehicle starts at the first coordinate and ends at the last one, or back at the start on a round trip), then the ordered stops routed as a Directions route, so trips[0] is a route object, as Mapbox's is.

What maps: roundtrip (default true), source (first or any), destination (last or any), with Mapbox's own table of supported combinations: roundtrip=false needs source=first&destination=last, and any other combination answers 200 NotImplemented, unbilled. steps, geometries, overview, language, annotations and approaches apply to the route.

What is refused: distributions, bearings and radiuses.

Mapbox Optimization v2 (asynchronous, a different shape) is not covered; use POST /optimise for fleets, time windows and capacities.

Billing: the optimise units plus the route units. A trip of up to 12 coordinates bills 11 calls: 10 for the solve and 1 for the route. When the order is forced (at most one stop to place) no solve runs and only the route is billed.

sh
# Before
curl "https://api.mapbox.com/optimized-trips/v1/mapbox/driving/-0.14,50.82;-0.13,50.83;-0.12,50.84;-0.11,50.85?steps=true&access_token=$MAPBOX_TOKEN"

# After
curl "https://api.mapmap.ai/optimized-trips/v1/mapbox/driving/-0.14,50.82;-0.13,50.83;-0.12,50.84;-0.11,50.85?steps=true&access_token=$MAPMAP_KEY"

Geocoding v6

GET /search/geocode/v6/forward and GET /search/geocode/v6/reverse, served by /geocode and /geocode/reverse.

The shape is Mapbox's; the results are MapMap's. Answers come from MapMap's own geocoder (OpenStreetMap data), rewritten into v6 property names. They will not match Mapbox's results row for row, and Mapbox's own place data is not involved. Each response carries the OpenStreetMap credit in attribution.

Forward: q, proximity (lon,lat), bbox, country, limit (1 to 10), language (its primary subtag selects the result language), and types, which is applied as a filter on the page returned, so fewer than limit results can come back. autocomplete, session_token and permanent are accepted and change nothing: every call is one stateless, billed lookup, and OpenStreetMap data may be stored under the ODbL. proximity=ip and worldview are refused.

Reverse: longitude, latitude, limit (default 1), types and country (both applied as filters on the page returned).

Properties: mapbox_id (MapMap's own id, or osm:<type>:<id> for an OpenStreetMap element), feature_type, name, full_address, place_formatted, coordinates and context (country with country_code, region, postcode, place, neighborhood, street, and address where there is a house number). A point of interest is labelled feature_type: "poi", which is not in Mapbox's v6 list, rather than passed off as an address.

Billing: as /geocode, one call per request.

sh
# Before
curl "https://api.mapbox.com/search/geocode/v6/forward?q=Brighton%20Station&proximity=-0.14,50.83&access_token=$MAPBOX_TOKEN"

# After
curl "https://api.mapmap.ai/search/geocode/v6/forward?q=Brighton%20Station&proximity=-0.14,50.83&access_token=$MAPMAP_KEY"

Geocoding v5 (legacy)

GET /geocoding/v5/mapbox.places/{query}.json, for the many integrations that still call it. A {query} that is a lon,lat pair is a reverse lookup, as on Mapbox.

Parameters: proximity, bbox, country, limit, language, types (a filter on the page returned) and autocomplete (accepted, changes nothing).

Features carry id, type, place_type, relevance (1 unless the geocoder reports a score), text, place_name, center, geometry, properties and context; the collection carries query and attribution. Context ids are readable labels such as place.brighton, not Mapbox's ids. The same rule applies as for v6: Mapbox's shape, MapMap's results.

Billing: as /geocode, one call per request.

sh
# Before
curl "https://api.mapbox.com/geocoding/v5/mapbox.places/Brighton%20Station.json?limit=5&access_token=$MAPBOX_TOKEN"

# After
curl "https://api.mapmap.ai/geocoding/v5/mapbox.places/Brighton%20Station.json?limit=5&access_token=$MAPMAP_KEY"

What this does not cover

  • The map itself. Satellite imagery and Mapbox-hosted tilesets are not served on Mapbox paths. Moving a Mapbox GL JS map is a renderer swap, covered in migrating from Mapbox.
  • Mobile SDKs. The Mapbox Navigation and Maps SDKs for iOS and Android talk to more endpoints than these and validate their own token format, so changing a base URL does not move them. MapMap's mobile SDKs are the route there.
  • Other Mapbox APIs. Map Matching, Optimization v2, the Search Box API, Tilesets, Static Images and the rest have no alias here. Where MapMap has an equivalent it is on its own path, listed in the API reference.

The OpenAPI document lists every alias under the mapbox-compat tag: api.mapmap.ai/openapi.json.