Quickstart
Create a Brix API key, make your first request with curl, list your screens and cast a playlist to a screen for an hour. Copy-paste commands.
This page takes you from nothing to content on a screen. You need a Brix workspace with at least one paired screen, and curl. Every command runs against the live API.
1. Create an API key
- Sign in to the CMS at cms.brixsignage.com.
- Open Settings > API & MCP.
- Select New key.
- Type a name into Name, for example
Quickstart. - Under Permissions, select Screens and Playlists. Leave Limit to a location empty.
- Select Create key.
- Copy the key from the panel. Brix shows the full key once.
A key looks like ak_us_live_ followed by 32 characters. The second part is your workspace’s data region: us, eu, oc or apac.
You need the api-key.create permission to make a key. Workspace Owners and Admins have it. A key never gets a permission that the person who creates it does not hold.
Store the key in an environment variable:
export BRIX_API_KEY="ak_us_live_..."
2. Check who you are
curl https://api.brixsignage.com/v1/me \
-H "Authorization: Bearer $BRIX_API_KEY"
{
"data": {
"actor": { "kind": "key", "id": "ak_...", "name": "Quickstart", "nodeId": null },
"workspace": { "id": "...", "name": "Acme Coffee" },
"permissions": ["screen.view", "screen.cast", "playlist.view", "..."]
}
}
permissions is what this key may do. If a later call returns 403 or an empty list, check this first.
A missing header returns 401 {"error":"missing_credentials",...}. A wrong, revoked or expired key returns 401 {"error":"invalid_credentials",...}.
3. List your screens
curl "https://api.brixsignage.com/v1/screens?limit=50" \
-H "Authorization: Bearer $BRIX_API_KEY"
{
"data": [
{ "id": "scr_...", "name": "Lobby", "status": "online", "contentKind": "playlist", "contentId": "pl_...", "lastSeenAt": "..." }
],
"nextCursor": null
}
The response is trimmed here. Copy the id of the screen you want to use. When nextCursor is not null, there are more screens: see Pagination.
With jq, print id, name and status:
curl -s "https://api.brixsignage.com/v1/screens?limit=500" \
-H "Authorization: Bearer $BRIX_API_KEY" | jq -r '.data[] | [.id, .name, .status] | @tsv'
4. Find a playlist
curl -s https://api.brixsignage.com/v1/playlists \
-H "Authorization: Bearer $BRIX_API_KEY" | jq -r '.data[] | [.id, .name] | @tsv'
Copy the id of a playlist.
5. Cast the playlist to the screen for one hour
A cast is a timed takeover. The screens play your content until expiresAt, then go back to their normal schedule by themselves.
SCREEN_ID="scr_..."
PLAYLIST_ID="pl_..."
EXPIRES_AT=$(( $(date +%s) * 1000 + 3600000 )) # one hour from now, epoch milliseconds
curl -X POST https://api.brixsignage.com/v1/casts \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"contentKind\": \"playlist\",
\"contentId\": \"$PLAYLIST_ID\",
\"scopeKind\": \"screens\",
\"screenIds\": [\"$SCREEN_ID\"],
\"expiresAt\": $EXPIRES_AT
}"
The API answers 201 with the cast:
{
"data": {
"id": "cast_...",
"kind": "cast",
"status": "active",
"contentKind": "playlist",
"contentId": "pl_...",
"scopeKind": "screens",
"screenCount": 1,
"triggeredAt": "...",
"expiresAt": "..."
}
}
Keep the cast id for the next step. With jq, run the same request with curl -s ... | jq -r .data.id and store it:
CAST_ID="cast_..." # data.id from the response above
Always send scopeKind. If you leave it out, the cast goes to every screen the key can reach.
| Field | Values |
|---|---|
contentKind | media, playlist, app, creative, schedule |
contentId | The id of that content. |
scopeKind | screens (with screenIds), node (with scopeNodeId, a location and everything under it), or all. Default all. |
expiresAt | ISO 8601 date-time or epoch milliseconds. Omit it and the cast stays until you clear it. |
contentName | Optional label shown in the CMS. |
The key needs screen.cast. A newer cast on the same screens replaces an older one. An emergency takeover pre-empts a cast, and the cast resumes after it.
6. End the cast early
curl -X POST https://api.brixsignage.com/v1/casts/$CAST_ID/clear \
-H "Authorization: Bearer $BRIX_API_KEY"
The screens go back to their scheduled content at once. Clearing a cast that already ended returns 409 already_inactive.
To see what is on air now:
curl "https://api.brixsignage.com/v1/casts?status=active" \
-H "Authorization: Bearer $BRIX_API_KEY"
Change what a screen plays by default
A cast is temporary. To change the content a screen plays every day, assign it:
curl -X POST https://api.brixsignage.com/v1/screens/$SCREEN_ID/assign \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" \
-d "{\"contentKind\": \"playlist\", \"contentId\": \"$PLAYLIST_ID\"}"
contentKind is one of playlist, schedule, layout, creative, signage, app, media. Send "contentKind": null to clear the assignment. For many screens at once, use POST /v1/screens/bulk-assign with screenIds.
Upload a file
curl -X POST https://api.brixsignage.com/v1/media/upload \
-H "Authorization: Bearer $BRIX_API_KEY" \
-F "[email protected]" \
-F "name=Winter menu"
The key needs media.create. The response is 201 with the new media item in data. Use its id as contentId with "contentKind": "media". For files over about 100 MB, use the multipart upload routes under /v1/media/upload/multipart/. To import from a public URL, use POST /v1/media/import-url. SVG files are refused.
Next
- Authentication and scopes for least-privilege keys.
- Errors and rate limits before you ship an integration.
- API reference for every endpoint.
- Connect an AI agent (MCP) to do all of this from Claude or ChatGPT.