Docs navigation
Authentication
How to authenticate against the tile API. For how credentials are stored and protected, see the security model.
Two paths, same wire format
Tile endpoints accept either a short-lived access token minted from an API key, or — for app-mode keys (no origins registered) — the API key itself as a bearer credential. Both arrive as Authorization: Bearer … (or ?token= on the token path); the difference is lifetime and blast radius, not request shape.
- Browsers: exchange a browser-mode key for an access token. 15-minute lifetime, origin-locked, plays well with
@tilery/clientand the offline cache. - Trusted backends, mobile, CI, scripts: use an app-mode key directly. One credential, no exchange call. Long-lived — only safe in environments you control end-to-end.
tiles.tilery.eu returns 401. This is enforced server-side; it is not an advisory.Token exchange (browser path)
Your backend exchanges an API key for an access token at POST /api/tokens/exchange on the web origin (not the API origin). The ttl is optional and capped at 900 seconds (15 minutes). Browser-mode keys must use this path.
POST /api/tokens/exchange HTTP/1.1
Host: tilery.eu
Authorization: Bearer <api-key>
Content-Type: application/json
{ "ttl": 900 }
Re-exchange before exp. @tilery/client does this automatically.
Fetching a tile with a credential
On the access-token path, pass the token as a ?token= query param on every tile, font, sprite, and style URL. The query form is what @tilery/client uses — it avoids a CORS preflight that an Authorization header would trigger.
GET /map/tiles/vector/0/0/0?token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIi... HTTP/1.1
Host: tiles.tilery.eu
Origin: https://yoursite.com
Direct API-key authentication (app-mode keys only)
App-mode keys (created without any registered origins) can be sent straight to the tile API as a bearer credential — skipping /api/tokens/exchange entirely. Convenient for server-to-server callers, but the credential is long-lived: a leak isn't bounded by a 15-minute TTL the way an access-token leak is, and the origin allowlist doesn't apply. See the security model for the tradeoff in full.
# App-mode key only (no origins registered).
# Long-lived credential — keep it on a backend you control.
curl -H "Authorization: Bearer $TILERY_API_KEY" \
https://tiles.tilery.eu/map/tiles/vector/0/0/0 \
-o tile.pbf
Only use this path from environments you fully control. Anywhere a browser or untrusted process can read the key, mint access tokens via the exchange endpoint instead.
Caching and token rotation
Because the access token lives in the URL, a naive browser cache treats each token rotation as a brand new URL and re-downloads every tile. The @tilery/client service worker fixes this by intercepting tile fetches and normalizing the cache key (stripping ?token=), so repeat tiles stay served from the cache across rotations — and keep working offline.
Without the client SDK you lose this benefit. Use the SDK unless you have a specific reason not to.
Origin header check (browser path)
On the access-token path, requests that carry an Origin header (always the case from browsers) are matched against the allowlist configured per key under API Keys. A mismatch returns 403 Forbidden. Requests without an Origin header (server-to-server, curl, mobile apps) pass this check — CORS is a browser concept.
Direct API-key authentication doesn't enforce origins because app-mode keys have none registered; the safety boundary there is "the key never leaves a backend you trust." See the security model for configuration guidance.
Error statuses
| Status | Meaning | Typical cause |
|---|---|---|
400 | Bad request | Invalid tile coordinates (zoom out of range, etc.). |
401 | Unauthorized | Missing credential, expired access token, signature mismatch, revoked key, or a browser-mode API key sent directly without exchanging for an access token first. |
402 | Payment required | Credit balance exhausted, past the overrun allowance (quantified on Pricing). Top up to resume serving — usage served past zero is collected from that top-up automatically. |
403 | Forbidden | Request Origin is not on your account's allowlist. |
404 | Not found | Coordinates are valid but the archive has no tile at that position. |
429 | Too many requests | Per-IP RPS limit exceeded, or brute-force block from too many recent auth failures. Not an empty credit balance — that's 402. |
Related
- Security model — credential storage, access-token internals, rate limits, and incident recovery.
- API reference — try the exchange endpoint with your real key.