Skip to main content
Every request carries a bearer key: Authorization: Bearer <key>. Keys are created in the dashboard, shown once, and stored only as a SHA-256 hash. There is no OAuth flow, so a person creates a key and your backend uses it.

Which key to use

Most integrations need one workspace key. Reach for a tenant key when a customer or a semi-trusted service should have direct access with a single tenant’s blast radius. Ship a client key in the app; it cannot read other subscribers or send.

Selecting a tenant

A workspace key implies its workspace. Add BuzzKit-Tenant: <slug> to work inside a specific tenant, the way a Stripe platform passes Stripe-Account. Leave it off and the default tenant is used, so a single-app integration never has to think about tenants.
Tenant keys already imply their tenant and need no header. A key used against a workspace or tenant it does not belong to is a 403, always.

Scopes

Every route declares one required scope, written as resource:action: messages:send, subscribers:read, events:write, topics:*, or * for everything a key may hold. The scope each operation needs is listed on its page in the API reference. A key without it gets a 403 with the code missing_permission.
Keys can never mint keys. keys:*, invites:*, members:write, workspace:delete and tenants:secrets are session-only and cannot be granted to a key at all. A key can only ever operate the data plane it was issued for, and revoking it ends that.

Errors

Every response, success or failure, uses the same envelope:
Branch on error.code, never on error.message. Quote metadata.requestId in support requests; it is also returned as the Request-Id header.

Rotation

For a zero-downtime rotation, create the replacement key first, move your backend over, then revoke the old one from the dashboard or with DELETE /v1/workspaces/:workspaceSlug/keys/:id. When a secret has leaked, rotate the key in place instead: POST /v1/workspaces/:workspaceSlug/keys/:id/rotate (or Rotate key on the dashboard’s API keys page) keeps the key’s id, name and scopes, kills the old secret at once and returns the new one exactly once. Revocation and rotation take effect immediately in the region that served the request and within about a minute everywhere else.