Skip to content
Documentation menu
docs / api
Reference

API endpoints

122 public endpoints, one page each. Every page on this index is generated at build time from the document the gateway publishes at /openapi.json, so what you read here is what that deployment declares, not a second copy of it maintained by hand.

gateway 0.3.0 · read from https://api.mapmap.ai/openapi.json on 2026-11-01 · 48 admin and console operations are not listed

The rules these endpoints share, authentication, coordinate order, quotas, the error model and the ADR tunnel codes, are defined once on API conventions. For the narrative version with worked requests, read the API reference guide.

assets

Static map assets: SDF font glyph ranges and sprite sheets referenced by compiled styles. Public, unmetered, immutable caching

boundaries

Administrative boundaries. GET /boundary: the country and first sub-division at a point, from the Valhalla admins.sqlite (501 unless the operator sets SN_ADMIN_BOUNDARIES_DB). GET /v1/boundaries and GET /v1/boundaries/{id}: OSM admin_level 2 to 10 boundaries by name or point with a stable boundary_id, and one boundary's simplified polygon, for custom regions by boundary_id (501 unless the operator sets SN_BOUNDARIES_DIR). Standard price class, metered per request. OSM-derived (ODbL); see docs/THIRD-PARTY-NOTICES.md

clearance

Measured overhead clearance along a route, from baked survey geometry (crates/sn-clearance). A within-survey difference with a stated uncertainty bound, never a signed or legal clearance and never a pass over ground the survey did not cover. Standard price class, never premium: a safety check carries no extra charge. 501 unless the deployment publishes at least one clearance artefact

collection

compliance

Metered ADR compliance endpoints

coordinates

Reprojection between reference systems, and the published list of the ones it will do it for. Every supported CRS states its own datum-shift error, and a code outside the table is refused by name rather than approximated. Standard price class, one unit per request whatever it carries

directional

Directional place lookup: given a position AND a bearing, the places inside that cone, each with its distance, its own bearing, its angular offset from the query bearing, and a visibility verdict computed against the bare-earth elevation model and OpenStreetMap building footprints. Every verdict names what it was checked against and can answer `unknown`; a place that could not be checked is returned labelled rather than silently kept or dropped. A QUERY surface only: it takes a position and a bearing and answers, and nothing here is route-triggered or proactive. Standard price class, billed a flat block

elevation

Point and along-route elevation via Valhalla's native /height action. Honest per-sample source/resolution metadata and a null (never a guess) wherever the engine has no DEM tile coverage. Standard price class, metered per request. 501 unless the operator sets SN_ELEVATION_ENABLED=true (off by default until DEM tiles are staged)

feedback

Integration retros: the structured end-of-integration report an agent (or human) submits once: what was built, problems, gotchas, wins and docs gaps. Key-authenticated, never charged, rate-limited per key. Content is stored verbatim and treated as untrusted text

geocode

geocoding

Metered Photon geocoding proxy (forward and reverse): GeoJSON passthrough, Standard price class. 501 unless the operator sets SN_PHOTON_URL

live

Live Earth layers for display: earthquakes, volcano alerts and fire detections (USGS, NOAA NCEI, NASA FIRMS), NOAA GFS forecast frames processed by MapMap, and the NOAA SWPC aurora forecast and Kp. Freshness is a field on every answer, never an error. Forecast and reported data for display, never a warning service. Standard price class, one unit per request; a browser (maps) key may read them. 501 unless the operator sets SN_LIVE_DIR and SN_WEATHER_DIR.

map-issues

User map-error reports ("Report a map issue"): a pin, a category and an optional note, key-authenticated and metered at the Standard price class. Reports never edit map data directly. The team triages them (see the admin surface) and verified fixes flow into the deployment's OSM-overrides file and upstream OpenStreetMap contributions. The same path carries drivers' traffic reports (the traffic-* categories, which require heading_deg): they are deleted after 24 hours, never published, and reach other drivers only through POST /v1/incidents/along once two drivers agree

mapbox-compat

Shape-compatible aliases of MapMap endpoints for clients written against Mapbox: Directions, Matrix, Isochrone, Optimization v1 and Geocoding (v6 and legacy v5) paths, parameters and response shapes, each served by the MapMap endpoint it wraps and metered as that endpoint. `access_token` is accepted as the key on these paths. A Mapbox option MapMap cannot honour is refused with a 400 naming the supported set, never silently dropped. `driving-traffic` is served as `driving` (traffic-aware times cover the England strategic road network only). Geocoding answers are MapMap's own in Mapbox's shape, not Mapbox's results

