One Server

Docs

Three kinds of key

What the publishable key, secret key and access token are for, and which one must never be in a browser.

Three kinds of key

get_project_keys gives you all three. They have different uses, and putting one in the wrong place causes incidents.

KeyWhereWhat it can do
Publishable keyFine in browsers and appsOnly what the access rules allow
Secret keyOn the server onlyBypasses every access rule
Access token (PAT)This MCP server and the management APICreates and deletes projects

Keys per use

The two keys from get_project_keys are tied together, so if one leaks you have to replace both. To give each server or app its own key, create named keys with create_api_key. bw_publishable_… has the same rights as the publishable key, bw_secret_… the same as the secret key. list_api_keys shows when each key was last used, so revoke unused keys one by one with revoke_api_key.

When a key leaks

get_jwt_signing      the signing method (HS256 | ES256) and old keys still accepted
rotate_signing_key   a new key to sign the publishable and secret keys (grace_hours: 0, 1, 24, 168)
retire_signing_key   end an old key's grace period now
set_jwt_signing      sign-in tokens as ES256 (other servers verify them with a public key)

rotate_signing_key changes both keys from get_project_keys. Every key in your apps has to be moved over, so after a leak use grace_hours: 0; for a planned rotation, allow as much grace as moving takes. Only owners and admins can do this. With grace_hours: 0 (or empty), put the project name exactly in confirm. When you only need values for frontend code, call get_project_keys { ref, only: "publishable" } to get just the address and the publishable key.

Never do this

Never put the secret key in browser code, a mobile app or a public repository. That key reads and writes every table in the project with no rules applied. If a key has to go into frontend code, it is always the publishable key.

Addresses

The project API is at https://<ref>.<zone>. get_project_keys tells you this too.

GET  https://<ref>.<zone>/rest/v1/notes?select=*     apikey: <publishable key>
POST https://<ref>.<zone>/auth/v1/signup             apikey: <publishable key>