All pages

Authentication

Every /v1 request carries an API key. A dashboard session token will not work here, and a key will not work on the dashboard's own endpoints; the two are deliberately separate. Connecting an app such as Claude.ai or ChatGPT is the one case where you never handle a key yourself - you sign in with your Mastheads login instead, and Full access & MCP covers what that looks like.

Getting a key

Mint one in the dashboard under Settings → Account → API access. Keys start with mh_live_ and you can hold up to 3 active at a time. Revoke one to make room for another.

You also choose what the key may do: Read only, the default, or Full access, which can also start work. That choice is fixed for the life of the key - there is no switch, so a spending key is a new key. See Full access & MCP.

The key is shown once, at the moment you create it. We store only a hash of it, so we cannot show it to you again and cannot recover it for you. Copy it straight into your secret store. Lost it? Revoke it and mint another.

Sending the key

Send it as an Authorization: Bearer header. An X-Api-Key header works too, if that fits your tooling better.

curl https://api.mastheads.app/v1/editions \
  -H "Authorization: Bearer mh_live_your_key_here"

Send only one. If the Authorization header starts with Bearer , that is the credential we check and X-Api-Key is never read - so a stale Bearer alongside a good X-Api-Key is a 401, not a fallback.

Plan access

The content API is on Growth and Pro. Minting a key on a plan without it is refused in the database rather than by the interface, so there is no version of the screen that lets one through.

The plan is checked again on the request, not only when the key was made. If the plan lapses or is downgraded, a key that is still valid answers 402 plan_required from then on, and a closed account answers 401 account_closed. Both are immediate; there is no grace window to plan around.

Key lifecycle

Keys are server-side secrets. Never ship one in browser code, in a mobile app, or in a public repository: it can read the articles on your account, and a full-access key can spend from your allowance. Reading covers the image endpoint too, so an image URL from the API cannot be used as a public <img src>.

Revoke a key in Settings at any time. Revocation is checked on every request, so it takes effect immediately with no propagation delay and nothing to purge. The dashboard also shows when each key was last used, stamped at most once a minute so a busy puller does not pay for the bookkeeping.

Keys do not expire on a timer and there is no rotation deadline. If you want rotation, mint the new key first, move your integration over, then revoke the old one - you have three slots so the two can overlap.

When a key is rejected

A missing, malformed, unknown or revoked key is a 401 with the code invalid_key. The message is deliberately the same for all four, so a probe cannot tell which one it hit.

{
  "error": {
    "code": "invalid_key",
    "message": "Missing, invalid, or revoked API key"
  }
}

Repeated failures from one address are throttled at 30 per minute and answer 429. If you are seeing that while testing, you are being counted with everyone else behind your address - wait a minute rather than retrying in a loop. The full table is on Rate limits & errors.