Authentication & API keys
Every request to https://api.zeemaps.com/v1/* is authenticated with an API key sent as a
Bearer token. There is no cookie or session fallback — the API authenticates only via
the Authorization header.
curl -s "https://api.zeemaps.com/v1/me" \
-H "Authorization: Bearer zm_your_api_key_here"
API keys
- Keys are minted by ZeeMaps on request and returned once, at mint time. ZeeMaps stores
only a SHA-256 hash of the key plus a short display prefix (e.g.
zm_a1b2c3…) — it cannot show you the full key again, so save it somewhere safe. - Keys look like
zm_followed by a random token. - An account can hold more than one key (for example a
Productionkey and aStagingkey), each with its own scope and, optionally, its own rate limit. - A key acts as its owning account. It can reach exactly the maps that account owns (see Conventions → Owned-only).
Scopes
Each key has one of two scopes:
| Scope | Can do | Rejected on |
|---|---|---|
read_only |
GET requests |
any write (POST / PATCH / DELETE) → 403 FORBIDDEN |
read_write |
all requests | — |
Check a key’s scope at any time with GET /v1/me,
which returns scope alongside the account email, plan, and rate limit.
The enterprise-plan requirement
API access requires the enterprise plan. A key can be minted for any account, but it only works while that account is on the enterprise plan. A valid key on a lower plan is rejected on every endpoint with:
HTTP/1.1 402 Payment Required
Content-Type: application/json
{
"error": {
"code": "PLAN_REQUIRED",
"message": "API access requires the enterprise plan.",
"help_url": "https://www.zeemaps.com/pricing?upgrade=enterprise"
}
}
402 PLAN_REQUIRED always means “upgrade the account”, never “bad key”. (A bad or revoked
key returns 401.)
How to request a key
For v1, keys are admin-minted — there is no self-serve key creation through the API.
- In the ZeeMaps dashboard go to Settings → API.
- Submit the request form (a label, e.g.
Production, and your intended use). This notifies the ZeeMaps team; it does not mint a key by itself. - ZeeMaps mints the key and delivers the raw value to you once. Paste it into your client or MCP configuration.
- From Settings → API you can see your active key’s label and prefix and request revocation.
Any account may request a key, but remember it only becomes usable once the account is on the enterprise plan.
The help_url deep-link / bootstrap flow
A brand-new client — especially an automated one like an MCP server — faces a chicken-and-egg problem: a key-gated API cannot mint its own first credential, and the client has no access to your authenticated web session. v1 solves this out of band.
On the two auth-failure responses, the error envelope carries an actionable help_url:
| Status | error.code |
help_url points to |
|---|---|---|
401 |
UNAUTHORIZED |
the request-an-API-key page (Settings → API) |
402 |
PLAN_REQUIRED |
the upgrade-to-enterprise page |
A client that hits a 401/402 surfaces this link to the user, who completes the request
or upgrade in their logged-in dashboard. The resulting key is then pasted back into the
client. This keeps provisioning in the user’s authenticated session while letting an
unattended client recover gracefully.
Note. Agent-obtains-access-on-behalf-of-a-user with explicit consent is the OAuth 2.0 case, which is out of scope for v1. v1 is Bearer keys only.
Security notes
- Send keys only over HTTPS. Requests over HTTP are redirected to HTTPS.
- Treat a key like a password: never commit it, never put it in client-side code or a URL.
- If a key is exposed, request revocation from Settings → API and rotate to a new one.
- Cross-origin (
CORS) requests are allowed with a wildcard origin precisely because the API is Bearer-only and never trusts ambient cookies.
Related
- Errors — the full envelope and status-code table.
- Rate limits — per-key limits and headers.
GET /mereference.