Authentication and keys
The bsk_… key format, scopes, permission model, and auth-related error codes.
Key format
A key looks like bsk_<prefix8>_<secret40>[<check6>] — bsk for "Brault secret key", an
8-character prefix used to look the key up, a 46-character secret, generated with
crypto.randomBytes and base62-encoded. The trailing check6 is a 6-character CRC32
checksum, also base62, computed over everything before it — it exists so an automated
secret scanner can validate a key's shape offline, without calling the API, the same idea
GitHub's own tokens use. It is shown once, at creation — there is no roll for bsk_…
keys; to replace one, create a new key and revoke the old. Afterwards only name, a
prefix and the last 4 characters are ever shown again.
Keys are created, renamed, paused, resumed, revoked, transferred and deleted from
Settings → Developers → API keys in the Brault web app — there is no /v1 route for
key management. Presets in the panel are Read only (every *:read scope) and
Full access (every scope); custom selections are allowed too.
Sending the key
Authorization: Bearer bsk_a1b2c3d4_…This is the only transport the API accepts. A key sent any other way — a query parameter,
most commonly — is rejected with 401 invalid_auth_transport and is never echoed back in
the error, so it never lands in a log or a browser history from that response.
Expiration is optional, set from the panel (30/90/365 days or a specific date). An expired
key answers 401 api_key_expired.
Who a key acts as
A key acts as the person who created it, capped by the key's own scopes:
effective permissions = creator's permissions ∩ key's scopesLibraries, folders and boards the creator cannot see are invisible to the key, exactly as they would be to that person in the web app. If the creator leaves the brandspace, is removed, or loses the role that granted an action, the key is paused automatically — an owner or admin can transfer it to another member, which makes them the new authorizing identity (the original creator stays in the audit trail).
Scopes
Every plan with API access can grant every scope below — plans differ in rate limits, not in which scopes exist.
| Scope | Covers |
|---|---|
files:read | Libraries, folders, files, versions, downloads, search, brandspace property values (read). |
files:write | Create/rename/move/tag/trash/restore/delete files and folders, uploads, versions, property values. |
boards:read | Boards, board properties and their options, board files and values (read). |
boards:write | Board CRUD, adding/removing files, setting values, managing properties. |
pages:read / pages:write | Listing/reading pages; creating, publishing/unpublishing, appending blocks. |
comments:read / comments:write | Comments and replies on files. |
shares:read / shares:write | Shared links. |
transfers:read / transfers:write | Transfers: create, list, read, update the expiry or password, expire one early. |
members:read | Brandspace members and roles — needed to resolve a person value or an author.user_id into a name. |
webhooks:manage | Webhook endpoints and their deliveries. There is no separate read-only webhooks scope. |
A key without the scope a route needs answers 403 insufficient_scope.
Errors specific to authentication
Every failure renders the standard error envelope (see Conventions § Errors). These codes are specific to resolving the key itself:
| Code | HTTP status | Meaning |
|---|---|---|
unauthorized | 401 | No key presented, or the guard could not authenticate it. |
api_key_invalid | 401 | The key does not resolve to an active row. |
api_key_paused | 401 | The key exists but is paused — manually, or automatically because its creator lost access. |
api_key_revoked | 401 | The key has been revoked. Terminal. |
api_key_expired | 401 | Past its expires_at. |
api_key_orphaned | 401 | The creator no longer has brandspace access; an admin must transfer the key. |
invalid_auth_transport | 401 | The key was sent somewhere other than the Authorization: Bearer header. |
insufficient_scope | 403 | The key's scopes do not cover this endpoint. |
forbidden | 403 | The creator must satisfy a brandspace security requirement first — in practice, mandatory two-factor enrollment. |
plan_without_api | 403 | The brandspace's plan does not include API access (Free). details.upgrade_url points at the pricing page. |
A denial that is really about which id you can reach — rather than a fact about the key
itself — is never a 403. See Conventions § Errors for why a
cross-tenant id and a same-tenant permission denial both answer a plain 404.