Authentication

Authentication

Every request to the MetaMonster API (except the health check) is authenticated with an API key sent as a Bearer token.

The Authorization header

Send your key in the Authorization header on every request:

Authorization: Bearer mm_YOUR_API_KEY

For example:

curl https://new.metamonster.ai/api/v1/sites \
  -H "Authorization: Bearer mm_aB3xK9pQ2rL7mN4vT1sY6wD8fH5gJ0cZ..."

The only endpoints that do not require a key are GET /health and GET /openapi.yaml (both per-IP rate limited).

Key format

A MetaMonster API key is a single opaque token:

mm_<43 random characters>
  • It always starts with the mm_ prefix.
  • The part after mm_ is the secret. The full string is the key — there's no separate ID and secret.
  • The dashboard displays a short prefix (mm_ + the first 4 characters, e.g. mm_aB3x) so you can tell keys apart without exposing the whole secret. The GET /me endpoint returns this prefix too.

Keep the full token secret. MetaMonster stores only a hash of it and can't show it to you again unless you use the dashboard's reveal button (see Key lifecycle).

Managing keys

Keys are created and managed in the dashboard under Settings → API Keys (/settings/api-keys). See Getting started for the step-by-step. There is no API endpoint for creating, listing, or revoking keys — key management is a dashboard-only operation.

Scopes

Every key carries one or more scopes that gate what it can do. Keys created in the dashboard are granted all scopes by default.

Scope Grants access to
sites:read All read endpoints — sites, pages, snapshots, analysis, drafts, and keyword metrics
content:write Write endpoints — update page metadata, save body content, and create/delete field drafts
cms:publish Publishing drafts to a connected CMS (reserved; no public endpoint uses this yet)

Each endpoint's reference page lists the scope it requires. If your key is missing the required scope, the request fails with 403 forbidden and a message like Missing required scope: content:write.

Key lifecycle

  • Reveal. After creation, you can reveal a key's full token again from the keys list (the eye icon), as long as the key hasn't been revoked. Keys created before reveal support was added can't be revealed.
  • Rename. You can rename a key at any time. This only changes its label — the token is unchanged.
  • Expiration. A key can be created with an expiration of Never, 30, 90, or 365 days. After it expires, requests using it fail with 401 unauthorized.
  • Revoke. Revoking a key disables it immediately and permanently. Any integration using it stops working at once. Revocation can't be undone — to rotate a key, create a new one and revoke the old.

Authentication errors

All auth failures return 401 unauthorized. The message tells you what went wrong:

Message Cause
Missing API key No Authorization: Bearer … header was sent
Invalid API key The token doesn't match any key
API key revoked The key has been revoked
API key expired The key's expiration has passed

A key that's valid but lacks the scope an endpoint requires returns 403 forbidden instead (see Scopes).

Response format note: Every /api/v1/* endpoint — GET /me and GET /health included — wraps errors in the standard envelope ({ "error": { "code", "message" } } — see Conventions).

OAuth access tokens (MCP connector)

The v1 API also accepts a Supabase OAuth access token minted through the claude.ai / Claude Desktop MCP connector flow, alongside mm_ API keys — mm_ keys are unchanged. An OAuth token is scoped to the organization chosen at consent time rather than to a dashboard-created key. See MCP server for how the connector flow works and how to revoke a connector's access.

Keeping keys safe

  • Never commit keys to source control or embed them in client-side code. The API is meant to be called from your server, not a browser or mobile app.
  • Store keys in environment variables or a secrets manager.
  • Use separate keys for separate integrations so you can revoke one without disrupting the others.
  • Rotate keys periodically by creating a new one and revoking the old.