Audit API
Audit endpoints in the Brix REST API for digital signage: 5 operations (GET, POST). Each lists its path, auth, required permission and a curl example.
Base URL https://api.brixsignage.com. Send Authorization: Bearer $BRIX_API_KEY unless an operation says No auth. The permission chip names what the key must hold. See Authentication and scopes, Errors and rate limits and Pagination.
GET /v1/auditPOST /v1/auditGET /v1/audit/exportGET /v1/audit/integrityPOST /v1/audit/integrity/verify
GET/v1/audit
Returns the workspace's append-only activity log, newest first, with each event's actor shown by name rather than raw id, whether the actor was a person, an API key, or the system. Page with limit and cursor; nextCursor sits beside data. There are no filters: use the export for a time window. A caller limited to some locations sees only the events at those locations.
**Notes.**
- Newest first. There are no filters: page with cursor.
- A caller limited to some locations sees only events at those locations, so a page can hold fewer than limit events while nextCursor is still set.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | no | Page size (default 200, max 500). |
cursor | query | string | no | `nextCursor` of the previous page. |
curl "https://api.brixsignage.com/v1/audit" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200 Success.
| Field | Type | Description |
|---|---|---|
data | array of AuditEvent | |
data[].id | string | |
data[].at | string | ISO-8601 timestamp (UTC). |
data[].workspaceId | string | |
data[].actor | string | `user:<id>`, `apikey:<id>`, `system`, or another internal actor. |
data[].actorKind | "user" | "api-key" | "system" | |
data[].actorName | string | The person's or key's name; `System` for the system. |
data[].actorEmail | string | The person's email; `n/a` for a key; `system@brix` for the system. |
data[].action | string | What happened, e.g. `screen.renamed`. |
data[].target | string | null | The id of the thing acted on. |
data[].detail | string | null | |
data[].nodeId | string | null | The location the event belongs to; null for the workspace. |
data[].nodeName | string | null | |
data[].ipAddress | string | null | |
data[].userAgent | string | null | |
data[].via | "mcp" | "api" | null | How it arrived: `mcp` (an MCP tool such as Claude or ChatGPT), `api` (an API key on REST), null (in the Brix app). |
data[].viaApp | string | null | The connector or API key behind an `mcp`/`api` event; null for the app. |
nextCursor | string | null | Pass as `cursor` for the next (older) page; null on the last page. |
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/audit
Appends one client event to the workspace's activity log, for example that a help panel was opened. The action must be in the cms. namespace, so only events of that kind can be added this way. The actor is always the caller, never taken from the request body. The activity log is append-only: events can be added but never updated or deleted. Limited to 120 events a minute.
**Notes.**
- Needs only audit-log.view. The actor is always the caller; ipAddress and userAgent come from the request.
Request body application/json
| Field | Type | Required | Description |
|---|---|---|---|
action | string | yes | Must be in the `cms.` namespace: `cms.` then lower-case letters, digits, `.`, `_` or `-` (up to 122 more characters). |
target | string | no | |
detail | string | no | |
nodeId | string | null | no | A location you can see. |
curl -X POST "https://api.brixsignage.com/v1/audit" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 201 Success.
| Field | Type | Description |
|---|---|---|
data | AuditEvent | One activity log event, with the actor resolved to a name. |
data.id | string | |
data.at | string | ISO-8601 timestamp (UTC). |
data.workspaceId | string | |
data.actor | string | `user:<id>`, `apikey:<id>`, `system`, or another internal actor. |
data.actorKind | "user" | "api-key" | "system" | |
data.actorName | string | The person's or key's name; `System` for the system. |
data.actorEmail | string | The person's email; `n/a` for a key; `system@brix` for the system. |
data.action | string | What happened, e.g. `screen.renamed`. |
data.target | string | null | The id of the thing acted on. |
data.detail | string | null | |
data.nodeId | string | null | The location the event belongs to; null for the workspace. |
data.nodeName | string | null | |
data.ipAddress | string | null | |
data.userAgent | string | null | |
data.via | "mcp" | "api" | null | How it arrived: `mcp` (an MCP tool such as Claude or ChatGPT), `api` (an API key on REST), null (in the Brix app). |
data.viaApp | string | null | The connector or API key behind an `mcp`/`api` event; null for the app. |
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 422 `action` is missing or outside the `cms.` namespace, or `nodeId` is not a location you can see.
| 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 429 More than 120 events a minute.
| 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/audit/export
Returns the activity log as a feed suitable for a log collector or SIEM tool. Unlike the regular activity log listing, results are returned oldest first, so a collector can page forward from a saved position without missing or re-reading events. Returns newline-delimited JSON by default; pass ?format=json for a human-readable array. Use the from and to parameters for a half-open time window, and the x-brix-next-cursor and x-brix-has-more response headers to page through results.
**Notes.**
- Oldest first. The default body is NDJSON: one AuditEvent object per line. The next-page cursor is in the X-Brix-Next-Cursor header (empty on the last page) and X-Brix-Has-More is 1 or 0.
- With format=json the body is JSON: { data: AuditEvent[], nextCursor: string | null }.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | no | Page size (default 500, max 1000). |
cursor | query | string | no | The `X-Brix-Next-Cursor` header (or `nextCursor`) of the previous page. |
from | query | string | no | ISO-8601; events at or after this time. |
to | query | string | no | ISO-8601; events before this time. |
format | query | "json" | no | `json` answers `{ data: AuditEvent[], nextCursor }` instead of NDJSON. |
curl "https://api.brixsignage.com/v1/audit/export" \
-H "Authorization: Bearer $BRIX_API_KEY" 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 422 `from` or `to` is not an ISO-8601 timestamp.
| 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/audit/integrity
Returns the tamper-evidence chain for the workspace's activity log: a digest to record for later comparison, and the daily checkpoints behind it. Each complete UTC day of events is combined into one checkpoint linked to the day before. The current, still-open day is deliberately not yet included, since a checkpoint over data still being written would have to be recalculated.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
limit | query | integer | no | Checkpoints to return, newest first (default 90, max 400). |
curl "https://api.brixsignage.com/v1/audit/integrity" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200 Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.latestDigest | string | null | The value to record. Null before the first day is covered. |
data.coveredThrough | string | null | The end of the last covered day. |
data.canonicalVersion | string | The newest row encoding the hashes use. Each row's hashed form starts with its own version: `1` for a row with no `via`, `2` for a row with one (the version-1 fields, then `via` last). |
data.note | string | |
data.checkpoints | array of object | |
data.checkpoints[].seq | integer | |
data.checkpoints[].periodStart | string | ISO-8601 timestamp (UTC). |
data.checkpoints[].periodEnd | string | ISO-8601 timestamp (UTC). |
data.checkpoints[].rowCount | integer | |
data.checkpoints[].firstEventId | string | null | |
data.checkpoints[].lastEventId | string | null | |
data.checkpoints[].merkleRoot | string | |
data.checkpoints[].prevDigest | string | The previous checkpoint's digest, or `genesis`. |
data.checkpoints[].digest | string |
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/audit/integrity/verify
Re-reads every event behind the integrity chain and recomputes it, to prove the activity log has not been altered since a digest was recorded. Returns HTTP 200 with ok: false when verification fails, rather than an error status, so a monitoring script can distinguish "the log was altered" from "the check itself failed". This is rate-limited because it re-reads the full log.
**Notes.**
- Answers 200 with ok: false when verification fails.
Request body application/json
| Field | Type | Required | Description |
|---|---|---|---|
limit | integer | no | Checkpoints to check, newest first (default 90). |
curl -X POST "https://api.brixsignage.com/v1/audit/integrity/verify" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 200 Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.checkpoints | array of object | |
data.checkpoints[].id | string | |
data.checkpoints[].seq | integer | |
data.checkpoints[].periodStart | string | ISO-8601 timestamp (UTC). |
data.checkpoints[].periodEnd | string | ISO-8601 timestamp (UTC). |
data.checkpoints[].storedRowCount | integer | |
data.checkpoints[].actualRowCount | integer | |
data.checkpoints[].recomputedRoot | string | null | |
data.checkpoints[].rootMatches | boolean | |
data.checkpoints[].digestMatches | boolean | |
data.checkpoints[].chainIntact | boolean | |
data.checkpoints[].ok | boolean | |
data.ok | boolean | False when any checkpoint failed: the log was changed. |
data.latestDigest | string | null |
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 429 More than 10 checks in 5 minutes.
| 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. |