API Keys

API keys are long-lived, scoped credentials for callers that run without a browser: a backend service, a CI job, or an autonomous AI agent. A key carries exactly the scopes you grant it, is bound to one organization, and can be rotated or revoked at any time.

After reading this page you will be able to: create a key scoped to only what a caller needs, read and reason about the scope allowlist, set the mandatory expiry, rotate a key with no downtime, revoke a key immediately, and explain to a security reviewer why a key can never exceed its grant or reach another organization.

API keys are available on every plan, including Free. Use them anywhere you would otherwise paste a user access token into a machine.

Key Format

bb_live_{prefix}_{secret}

A key has three parts: the bb_live_ label, a short public prefix that identifies the key in listings and audit logs, and a long secret. Only the secret grants access. Present the whole value in the standard header:

Authorization: Bearer bb_live_abc123_yourLongSecret

The Secret Is Shown Once

The full key value is returned only in the response to the create call. It is never shown again and cannot be recovered: the platform stores only what it needs to verify the key, not the secret itself. Copy the value into your secret manager the moment you create it. If you lose it, revoke the key and create a new one; there is no way to reveal it after the fact.

The API Key Created dialog shown immediately after a key is created. It warns that the key is shown only once. Callout 1 circles the full bb_live_ secret value in its copy-to-clipboard field, with a red label reading shown once, copy it now, alongside a Copy to Clipboard button and a Done button.
The create response, and this dialog, are the only place the full key value ever appears. If you lose it, revoke the key and create a new one.

Create a Key

POST /v1/api-keys

Creating a key requires a recently completed authentication (a step-up re-auth). If your session’s authentication is stale, the request is rejected and you must re-authenticate before retrying. This applies to creating, rotating, and revoking keys, because each is a credential-lifecycle action.

Request Body

{
  "name": "CI deploy bot",
  "scopes": ["bbdocs", "mcp:secrets.read"],
  "expires_in_days": 90
}
FieldRequiredDescription
nameYesA human label so you can identify and revoke the key later
scopesYesThe allowlisted scopes the key may use (see below)
expires_in_daysRecommendedLifetime in days, 1 to 365. If you omit it, the key is created with the maximum 365-day lifetime. There is no non-expiring key.

Response

The response carries the full key value once, plus the key’s identifying metadata. The scopes and expiry you set are stored on the key and are returned whenever you list your keys.

{
  "success": true,
  "data": {
    "id": "...",
    "name": "CI deploy bot",
    "prefix": "abc123",
    "key": "bb_live_abc123_yourLongSecret",
    "created_at": "2026-07-16T00:00:00Z"
  }
}

Mandatory Expiry

Every key expires; there is no permanent key. When you supply expires_in_days it must be between 1 and 365; if you omit it, the key is created with the maximum 365-day lifetime. This is a deliberate rotation-hygiene control: a leaked key that is never rotated is one of the most common ways credentials are abused, so the platform caps the lifetime and expects you to rotate on a schedule. Pick the shortest lifetime that fits the caller’s job (30 or 90 days is typical for a service; 1 day is right for a short-lived agent run).

Scopes

Scopes are an allowlist: a key can do only what its scopes permit, and nothing else. There are no wildcard grants beyond the explicit MCP grant described below, so you never accidentally hand a key “everything.” Scopes come in two grains.

GrainExamplesWhat it grants
Fine-grained mcp:secrets.read, mcp:secrets.write One specific capability. Prefer these for least privilege.
Coarse bbdocs, bbsheet, secrets A whole product area.
MCP grant mcp:* Every MCP tool. Use only for a trusted, general-purpose agent.

When a key calls an MCP tool, the key is authorized if its scopes contain the tool’s fine-grained scope or the matching coarse grant or mcp:*. So a key with mcp:secrets.read can read secrets through MCP but not write them, while a key with mcp:* can use every tool. Grant the narrowest set that lets the caller do its job.

An unknown or unsupported scope is rejected at create time with a 400 whose message lists the scopes you are allowed to request, so a typo fails loudly rather than silently under-granting.