meta

Unauthenticated service metadata

oauth

OAuth 2.1 authorization server: RFC 8414 discovery, RFC 7591 dynamic client registration, and the token endpoint. Public clients only (PKCE S256, no client secrets), rotating refresh tokens with reuse-revokes-chain, and client-id metadata document (CIMD) clients. An issued `sno_` access token resolves in the auth layer to a real API key, so every existing quota, metering and billing rule applies unchanged. The interactive authorization page lives on the website (SN_OAUTH_AUTHORIZE_URL); 501 unless the deployment has one

places

Customer places ("bring your own places"): per-key proprietary place datasets with full-text and nearest search over the caller's own tantivy index. Never merged into OSM-derived data (ODbL boundary). All routes key-authenticated and metered at the Standard price class

pointclouds

routing

Metered routing endpoints

POST/centroid

Finds the least-cost meeting point of several locations (see module docs).

POST/isochrone

Isochrone endpoint (see module docs).

POST/locate

Snaps each location to the road graph (see module docs).

POST/matrix

Matrix endpoint (see module docs).

POST/optimise

Route-optimisation endpoint (see module docs). `/optimize` is an alias.

POST/optimise/replan

Re-plan a fleet mid-shift (see module docs). `/optimize/replan` is an alias.

POST/route

Valhalla-compatible route endpoint (see module docs).

POST/route/along

Along-route search endpoint (see module docs).

POST/route/progress

Progress endpoint (see module docs).

POST/route/report

Report endpoint (see module docs).

GET/route/v1/{profile}/{coordinates}

OSRM-compatible route endpoint (see module docs).

POST/trace_attributes

Map matching to per-edge attributes (see module docs).

POST/trace_route

Map matching to a route (see module docs).

POST/v1/cameras/along

Safety cameras along a route shape (see module docs).

POST/v1/charging/along

Best EV chargers along a route (see module docs).

POST/v1/cluster

Capacity-constrained clustering (see module docs).

POST/v1/errands/plan

Plans a chain of errands against a hard arrival time.

POST/v1/ev/plan

Plans an EV journey with its charge stops (see module docs).

POST/v1/fuel/along

Cheapest fuel along a route (see module docs).

POST/v1/incidents/along

Traffic incidents and closures along a route shape (see module docs).

POST/v1/jobs/coverage

Submit a drive-every-street coverage plan to the asynchronous lane.

POST/v1/jobs/matrix

Submit a matrix to the asynchronous lane.

POST/v1/jobs/optimise

Submit an optimisation problem to the asynchronous lane.

POST/v1/jobs/replan

Submit a mid-shift re-plan to the asynchronous lane.

POST/v1/route/heritage

`POST /v1/route/heritage` (see module docs).

POST/v1/route/observations

`POST /v1/route/observations` (see module docs).

POST/v1/weather/along

Forecast weather along a route, aligned to each point's ETA (see module docs).

GET/v1/zones

The curated UK zone dataset, with provenance.

self-serve

Agent-first self-serve keys: one-call signup, magic-link verification, quota-free status poll. Beyond the free tier, 402 responses use the x402 machine-payment wire format

GET/v1/jobs

List the caller's recent jobs (quota-free).

GET/v1/jobs/{id}

Read one job (quota-free).

POST/v1/keys

One-call signup: issues a provisional key and emails a magic verification link.

DELETE/v1/keys/self

Deletes the caller's account, per app: a verified key revokes every key of the identity behind it that carries the same label (each MapMap app labels its own key), and, when no other active key remains on the identity, deletes the account itself and erases its email, IP addresses and user agents. An unverified (`provisional`) key revokes only itself, and deletes the account only when it is the account's sole key: anyone who types an address can mint one, so it never speaks for the account. On the store-review identity any key deletes only itself, because that address is not a secret (security check M3). Idempotent: a retry with the same, now revoked, key answers 200 with `already_deleted`.

GET/v1/keys/self

Key status for the calling agent (quota-free: polling it never consumes the free tier).

POST/v1/keys/self/email

