Brix Audit API

The audit API from Brix — 4 operation(s) for audit.

Operations 5

GET /v1/audit List activity log events #
POST /v1/audit Add activity log event #
GET /v1/audit/export Export activity log feed #
GET /v1/audit/integrity Get activity log integrity chain #
POST /v1/audit/integrity/verify Verify activity log integrity #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/brixsignage-com:brixsignage-com-audit-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

brixsignage-com-audit-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Brix Audit API
  version: '1'
  summary: 'Control plane for Brix digital signage: screens, content, playlists, schedules, casts and emergencies.'
  description: 'Generated from the route table the API actually mounts

    (`apps/api/routes.snapshot.json`), the description each route is required to

    carry (`tests/contracts/route-registry.json`), and request/response schemas

    (`apps/api/src/openapi/`). CI enforces all three, so this document cannot list a

    route that does not exist or omit one that does.


    **Schemas.** 447 operations carry request and response schemas

    (`x-brix-schema: verified`). Each is checked in CI against the response the

    real handler returns — a missing, mistyped or undeclared field fails the build.

    The remaining operations are route-level only (`x-brix-schema: none`): their

    path, method, permission and purpose are exact, but the shape of `data` is not

    yet modelled, and we would rather say so than publish a schema that validates

    against nothing. Objects are open: a new field is not a breaking change.


    **Envelope.** Success bodies are `{ "data": … }`. Failures are

    `{ "error": "", "message": "…" }`, plus `requestId` on a 5xx.

    Many list routes page opt-in (see each operation): pass `?limit=` and

    follow `nextCursor` via `?cursor=` until it is null.


    **Authentication.** `Authorization: Bearer ` with an API key

    (`ak_…`, created in the console under Settings → API & MCP) or a user session. An

    API key carries a creator-chosen set of `resource.verb` permissions and may be

    pinned to one location''s subtree; a key can never be granted a permission its

    creator does not hold. The permission an operation needs is in

    `x-brix-permission` and in its security requirement.


    **Tenancy.** Every request resolves to one workspace. A resource belonging to

    another tenant returns 404, never 403, so a response never confirms that an

    account exists.


    **Rate limits.** A 429 carries `Retry-After`; a 503 `database_busy` means retry

    after the `Retry-After` interval.'
servers:
- url: https://api.brixsignage.com
  description: Production
