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.

View as Markdown

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

  1. Sign in to the CMS at cms.brixsignage.com.
  2. Open Settings > API & MCP.
  3. Select New key.
  4. Type a name into Name, for example Quickstart.
  5. Under Permissions, select Screens and Playlists. Leave Limit to a location empty.
  6. Select Create key.
  7. 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.

FieldValues
contentKindmedia, playlist, app, creative, schedule
contentIdThe id of that content.
scopeKindscreens (with screenIds), node (with scopeNodeId, a location and everything under it), or all. Default all.
expiresAtISO 8601 date-time or epoch milliseconds. Omit it and the cast stays until you clear it.
contentNameOptional 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