Sends a one-time code to an address for the calling email-less (`anonymous`) key. Nothing changes until the SAME key sends the code back to `POST /v1/keys/self/email/verify`; meanwhile `GET /v1/keys/self` shows the address as `pending_email`. Sending again (a corrected address, or a resend) replaces the pending address and voids the earlier code.

POST/v1/keys/self/email/verify

Proves the address: the calling email-less key sends back the code `POST /v1/keys/self/email` mailed. On success the address becomes this key's account's, and THIS key, and only this key, is lifted to `verified` on the free tier, which also unlocks offline downloads.

POST/v1/keys/self/webhook-secret

Mint (or rotate) the calling key's webhook signing secret (quota-free).

GET/v1/keys/verify

The emailed link's landing page. **Opening it changes nothing** (review of #1339, H1): mail security scanners and a single stray click open links, so a link that confirmed on GET could confirm a key a stranger asked for. The page shows the request (the app it said it came from, or that it named none, the time and the device class; no location is recorded) and confirms or refuses only on an explicit button, which POSTs to [`confirm_key`] or [`deny_key`].

POST/v1/keys/verify

Confirms the ONE key a link was mailed for, upgrading it to the verified free tier (or the plan already bought). Only an explicit press of the page's button reaches this (review of #1339, H1).

POST/v1/keys/verify/deny

"This wasn't me": revokes the key a link was mailed for and spends the link. The owner of the address refuses a key somebody asked for against it (review of #1339, H1).

POST/v1/keys/verify/details

What the confirmation page shows: the request behind a link, without consuming it. A POST, so the token stays out of URLs and logs.

GET/v1/usage

The calling key's own metered units, day by day and endpoint by endpoint (quota-free: reading it never spends units).

POST/v1/x402/topup

`POST /v1/x402/topup?usd={bundle}`.

static-maps

Rendered map images for callers that can look at a map but cannot run one: camera, overlays (encoded polyline, GeoJSON, markers) and format in the query string, or the GeoJSON overlay in a POST body. The gateway renders nothing itself: it checks the key, meters the call and proxies the same renderer the keyless website route uses, so the keyed image and the keyless one cannot disagree. The renderer's own ETag and Cache-Control pass through untouched. Standard price class, a flat block of units per image

styles

Hosted style API (MapMap Studio): versioned, immutable MapLibre styles compiled from sn-style theme documents. Compiled-style and theme reads are public and unmetered (browser map clients fetch them by bare URL); listing is authenticated and scoped to the caller's own styles; publishes are metered at the Standard price class and enforce ownership

territories

Metered territory update-channel downloads (signed static files; devices verify signatures and hashes themselves)

tiles

Hosted vector-tiles API: per-tile MVT, TileJSON and a MapLibre style from the territory PMTiles. Standard price class, metered per request

timezone

Timezone-at-coordinate: IANA zone id, UTC offset, DST offset and abbreviation at a given timestamp. Backed by Valhalla's own timezones.sqlite boundary database and chrono-tz's IANA rules. 501 unless the operator sets SN_TIMEZONE_SQLITE. Standard price class, metered per request

transit

Live public-transport positions for display: England local buses from the DfT Bus Open Data Service (BODS SIRI-VM), as GeoJSON for a bounding box, with the feed's freshness on every answer (a stale feed is a field, never an error) and the Open Government Licence v3.0 attribution. Also England bus and coach stops (NaPTAN) near a point and timetabled departures at a stop (BODS timetables), each departure optionally paired with a vehicle seen on its line heading towards the stop. Display only: no journey-time, timetable-routing or arrival-prediction answers. Standard price class, one unit per request; a browser (`maps`) key may call them. 501 unless the operator sets SN_TRANSIT_DIR (and, for stops and departures, builds the departures index in it)

voice

Guidance voice clips: synthesise-once, cache-forever audio for the closed navigation grammar. The app asks for the utterances a route will speak and plays the returned files; the gateway keeps every clip forever, so a sentence is synthesised once across every driver. Synthesis is metered one unit per NEW clip (cache hits are refunded); fetching a cached clip and listing the bank are key-authenticated and quota-free. 501 unless the operator sets SN_VOICE_DIR and at least one of SN_ELEVENLABS_API_KEY (ElevenLabs) and SN_TTS_URL (the self-hosted open-source voices). A clip answered by an open-source fallback voice carries its own hash and `fallback: true`, so clients take hashes from the response. The synthesis key can never ship in an app (ElevenAPI Terms), which is why this endpoint exists at all