A scope-gate diagram with two rows. In the top row, a least-privilege key holding the scopes bbdocs and mcp:secrets.read passes through a scope check: the secrets.read tool is lit and callable, while the secrets.write tool is locked and denied because the key has no matching scope. In the bottom row, a trusted agent key holding mcp:* passes the same check and every tool, including both secrets.read and secrets.write, is lit and callable.
A key reaches a tool only when its scopes contain the tool’s fine-grained scope, the matching coarse grant, or mcp:*.

List Keys

GET /v1/api-keys

Returns every key in the organization with its metadata (id, name, prefix, scopes, expiry, last-used and created timestamps). The secret is never included. A convenience read is also available at GET /v1/settings/api-keys.

{
  "success": true,
  "data": {
    "keys": [
      {
        "id": "...",
        "name": "CI deploy bot",
        "prefix": "abc123",
        "scopes": ["bbdocs", "mcp:secrets.read"],
        "last_used_at": null,
        "expires_at": "2026-10-14T00:00:00Z",
        "created_at": "2026-07-16T00:00:00Z"
      }
    ]
  }
}

Rotate a Key With No Downtime

POST /v1/api-keys/{id}/rotate

Rotation issues a fresh secret that carries over the retired key’s name, scopes, rate limit, and expiry, so you do not re-grant anything. Requires a step-up re-auth, like creation. The response returns the new full value once, exactly as create does. Crucially, the old secret does not stop working the instant you rotate: it stays valid for a short overlap window (a few minutes by default) so in-flight requests are not dropped mid-rollout. Roll it out like this:

  1. Call rotate and capture the new key value from the response.
  2. Deploy the new value to every service, within the overlap window.
  3. Confirm all traffic is on the new value (watch the new key’s last-used and your logs).
  4. The old secret retires automatically when the overlap window ends; after that it returns 401.

Because the new key inherits the retired key’s scopes and configuration, you rotate on a schedule without editing scope grants or reconfiguring the caller.

A rotation timeline with two lanes. The old value lane is valid from the start and stays valid through an overlap window. At the rotate milestone a new value is issued and its lane begins. The four milestones in order are rotate (new secret issued), deploy the new value to services, traffic cuts over to the new value, and retire the old value once the rollout is finished. During the highlighted overlap window both values work, so no request is dropped.
The new key carries over the retired key’s scopes and configuration. During the overlap window both values work, so services cut over with no dropped request.

Revoke a Key

DELETE /v1/api-keys/{id}

Revoking a key invalidates it immediately; any caller still presenting it starts receiving 401. Requires a step-up re-auth. Revoke a key the moment it is no longer needed or is suspected of exposure, then create a fresh scoped key for the caller that still needs access.

Security Guarantees

  • A key holds only its scopes. It can never perform an action outside the allowlist you granted, and there is no hidden elevated context.
  • A key is bound to one organization. It cannot read or write another organization’s data; a cross-organization id simply reads as not found.
  • The secret is never echoed. After creation or rotation it is unrecoverable. Store it in a secret manager, never in source control.
  • Lifecycle actions require step-up. Creating, rotating, or revoking a key needs a recently completed authentication, so a stale session cannot mint or destroy credentials.
  • Every key expires. The mandatory 1 to 365 day lifetime enforces rotation hygiene.

Frequently Asked Questions

Can I see the key again after I create it?
No. The full value is shown once, at creation (and again after each rotation). If you lose it, revoke the key and create a new one.

How do I rotate without downtime?
Call rotate, deploy the new value everywhere within the overlap window, confirm traffic has cut over, then let the old secret retire when the window ends. The new key carries over the retired key’s scopes and configuration.

Can I avoid wildcard grants?
Yes, and you should. Grant fine-grained scopes such as mcp:secrets.read rather than mcp:*. A key holds only its allowlisted scopes.

Why must a key have an expiry?
Every key expires (1 to 365 days) as a rotation control. There is no permanent key, so a forgotten leaked key cannot live forever.

How is a key different from a user access token?
An access token is short-lived and tied to a signed-in user session; a key is long-lived, scoped, and revocable, and it needs no interactive login, which is what makes it right for servers and agents. Both are bounded by the access of the identity behind them. See MCP Server for how a key drives agent tools.

My create call was rejected even though I am signed in. Why?
Key creation requires a recent authentication. Re-authenticate (a step-up re-auth) and retry.