Authentication and scopes
How Brix API keys work: key format, the Bearer header, resource.verb permissions, location-pinned keys, rotation, revocation and OAuth client credentials.
Every request carries one API key as a Bearer token:
curl https://api.brixsignage.com/v1/me \
-H "Authorization: Bearer $BRIX_API_KEY"
The key decides everything: which workspace the request acts on, what it may do, and which locations it can reach. There is no workspace header and no workspace id in the path.
Key format
ak_<region>_live_<32 characters>, for example ak_eu_live_....
regionis the workspace’s data region:us,eu,ocorapac. The API routes the request to that region. All regions use the same host,https://api.brixsignage.com.- Keys made before regions were tagged look like
ak_live_...and belong tous. - The CMS shows only a preview (the first 15 characters). Brix stores a SHA-256 hash, never the key itself. Brix cannot show you a lost key. Rotate it instead.
- Keys are for server-side use. Browser calls from other origins are refused by CORS. Do not put a key in front-end code.
Create a key
In the CMS: Settings > API & MCP > New key.
| Field | What it does |
|---|---|
| Name | A label, for example Roster sync - PowerSchool. |
| Limit to a location (optional) | Pins the key to one location and every location under it. Leave it empty for the whole workspace. |
| Full access | Every permission. Shown only to people who hold every permission. |
| Permissions | Areas such as Screens, Playlists, Files. Each area grants every action in that area that you hold. |
Select Create key, then copy the key from the panel. It is shown once.
Rules:
- You need
api-key.createto make a key,api-key.viewto list keys andapi-key.deleteto revoke one. - A key never gets a permission its creator does not hold:
403 "A key can't be granted permissions you don't hold." - A key for the whole workspace needs its permissions at the workspace level. Otherwise pin it to a location you control.
- Every workspace can create keys. There is no plan gate.
You can also manage keys over the API:
# Create (returns the secret once, in data.secret)
curl -X POST https://api.brixsignage.com/v1/api-keys \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" \
-d '{"name": "Nightly report", "permissions": ["screen.view", "playback-log.view"], "expiresInDays": 90}'
| Field | Notes |
|---|---|
name | Required. |
permissions | An array of resource.verb strings, or "all". |
nodeId | Optional. Pins the key to that location and everything under it. |
expiresInDays | Optional, 1 to 3650. Omit it for a key that does not expire. The CMS does not set an expiry. |
A key’s record has id, name, preview, permissions, nodeId, lastUsedAt, expiresAt, expired, revokedAt and createdAt. The secret is never returned again after create or rotate.
Rotate and revoke
- Rotate:
POST /v1/api-keys/{id}/rotate, or Rotate in the CMS. Returns a new secret once. The old secret stops working at once. Name, permissions, location and expiry stay the same. You cannot rotate a revoked key (409 revoked). - Revoke:
DELETE /v1/api-keys/{id}, or Revoke in the CMS. Every integration that uses the key stops at once. This cannot be undone.
An expired or revoked key gets 401 invalid_credentials, the same as an unknown key.
Permissions (scopes)
A permission is resource.verb. Every endpoint requires exactly one, shown in the API reference and in the spec as x-brix-permission. A missing permission returns:
{ "error": "forbidden", "message": "Missing permission: screen.cast" }
| Resource | Verbs |
|---|---|
screen | view, create, edit, delete, cast, manage-permissions |
playlist, schedule | view, create, edit, delete, approve, publish, share, manage-permissions |
layout, creative | view, create, edit, delete, approve, publish, share |
media (Files) | view, create, edit, delete, share, export |
font | view, create, delete |
app-instance | view, create, edit, delete, share |
brand-kit | view, edit |
billing | view, edit, export |
recycle-bin | view, edit, delete |
audit-log, playback-log (Proof of Play) | view, export |
org-unit, user, permission-group (Roles), tag, alert-rule | view, create, edit, delete |
api-key | view, create, delete |
integration | view, create, edit, delete |
data-source | delete |
settings | view, edit |
quick-post | view, create, approve, publish |
emergency-override | view, create, edit, approve, publish |
import | create |
Verb meanings: cast puts content on a screen. publish means publish without approval. share means share to other locations.
Common sets:
| Integration | Permissions |
|---|---|
| Read-only dashboard or AI assistant | screen.view, playlist.view, schedule.view, media.view, playback-log.view |
| Menu or price sync | media.view, media.create, media.edit, playlist.view, playlist.edit |
| Timed takeovers | screen.view, screen.cast, plus .view on the content you cast |
| Webhook management | integration.view, integration.edit |
Keys pinned to a location
A key with a location (nodeId) sees and changes only that location and the locations under it. Anything outside returns 404, not 403. GET /v1/me shows the pin in actor.nodeId. An empty list or an unexpected 404 from a pinned key usually means the resource is outside its branch.
Tenancy
Every request resolves to one workspace. A resource that belongs to another workspace returns 404, never 403, so a response never confirms that something exists elsewhere.
OAuth client credentials
For tools that expect OAuth, exchange a key for a short-lived access token. The client id is the key’s id (ak_..., from the key list), and the client secret is the key itself.
curl -X POST https://api.brixsignage.com/v1/oauth/token \
-u "$BRIX_KEY_ID:$BRIX_API_KEY" \
-d grant_type=client_credentials
{ "access_token": "bat_...", "token_type": "Bearer", "expires_in": 3600, "scope": "..." }
- Send
access_tokenasAuthorization: Bearer bat_.... It lasts 3600 seconds. - The token carries the key’s permissions. Revoking or rotating the key ends the token.
- Credentials can go in HTTP Basic (
client_secret_basic) or in the form body (client_secret_post). - Only the
client_credentialsgrant exists. There is no authorization-code flow and no consent screen. - The token endpoint allows 30 requests per 5 minutes per IP address.
- Discovery:
GET https://api.brixsignage.com/.well-known/oauth-authorization-server.