Conventions
Conventions
A few cross-cutting rules apply across the whole API. Reading this page once will save you debugging time later.
Base URL & versioning
All endpoints are served under a versioned prefix:
https://navvo.io/api/v1
Paths in this reference are written in full, e.g. GET /api/v1/search.
Service health
GET /api/v1/health is a public, unauthenticated probe you can poll from your own monitoring.
{
"ok": true,
"strict": false,
"service": "navvo-api",
"time": "2026-07-27T14:08:23.552Z",
"dependencies": { "mysql": true, "redis": true, "routing": true, "nominatim": true },
"search": { "engine": "navvo-search", "configured": true }
}
okis the overall API verdict: it reflects the datastore layer only, so a degraded optional dependency does not flip it tofalse.dependencies.routingis Navvo's own routing engine;nominatimis the geocoding backend. Each probe has a 2-second timeout and reportsfalse(never an error) when unreachable. One additional deprecated alias key mirroringroutingis still emitted for backwards compatibility with older monitors; do not depend on it.search.enginetells you what is actually answering/search—navvo-search(the full search index) orfallback(the degraded database search used while the index is unreachable).search.configuredis whether a search index is configured at all. Earlier releases reported these two states under different names; update any monitor that matched the old strings.strictreflects the deployment's strict-health mode.
Request & response format
- Request bodies are JSON (
Content-Type: application/json), except file uploads. - Responses are JSON unless the endpoint returns a tile or image (vector tiles, PNG/JPEG, SVG, or
.pbfglyphs/sprites) — those return the appropriate binary/image/*content type. - Unknown body fields are silently stripped. The API validates and whitelists request bodies, so extra properties you send are dropped rather than rejected.
POSThandlers return201 Createdon success (a NestJS default), even for compute-only endpoints like routing.
Request IDs & errors
Every response carries an x-request-id header, and every error body repeats it as requestId.
Quote it when reporting a problem — it identifies the exact request in our logs, so nothing has to be
reproduced from a description.
x-request-id: 09de21ef-fa8f-4815-8453-9a19a3132763
Error bodies keep the shape v1 clients already parse and add two fields:
{
"statusCode": 404,
"error": "Not Found",
"message": "Place \"ardh-cafe-ard-kafyh-2bd24a\" not found.",
"code": "NOT_FOUND",
"requestId": "847c7a9b-a7c8-4b61-b138-d4e6b585626a"
}
statusCode, error and message are unchanged. code is a stable machine-readable identifier —
branch on it rather than on message, which is prose and may be reworded. Codes you may want to handle
specifically include UNAUTHENTICATED, NOT_FOUND, VALIDATION_ERROR, QUOTA_EXCEEDED, RATE_LIMITED and
DESTINATION_OUT_OF_COVERAGE.
Cross-origin (CORS)
The API reflects the request Origin, so you can call it from browser JavaScript on any domain — a third-party site embedding the keyed Navvo Web SDK, a static map <img>, or your own web app. Authentication is header/query based (x-api-key, Authorization: Bearer, api_key) and cookie-free, so open CORS carries no ambient-authority risk. Native mobile apps aren't subject to browser CORS at all. Prefer keeping secret keys server-side where you can (see Rate limits → Keep keys server-side).
A browser hides most response headers from cross-origin scripts unless the API exposes them. Navvo exposes these, so your browser code can read them with response.headers.get(…):
x-request-idRetry-AfterX-RateLimit-Limit,X-RateLimit-Remaining,X-RateLimit-Resetx-navvo-quota-limit-minute,x-navvo-quota-remaining-minute,x-navvo-quota-limit-day,x-navvo-quota-remaining-day,x-navvo-quota-reset-minute,x-navvo-quota-unlimited
Rate limits → Response headers explains what each limit header means.
Coordinates
| Where | Format | Notes |
|---|---|---|
| GeoJSON output (overlays, isochrones, incidents, traffic, weather) | [lng, lat] | Standard GeoJSON — longitude first. |
Place center / entrance location | POINT(lng lat) (WKT string) | Longitude first. Parse the string yourself. |
bbox query parameter | west,south,east,north | i.e. minLng,minLat,maxLng,maxLat. |
Routing raw payload (route/matrix/etc.) | { "lat": …, "lon": … } objects | The routing engine's native format — note lon, not lng. |
Routing /plan, Traffic /route | { "lon": …, "lat": … } objects | Navvo-defined; keys named, so order is irrelevant. |
| Geocoding reverse | lat & lon query params | Separate parameters. |
Geo 3D way geometry | POINT/LINESTRING/POLYGON(x y) in EPSG:3857 | Web-Mercator meters, not degrees. |
Bounding boxes
Endpoints that filter by area accept a bbox query parameter as four comma-separated numbers:
bbox=west,south,east,north e.g. bbox=35.85,31.90,35.99,31.99
This is minLng,minLat,maxLng,maxLat. A bbox must satisfy west < east and south < north. Many endpoints cap the bbox span server-side based on zoom to protect performance.
Tiles ({z}/{x}/{y})
Tile endpoints use the standard slippy-map / XYZ scheme: z is the zoom (origin top-left, y measured from the north). Tile coordinates must satisfy 0 ≤ z ≤ 22 and 0 ≤ x,y < 2^z. Some tile routes accept a file extension on {y} (e.g. .png, .pbf, .json) which is stripped before parsing.
For loading bounded areas efficiently, many overlays expose a tile-cover endpoint that returns the exact list of tile URLs covering a bbox.
Pagination
List endpoints that paginate use page (1-based) and limit query parameters and return an envelope:
{ "items": [ ], "total": 137, "page": 1, "limit": 50 }
There is no nextPage cursor — compare page * limit against total to know when to stop. Per-endpoint limit caps apply (see each reference page).
Units
- Distances: kilometers unless an endpoint states otherwise.
- Durations: seconds (some responses also include a rounded
*Minutesfield). - Speeds: km/h in responses; the telemetry ingest input uses m/s.
- Timestamps: ISO-8601 strings (UTC), e.g.
2026-06-09T08:30:00.000Z.
Localization
Navvo is bilingual. Many place objects include both nameEn and nameAr. Where a locale parameter is accepted, en and ar are supported.
Attribution
When you display Navvo map tiles, styles, street-level imagery, or data derived from them, show the Navvo attribution. Navvo style/tile responses carry the attribution string (e.g. 2026 © Navvo) in their attribution / metadata fields, and imagery responses set sourceAttributionRequired: true (Navvo imagery attribution is mandatory). One exception: the aerial imagery in the satellite map style is licensed third-party imagery served from the provider's own CDN, and its style source carries Imagery © Esri, Maxar, Earthstar Geographics alongside © Navvo — display both whenever you render that style. See Map Tiles & Styles → Attribution.