# Emergencies

Base URL: `https://api.brixsignage.com`. Send `Authorization: Bearer $BRIX_API_KEY` unless an operation says Auth: none.

## GET /v1/emergencies

List emergency overrides, newest first. Use `?status=active` to filter to overrides currently taking over screens.

Auth: Bearer token. Permission: `emergency-override.view`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `status` | query | "active" \| "cleared" \| "expired" | no | Only overrides in this state. |
| `limit` | query | integer | no | At most this many, newest first (default 200, max 500). |

```bash
curl "https://api.brixsignage.com/v1/emergencies" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of Override |  |
| `data[].id` | string | Override (cast_… or emg_…) id. |
| `data[].spaceId` | string | Workspace id. |
| `data[].kind` | "emergency" \| "cast" |  |
| `data[].status` | "active" \| "cleared" \| "expired" |  |
| `data[].severity` | "info" \| "warning" \| "critical" | Always `info` for a cast. |
| `data[].headline` | string | An emergency's message; for a cast, the content's name (or "Cast"). |
| `data[].body` | string \| null |  |
| `data[].contentKind` | "media" \| "creative" \| "playlist" \| "app" \| "schedule" \| null |  |
| `data[].contentId` | string \| null |  |
| `data[].scopeKind` | "all" \| "node" \| "screens" |  |
| `data[].scopeNodeId` | string \| null | The location, when `scopeKind` is `node`. |
| `data[].nodeId` | string \| null | Location the override is attributed to (null = workspace root). |
| `data[].screenCount` | integer | Screens targeted, snapshotted when it started. |
| `data[].triggeredBy` | string | User id, or `system`. |
| `data[].triggeredAt` | string | ISO-8601 timestamp (UTC). |
| `data[].expiresAt` | string \| null | Auto-clear time; null = until cleared. |
| `data[].clearedBy` | string \| null |  |
| `data[].clearedAt` | string \| null |  |
| `data[].triggeredByName` | string | Display name of `triggeredBy`. |
| `data[].clearedByName` | string \| null |  |
| `data[].scopeName` | string \| null | Location name, `All screens`, or null for a screen list. |
| `data[].confirmedCount` | integer \| null | Active emergencies only: screens confirmed showing it now. Null otherwise. |

```json
{
  "data": [
    {
      "id": "emg_4d5e6f7a8b9c0d1e",
      "spaceId": "space_1a2b3c4d5e6f7a8b",
      "kind": "emergency",
      "status": "active",
      "severity": "critical",
      "headline": "Evacuate the building now",
      "body": "Use the nearest exit. Do not use the lifts.",
      "contentKind": null,
      "contentId": null,
      "scopeKind": "all",
      "scopeNodeId": null,
      "nodeId": null,
      "screenCount": 42,
      "triggeredBy": "usr_5e6f7a8b9c0d1e2f",
      "triggeredAt": "2026-09-28T11:30:00.000Z",
      "expiresAt": null,
      "clearedBy": null,
      "clearedAt": null,
      "triggeredByName": "Sam Rivera",
      "clearedByName": null,
      "scopeName": "All screens",
      "confirmedCount": 0
    }
  ]
}
```

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 403: The token lacks the permission this operation needs (see `x-brix-permission`).

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 5XX: Server error. The body carries a `requestId` to quote to support.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

## POST /v1/emergencies

Trigger an emergency takeover across a set of screens. An emergency takes the highest priority and layers over each screen's normal content, so clearing it restores exactly what was playing before.

Takes over the chosen screens now, above every schedule and cast, until cleared or expired. Clearing restores exactly what was playing.

**Notes.**
- The route is gated by `emergency-override.create`; the route registry's description names `emergency-override.trigger`, which is not a permission the API checks.

Auth: Bearer token. Permission: `emergency-override.create`.

Request body (`application/json`):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `headline` | string | yes | The message on every targeted screen. Required, non-blank. |
| `body` | string | no | Optional second line. |
| `severity` | "info" \| "warning" \| "critical" | no | Default `critical`. |
| `contentKind` | "media" \| "creative" | no | Attach content to show under the banner. Needs `contentId`. |
| `contentId` | string | no | The media or creative id. Needs `contentKind`. |
| `scopeKind` | "all" \| "node" \| "screens" | no | Which screens: every screen you can reach (`all`), one location's subtree (`node`), or a list (`screens`). **Defaults to `all`: omit it and the emergency goes to EVERY screen you can reach.** |
| `scopeNodeId` | string | no | Location id, with `scopeKind: node`. |
| `screenIds` | array of string | no | Screen ids, with `scopeKind: screens`. |
| `expiresAt` | string \| number \| null | no | When it clears by itself: ISO-8601 or epoch milliseconds. Omit or null to run until cleared. |

```bash
curl -X POST "https://api.brixsignage.com/v1/emergencies" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"headline":"Evacuate the building now","body":"Use the nearest exit. Do not use the lifts.","severity":"critical","scopeKind":"all"}'
```

Response 201: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | Override | A cast or an emergency override. |
| `data.id` | string | Override (cast_… or emg_…) id. |
| `data.spaceId` | string | Workspace id. |
| `data.kind` | "emergency" \| "cast" |  |
| `data.status` | "active" \| "cleared" \| "expired" |  |
| `data.severity` | "info" \| "warning" \| "critical" | Always `info` for a cast. |
| `data.headline` | string | An emergency's message; for a cast, the content's name (or "Cast"). |
| `data.body` | string \| null |  |
| `data.contentKind` | "media" \| "creative" \| "playlist" \| "app" \| "schedule" \| null |  |
| `data.contentId` | string \| null |  |
| `data.scopeKind` | "all" \| "node" \| "screens" |  |
| `data.scopeNodeId` | string \| null | The location, when `scopeKind` is `node`. |
| `data.nodeId` | string \| null | Location the override is attributed to (null = workspace root). |
| `data.screenCount` | integer | Screens targeted, snapshotted when it started. |
| `data.triggeredBy` | string | User id, or `system`. |
| `data.triggeredAt` | string | ISO-8601 timestamp (UTC). |
| `data.expiresAt` | string \| null | Auto-clear time; null = until cleared. |
| `data.clearedBy` | string \| null |  |
| `data.clearedAt` | string \| null |  |
| `data.triggeredByName` | string | Display name of `triggeredBy`. |
| `data.clearedByName` | string \| null |  |
| `data.scopeName` | string \| null | Location name, `All screens`, or null for a screen list. |
| `data.confirmedCount` | integer \| null | Active emergencies only: screens confirmed showing it now. Null otherwise. |

```json
{
  "data": {
    "id": "emg_4d5e6f7a8b9c0d1e",
    "spaceId": "space_1a2b3c4d5e6f7a8b",
    "kind": "emergency",
    "status": "active",
    "severity": "critical",
    "headline": "Evacuate the building now",
    "body": "Use the nearest exit. Do not use the lifts.",
    "contentKind": null,
    "contentId": null,
    "scopeKind": "all",
    "scopeNodeId": null,
    "nodeId": null,
    "screenCount": 42,
    "triggeredBy": "usr_5e6f7a8b9c0d1e2f",
    "triggeredAt": "2026-09-28T11:30:00.000Z",
    "expiresAt": null,
    "clearedBy": null,
    "clearedAt": null,
    "triggeredByName": "Sam Rivera",
    "clearedByName": null,
    "scopeName": "All screens",
    "confirmedCount": 0
  }
}
```

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 403: `not_shared`: the content is not shared to one or more target locations.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 404: The content does not exist in this workspace.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 422: Missing headline, a half content pointer, a bad `expiresAt`, no reachable screens (`no_screens`), or content that cannot play (`content_unplayable`).

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 5XX: Server error. The body carries a `requestId` to quote to support.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

## GET /v1/emergencies/{id}

Get an emergency override

Retrieve one emergency override, including its scope, content, and expiry.

Auth: Bearer token. Permission: `emergency-override.view`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Emergency id. |

```bash
curl "https://api.brixsignage.com/v1/emergencies/{id}" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | Override | A cast or an emergency override. |
| `data.id` | string | Override (cast_… or emg_…) id. |
| `data.spaceId` | string | Workspace id. |
| `data.kind` | "emergency" \| "cast" |  |
| `data.status` | "active" \| "cleared" \| "expired" |  |
| `data.severity` | "info" \| "warning" \| "critical" | Always `info` for a cast. |
| `data.headline` | string | An emergency's message; for a cast, the content's name (or "Cast"). |
| `data.body` | string \| null |  |
| `data.contentKind` | "media" \| "creative" \| "playlist" \| "app" \| "schedule" \| null |  |
| `data.contentId` | string \| null |  |
| `data.scopeKind` | "all" \| "node" \| "screens" |  |
| `data.scopeNodeId` | string \| null | The location, when `scopeKind` is `node`. |
| `data.nodeId` | string \| null | Location the override is attributed to (null = workspace root). |
| `data.screenCount` | integer | Screens targeted, snapshotted when it started. |
| `data.triggeredBy` | string | User id, or `system`. |
| `data.triggeredAt` | string | ISO-8601 timestamp (UTC). |
| `data.expiresAt` | string \| null | Auto-clear time; null = until cleared. |
| `data.clearedBy` | string \| null |  |
| `data.clearedAt` | string \| null |  |
| `data.triggeredByName` | string | Display name of `triggeredBy`. |
| `data.clearedByName` | string \| null |  |
| `data.scopeName` | string \| null | Location name, `All screens`, or null for a screen list. |
| `data.confirmedCount` | integer \| null | Active emergencies only: screens confirmed showing it now. Null otherwise. |

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 403: The token lacks the permission this operation needs (see `x-brix-permission`).

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 404: No such emergency in this workspace (or outside your locations).

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 5XX: Server error. The body carries a `requestId` to quote to support.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