security:
- bearerAuth: []
tags:
- name: Audit
paths:
  /v1/audit:
    get:
      operationId: getAudit
      tags:
      - Audit
      summary: List activity log events
      description: '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.'
      x-brix-permission: audit-log.view
      x-brix-schema: verified
      x-brix-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.
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
        description: Page size (default 200, max 500).
      - name: cursor
        in: query
        required: false
        schema:
          type: string
        description: '`nextCursor` of the previous page.'
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/AuditEvent'
                  nextCursor:
                    anyOf:
                    - type: string
                    - type: 'null'
                    description: Pass as `cursor` for the next (older) page; null on the last page.
                required:
                - data
                - nextCursor
        '401':
          description: Missing, expired or revoked bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The token lacks the permission this operation needs (see `x-brix-permission`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        5XX:
          description: Server error. The body carries a `requestId` to quote to support.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth:
        - audit-log.view
    post:
      operationId: createAudit
      tags:
      - Audit
      summary: Add activity log event
      description: '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.'
      x-brix-permission: audit-log.view
      x-brix-schema: verified
      x-brix-notes:
      - Needs only `audit-log.view`. The actor is always the caller; `ipAddress` and `userAgent` come from the request.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                action:
                  type: string
                  description: 'Must be in the `cms.` namespace: `cms.` then lower-case letters, digits, `.`, `_` or `-` (up to 122 more characters).'
                target:
                  type: string
                detail:
                  type: string
                nodeId:
                  description: A location you can see.
                  anyOf:
                  - type: string
                  - type: 'null'
              required:
              - action
      responses:
        '201':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    $ref: '#/components/schemas/AuditEvent'
                required:
                - data
        '401':
          description: Missing, expired or revoked bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The token lacks the permission this operation needs (see `x-brix-permission`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: '`action` is missing or outside the `cms.` namespace, or `nodeId` is not a location you can see.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: More than 120 events a minute.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        5XX:
          description: Server error. The body carries a `requestId` to quote to support.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth:
        - audit-log.view
  /v1/audit/export:
    get:
      operationId: exportAudit
      tags:
      - Audit
      summary: Export activity log feed
      description: '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 }`.'
      x-brix-permission: audit-log.view
      x-brix-schema: verified
      x-brix-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 }`.'
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
        description: Page size (default 500, max 1000).
      - name: cursor
        in: query
        required: false
        schema:
          type: string
        description: The `X-Brix-Next-Cursor` header (or `nextCursor`) of the previous page.
      - name: from
        in: query
        required: false
        schema:
          type: string
        description: ISO-8601; events at or after this time.
      - name: to
        in: query
        required: false
        schema:
          type: string
        description: ISO-8601; events before this time.
      - name: format
        in: query
        required: false
        schema:
          type: string
          enum:
          - json
        description: '`json` answers `{ data: AuditEvent[], nextCursor }` instead of NDJSON.'
      responses:
        '200':
          description: Success. The body is the file itself.
          content:
            application/x-ndjson:
              schema:
                type: string
                format: binary
        '401':
          description: Missing, expired or revoked bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The token lacks the permission this operation needs (see `x-brix-permission`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '422':
          description: '`from` or `to` is not an ISO-8601 timestamp.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        5XX:
          description: Server error. The body carries a `requestId` to quote to support.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth:
        - audit-log.view
  /v1/audit/integrity:
    get:
      operationId: getAuditIntegrity
      tags:
      - Audit
      summary: Get activity log integrity chain
      description: '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.'
      x-brix-permission: audit-log.view
      x-brix-schema: verified
      parameters:
      - name: limit
        in: query
        required: false
        schema:
          type: integer
          minimum: 1
          maximum: 400
        description: Checkpoints to return, newest first (default 90, max 400).
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      latestDigest:
                        anyOf:
                        - type: string
                        - type: 'null'
                        description: The value to record. Null before the first day is covered.
                      coveredThrough:
                        anyOf:
                        - type: string
                          description: ISO-8601 timestamp (UTC).
                        - type: 'null'
                        description: The end of the last covered day.
                      canonicalVersion:
                        type: string
                        description: The newest row encoding the hashes use (`3`). Each checkpoint names its own in `leafVersion`.
                      note:
                        type: string
                      checkpoints:
                        type: array
                        items:
                          type: object
                          properties:
                            seq:
                              type: integer
                            periodStart:
                              type: string
                              description: ISO-8601 timestamp (UTC).
                            periodEnd:
                              type: string
                              description: ISO-8601 timestamp (UTC).
                            rowCount:
                              type: integer
                            firstEventId:
                              anyOf:
                              - type: string
                              - type: 'null'
                            lastEventId:
                              anyOf:
                              - type: string
                              - type: 'null'
                            merkleRoot:
                              type: string
                            leafVersion:
                              anyOf:
                              - type: string
                              - type: 'null'
                              description: 'The row encoding this checkpoint''s root was taken over. `3`: every field escaped (backslash as `\\`, U+001F as `\u`) and joined on U+001F, `via` last. Null: a checkpoint written before version 3, whose rows are joined unescaped, each starting with its own version (`1` with no `via`, `2` with `via` last).'
                            prevDigest:
                              type: string
                              description: The previous checkpoint's digest, or `genesis`.
                            digest:
                              type: string
                          required:
                          - seq
                          - periodStart
                          - periodEnd
                          - rowCount
                          - firstEventId
                          - lastEventId
                          - merkleRoot
                          - leafVersion
                          - prevDigest
                          - digest
                    required:
                    - latestDigest
                    - coveredThrough
                    - canonicalVersion
                    - note
                    - checkpoints
                required:
                - data
        '401':
          description: Missing, expired or revoked bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The token lacks the permission this operation needs (see `x-brix-permission`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        5XX:
          description: Server error. The body carries a `requestId` to quote to support.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth:
        - audit-log.view
  /v1/audit/integrity/verify:
    post:
      operationId: verifyAuditIntegrity
      tags:
      - Audit
      summary: Verify activity log integrity
      description: '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.'
      x-brix-permission: audit-log.view
      x-brix-schema: verified
      x-brix-notes:
      - 'Answers 200 with `ok: false` when verification fails.'
      requestBody:
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                limit:
                  description: Checkpoints to check, newest first (default 90).
                  type: integer
      responses:
        '200':
          description: Success.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      checkpoints:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: string
                            seq:
                              type: integer
                            periodStart:
                              type: string
                              description: ISO-8601 timestamp (UTC).
                            periodEnd:
                              type: string
                              description: ISO-8601 timestamp (UTC).
                            storedRowCount:
                              type: integer
                            actualRowCount:
                              type: integer
                            recomputedRoot:
                              anyOf:
                              - type: string
                              - type: 'null'
                            rootMatches:
                              type: boolean
                            digestMatches:
                              type: boolean
                            chainIntact:
                              type: boolean
                            ok:
                              type: boolean
                          required:
                          - id
                          - seq
                          - periodStart
                          - periodEnd
                          - storedRowCount
                          - actualRowCount
                          - recomputedRoot
                          - rootMatches
                          - digestMatches
                          - chainIntact
                          - ok
                      ok:
                        type: boolean
                        description: 'False when any checkpoint failed: the log was changed.'
                      latestDigest:
                        anyOf:
                        - type: string
                        - type: 'null'
                    required:
                    - checkpoints
                    - ok
                    - latestDigest
                required:
                - data
        '401':
          description: Missing, expired or revoked bearer token.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '403':
          description: The token lacks the permission this operation needs (see `x-brix-permission`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        '429':
          description: More than 10 checks in 5 minutes.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
        5XX:
          description: Server error. The body carries a `requestId` to quote to support.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Error'
      security:
      - bearerAuth:
        - audit-log.view
components:
  schemas:
    AuditEvent:
      type: object
      properties:
        id:
          type: string
        at:
          type: string
          description: ISO-8601 timestamp (UTC).
        workspaceId:
          type: string
        actor:
          type: string
          description: '`user:<id>`, `apikey:<id>`, `system`, `staff` (our support team), or another internal actor.'
        actorKind:
          type: string
          enum:
          - user
          - api-key
          - system
          - brix-support
          - support
          description: 'Our support team made the change: `support` in a workspace a white-label partner owns, `brix-support` otherwise.'
        actorName:
          type: string
          description: The person's or key's name; `System` for the system; the support team's name for `support` / `brix-support`.
        actorEmail:
          type: string
          description: The person's email; `n/a` for a key; `system@brix` for the system (`system` in a white-label partner's workspace); empty for `support` / `brix-support`.
        action:
          type: string
          description: What happened, e.g. `screen.renamed`.
        target:
          anyOf:
          - type: string
          - type: 'null'
          description: The id of the thing acted on.
        detail:
          anyOf:
          - type: string
          - type: 'null'
        nodeId:
          anyOf:
          - type: string
          - type: 'null'
          description: The location the event belongs to; null for the workspace.
        nodeName:
          anyOf:
          - type: string
          - type: 'null'
        ipAddress:
          anyOf:
          - type: string
          - type: 'null'
        userAgent:
          anyOf:
          - type: string
          - type: 'null'
        via:
          anyOf:
          - type: string
            enum:
            - mcp
            - api
          - type: 'null'
          description: 'How it arrived: `mcp` (an MCP tool such as Claude or ChatGPT), `api` (an API key on REST), null (in the Brix app).'
        viaApp:
          anyOf:
          - type: string
          - type: 'null'
          description: The connector or API key behind an `mcp`/`api` event; null for the app.
      required:
      - id
      - at
      - workspaceId
      - actor
      - actorKind
      - actorName
      - actorEmail
      - action
      - target
      - detail
      - nodeId
      - nodeName
      - ipAddress
      - userAgent
      - via
      - viaApp
      description: One activity log event, with the actor resolved to a name.
    Error:
      type: object
      properties:
        error:
          type: string
          description: 'Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, …'
        message:
          description: Human-readable explanation. Safe to show an operator.
          type: string
        requestId:
          description: 'Present on 5xx: quote it to support.'
          type: string
      required:
      - error
      additionalProperties: {}
      description: Error envelope returned by every failing request.
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: An API key (`ak_…`) or a user session token. API keys carry `resource.verb` permissions.