Skip to content

50,000 free calls a month, card-free. Get an API key →

Documentation menu
docs / quickstart · raw .md
Your first map in 3 minutes · 3:15 · all videos

Quickstart

From nothing to a dimensioned truck route in two calls. No install needed to try it: the playground runs the same requests from your browser.

Status, honestly: the hosted gateway at https://api.mapmap.ai is live: sign up for a key, or run the self-host distro; every call below works identically against your own deployment. Base URL, auth and conventions are defined in full on the conventions page.

Truck routing with multiple stops, from key to rendered route · © OpenStreetMap contributors © OpenMapTiles

Set up your shell once so every snippet on this page is copy-pasteable:

sh
export BASE=https://api.mapmap.ai   # or your self-hosted gateway origin

1. Issue a key, one call, card-free

sh
curl -fsS -X POST "$BASE/v1/keys" \
  -H "Content-Type: application/json" \
  -d '{"email": "you@example.co.uk", "accept_tos": true}'

Response (201 Created):

json
{
  "key": "snk_…",
  "key_id": "3f1c…-uuid",
  "state": "provisional",
  "calls": 1000,
  "expires_in_h": 72,
  "verify": "link sent to email; clicking upgrades this key to the free tier",
  "tos": "https://mapmap.ai/terms"
}

The snk_ key is shown once. Store it now:

sh
export API_KEY=snk_…   # the "key" field from the response

It is live immediately as a provisional key: 1,000 calls, valid for 72 hours, rate-limited to 60 requests a minute. A magic verification link is emailed separately (it is not in the response; verify is just a note). Click it and the same key is upgraded to the free tier of 50,000 calls a month.

No email? POST /v1/keys again with the same address; the verification link upgrades every provisional key issued to that email, so re-issuing is safe. Unverified keys stop working after 72 hours; just issue a new one.

2. Route a truck

Our routing API takes coordinates as lon,lat;lon,lat, with truck dimensions and the tunnel code as query parameters. Several profiles are exposed on this endpoint: truck, driving (aliases car/auto), bus, bicycle (bike/cycling), walking (foot/pedestrian), scooter and motorcycle (motorbike), so swap truck for driving for a standard car route, or any of the others. The truck parameters below require the truck profile (they 400 on any other profile).

The tunnel code is from ADR (the European agreement on carriage of dangerous goods by road; tunnel codes B–E restrict which tunnels a hazmat load may use); the full tunnel-code table is on the conventions page. Setting tunnel_code implies hazmat=true. Slashed codes like B/D must be URL-encoded, which --data-urlencode handles below.

ParameterRequiredDefaultMeaning
{profile} (path)yesn/atruck, driving/car, bus, bicycle, walking, scooter or motorcycle
{coordinates} (path)yesn/alon,lat pairs separated by ;
heightnoEU 96/53/EC articVehicle height in metres (truck only)
widthnoEU 96/53/EC articVehicle width in metres (truck only)
lengthnoEU 96/53/EC articVehicle length in metres (truck only)
weightnoEU 96/53/EC articGross weight in tonnes (truck only)
hazmatnofalse (true if tunnel_code set)Carrying dangerous goods (truck only)
tunnel_codenononeADR 8.6.4 tunnel restriction code, e.g. D or B/D (truck only)
stepsnofalseInclude turn-by-turn steps
geometriesnopolylinepolyline, polyline6 or geojson
overviewnosimplifiedfull, simplified or false
alternativesnofalsetrue, false or a number of alternates
avoid_tollsnofalseAvoid toll roads (motorised profiles only)
avoid_motorwaysnofalseAvoid motorways/highways (motorised profiles only)
avoid_ferriesnofalseAvoid ferries (all profiles)
shortestnofalseOptimise for distance over time (all profiles)

The four route options are honoured by the hosted gateway only; the keyless demo router ignores them. avoid_tolls/avoid_motorways on a non-motorised profile (bicycle/walking) return InvalidValue.

Dover to Birmingham, 44 t artic, 4.0 m high, ADR tunnel restriction code D:

sh
curl -fsS -G "$BASE/route/v1/truck/1.3134,51.1279;-1.8904,52.4862" \
  -H "Authorization: Bearer $API_KEY" \
  --data-urlencode "overview=full" \
  --data-urlencode "height=4.0" \
  --data-urlencode "width=2.55" \
  --data-urlencode "weight=44.0" \
  --data-urlencode "hazmat=true" \
  --data-urlencode "tunnel_code=D"

Response (200 OK, truncated):

json
{
  "code": "Ok",
  "routes": [
    {
      "distance": 362514.3,
      "duration": 16043.9,
      "geometry": "u{~vHmgg@…",
      "weight": 16043.9,
      "weight_name": "duration",
      "legs": [
        {
          "distance": 362514.3,
          "duration": 16043.9,
          "summary": "M25, M40"
        }
      ]
    }
  ],
  "waypoints": [
    { "name": "A20", "location": [1.3134, 51.1279] },
    { "name": "", "location": [-1.8904, 52.4862] }
  ]
}

OSRM-compatible: distances are metres, durations are seconds, geometry is an encoded polyline (geometries=geojson for GeoJSON), so common routing clients work unchanged. Prefer a richer JSON body? POST /route takes a native routing request plus a top-level adr extension. See the API reference. Coverage is territory-based; see territories for what is loaded where.

3. Check your key

sh
curl -fsS "$BASE/v1/keys/self" -H "Authorization: Bearer $API_KEY"

Fresh from steps 1–2, before clicking the verification link, you hold a provisional key:

json
{
  "key_id": "3f1c…-uuid",
  "state": "provisional",
  "monthly_quota": 1000,
  "used_this_month": 1,
  "remaining": 999,
  "credits_pence": 0,
  "credits_millipence": 0,
  "expires_at": "2026-07-18T09:00:00Z",
  "identity_keys": 1,
  "download_allowance_mib": 8192,
  "download_used_mib": 0,
  "mau_this_month": 0,
  "mau_included": 1000,
  "mau_overdrawn": false
}

After you click the emailed link, state flips to "verified", monthly_quota becomes 50,000 and expires_at disappears. Polling this endpoint is quota-free, so agents can watch for the upgrade.

Beyond the free quota, calls draw prepaid credit at the two-speed rate: standard routing and data from 0.05p/call, truck and ADR compliance from 1p/call; the class is detected per request (see /pricing.json). A truck/ADR call draws 20 included calls from the free tier, matching the price ratio. Top up from /account. No credit means no overage: requests stop with 429 rather than billing you.

If something goes wrong

The routing endpoint answers errors in the OSRM envelope ({"code": …, "message": …}) because OSRM clients dispatch on code; everything else uses RFC 9457 application/problem+json. The first failures a new key hits:

Statuscode / problemCause and fix
400InvalidQueryMalformed coordinates; check lon,lat;lon,lat order and that you sent at least two pairs
400InvalidValueUnsupported profile (see the profile list above), bad tunnel_code, or truck parameters on a non-truck profile
400NoSegment / NoRouteCoordinates could not snap to a road / no legal path exists for the vehicle
401unauthorizedMissing, unknown or expired key; check the Authorization: Bearer header
429rate-limited / quota-exceededOver 60 requests/min, or free quota exhausted with no credit

For example, a wrong profile:

json
{ "code": "InvalidValue", "message": "unsupported profile \"hovercraft\": expected one of driving/car, truck, bus, bicycle/bike, walking/foot/pedestrian, scooter, motorcycle" }

And a bad key:

json
{
  "type": "urn:sn-gateway:problem:unauthorized",
  "title": "Unauthorised",
  "status": 401,
  "detail": "unknown API key"
}

The full error envelope, including when you see 402 versus 429, is on the conventions page.

Attribution

Routing derives from OpenStreetMap data. Anything you render or republish must credit "© OpenStreetMap contributors" with a link to openstreetmap.org/copyright.

Next steps

  • API reference: every endpoint, parameter and response shape
  • Conventions: base URL, auth, units, error envelope, ADR tunnel codes
  • SDKs: web, Android and iOS wrappers around these calls
  • Self-host: run the whole stack on your own hardware
Get an API key · 1:28 · all videos