## POST /v1/emergencies/{id}/clear

Clear an emergency override

Clear an active emergency override. This releases its screens back to their normal content, and the action is recorded in the activity log.

Auth: Bearer token. Permission: `emergency-override.create`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Emergency id. |

```bash
curl -X POST "https://api.brixsignage.com/v1/emergencies/{id}/clear" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | Override | A cast or an emergency override. |
| `data.id` | string | Override (cast_… or emg_…) id. |
| `data.spaceId` | string | Workspace id. |
| `data.kind` | "emergency" \| "cast" |  |
| `data.status` | "active" \| "cleared" \| "expired" |  |
| `data.severity` | "info" \| "warning" \| "critical" | Always `info` for a cast. |
| `data.headline` | string | An emergency's message; for a cast, the content's name (or "Cast"). |
| `data.body` | string \| null |  |
| `data.contentKind` | "media" \| "creative" \| "playlist" \| "app" \| "schedule" \| null |  |
| `data.contentId` | string \| null |  |
| `data.scopeKind` | "all" \| "node" \| "screens" |  |
| `data.scopeNodeId` | string \| null | The location, when `scopeKind` is `node`. |
| `data.nodeId` | string \| null | Location the override is attributed to (null = workspace root). |
| `data.screenCount` | integer | Screens targeted, snapshotted when it started. |
| `data.triggeredBy` | string | User id, or `system`. |
| `data.triggeredAt` | string | ISO-8601 timestamp (UTC). |
| `data.expiresAt` | string \| null | Auto-clear time; null = until cleared. |
| `data.clearedBy` | string \| null |  |
| `data.clearedAt` | string \| null |  |
| `data.triggeredByName` | string | Display name of `triggeredBy`. |
| `data.clearedByName` | string \| null |  |
| `data.scopeName` | string \| null | Location name, `All screens`, or null for a screen list. |
| `data.confirmedCount` | integer \| null | Active emergencies only: screens confirmed showing it now. Null otherwise. |

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 403: The token lacks the permission this operation needs (see `x-brix-permission`).

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 404: No such emergency in this workspace.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 409: `already_inactive`: already cleared or expired.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 5XX: Server error. The body carries a `requestId` to quote to support.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

## POST /v1/emergencies/from-template/{templateId}

Trigger an emergency from a template

Trigger an emergency using a stored template. Any scope or expiry sent with the request overrides the template's defaults.

Fires a stored template. Scope and expiry given here override the template's defaults. Send `{}` to use the template as stored.

Auth: Bearer token. Permission: `emergency-override.create`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `templateId` | path | string | yes | Emergency template id. |

Request body (`application/json`):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `scopeKind` | "all" \| "node" \| "screens" | no | Which screens: every screen you can reach (`all`), one location's subtree (`node`), or a list (`screens`). **Defaults to `all`: omit it and the emergency goes to EVERY screen you can reach.** |
| `scopeNodeId` | string | no | Location id, with `scopeKind: node`. |
| `screenIds` | array of string | no | Screen ids, with `scopeKind: screens`. |
| `expiresAt` | string \| number \| null | no | When it clears by itself: ISO-8601 or epoch milliseconds. Omit or null to run until cleared. |

```bash
curl -X POST "https://api.brixsignage.com/v1/emergencies/from-template/{templateId}" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 201: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | Override | A cast or an emergency override. |
| `data.id` | string | Override (cast_… or emg_…) id. |
| `data.spaceId` | string | Workspace id. |
| `data.kind` | "emergency" \| "cast" |  |
| `data.status` | "active" \| "cleared" \| "expired" |  |
| `data.severity` | "info" \| "warning" \| "critical" | Always `info` for a cast. |
| `data.headline` | string | An emergency's message; for a cast, the content's name (or "Cast"). |
| `data.body` | string \| null |  |
| `data.contentKind` | "media" \| "creative" \| "playlist" \| "app" \| "schedule" \| null |  |
| `data.contentId` | string \| null |  |
| `data.scopeKind` | "all" \| "node" \| "screens" |  |
| `data.scopeNodeId` | string \| null | The location, when `scopeKind` is `node`. |
| `data.nodeId` | string \| null | Location the override is attributed to (null = workspace root). |
| `data.screenCount` | integer | Screens targeted, snapshotted when it started. |
| `data.triggeredBy` | string | User id, or `system`. |
| `data.triggeredAt` | string | ISO-8601 timestamp (UTC). |
| `data.expiresAt` | string \| null | Auto-clear time; null = until cleared. |
| `data.clearedBy` | string \| null |  |
| `data.clearedAt` | string \| null |  |
| `data.triggeredByName` | string | Display name of `triggeredBy`. |
| `data.clearedByName` | string \| null |  |
| `data.scopeName` | string \| null | Location name, `All screens`, or null for a screen list. |
| `data.confirmedCount` | integer \| null | Active emergencies only: screens confirmed showing it now. Null otherwise. |

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 403: `not_shared`: the template's content is not shared to one or more target locations.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 404: No such template, or its content is gone.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 422: Bad `expiresAt`, no reachable screens (`no_screens`), or content that cannot play.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 5XX: Server error. The body carries a `requestId` to quote to support.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |
