Authentication

Every endpoint under /api/v1 requires a key. There is no anonymous access.

Sending your key

Two headers are accepted. Prefer the first; the second exists because a lot of tooling reaches for it by default.

Authorization header (preferred)
Authorization: Bearer edm_live_...
x-api-key header
x-api-key: edm_live_...

Keys carry an edm_live_ prefix so they are recognisable in logs and in secret-scanning rules.

What a rejection looks like

Statuserror.typeMeaning
401missing_api_keyNo key on the request.
401invalid_api_keyNot a valid key, or it has been revoked or expired.
429rate_limit_exceededValid key, too many requests.

A revoked key and a rate-limited key are deliberately different statuses — conflating them sends you hunting for a credential problem you do not have.

How keys are stored

  • Hashed at rest. The plaintext is shown once at creation and never again.
  • Owned by your user account. Deleting the account deletes the keys.
  • Revocable at any time from the dashboard, taking effect immediately.

Keep keys server-side

A key in browser or mobile-app code is public, whatever the bundler does to it. Call the API from your own backend and keep the key there. If a key does leak, revoke it — that is the whole remedy, and it is instant.

Rotating

There is no in-place rotation. Create the replacement, deploy it, then revoke the old key — that way there is no window where neither works. You can hold several keys at once, which also makes it practical to give each service its own.

Which credential works where

The REST API takes an API key. The MCP server takes an API key or an OAuth 2.1 access token.

That asymmetry is deliberate rather than unfinished. MCP callers are assistants with a browser to authorize in, so OAuth is the better experience there and no secret is pasted anywhere. REST callers are software, which can hold a key perfectly well — and a key is simpler to rotate, scope and revoke than a token flow.

An OAuth token issued for the MCP endpoint will not work against /api/v1/*. Audiences are bound per resource, so a token minted for one cannot be replayed against the other. If you want both surfaces from the same program, use a key for both.

Scopes

Not yet. Keys currently grant the same read access as each other, matching your plan. The column exists in the key store, so scoped keys are additive when they arrive.

Manage keys at edmdb.net/account/developer.