Proof API
Proof endpoints in the Brix REST API: 10 operations (GET, POST, DELETE). Each lists its path, auth, required permission and a curl example.
View as Markdown · For AI agents: the full docs index is at /llms.txt
Base URL https://api.brixsignage.com. Send Authorization: Bearer $BRIX_API_KEY unless an operation says Auth: none or Auth: no API key. The Permission line names what the key must hold. See Authentication and scopes, Errors and rate limits and Pagination.
GET /v1/proofGET /v1/proof/advertisersGET /v1/proof/eventsGET /v1/proof/exportGET /v1/proof/keysPOST /v1/proof/keys/{keyId}/revokeGET /v1/proof/schedulesPOST /v1/proof/schedulesDELETE /v1/proof/schedules/{id}POST /v1/proof/verify-bundle
Every 4xx and 5xx response below returns this body:
| 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/proof
Get proof-of-play totals for a date range, broken down by content item and by screen, including digital-out-of-home verification fields. Use the from and to query parameters to set the date range.
Counts what played, where and for how long, over a time window. Only screens the caller can see are counted.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
from | query | string | no | Window start (ISO-8601). Default: the start of the retention window. |
to | query | string | no | Window end (ISO-8601). Default: now. |
screenId | query | string | no | Only this screen. |
screenIds | query | string | no | Only these screens: ids separated by commas. |
contentIds | query | string | no | Only this content: ids separated by commas. Totals count only this content. |
detail | query | "screens" | no | screens adds byScreen: one row per content and screen. |
curl "https://api.brixsignage.com/v1/proof" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | ProofOfPlayReport | |
data.totals | object | |
data.totals.plays | integer | Successful plays (neither skipped nor failed). |
data.totals.skipped | integer | |
data.totals.failed | integer | |
data.totals.events | integer | Every playback-end event: plays + skipped + failed. |
data.totals.uniqueContent | integer | |
data.totals.screensReporting | integer | |
data.byContent | array of object | Per content, most successful plays first. |
data.byContent[].contentId | string | unknown when the player did not report one. |
data.byContent[].contentName | string | Falls back to the id when no name was reported. |
data.byContent[].contentKind | string | media, app, creative, …; media for days read from the daily rollup. |
data.byContent[].screenName | string | null | Set only when exactly one screen played it. |
data.byContent[].played | integer | |
data.byContent[].skipped | integer | |
data.byContent[].failed | integer | |
data.byContent[].screenCount | integer | |
data.byContent[].totalDurationSec | integer | |
data.byContent[].firstAt | string | ISO-8601 timestamp (UTC). |
data.byContent[].lastAt | string | ISO-8601 timestamp (UTC). |
data.screens | array of object | Screens that reported in the window, by name. |
data.screens[].id | string | |
data.screens[].name | string | |
data.from | string | ISO-8601 timestamp (UTC). |
data.to | string | ISO-8601 timestamp (UTC). |
data.retentionDays | integer | How far back raw play events exist; older days come from the daily rollup. |
data.truncated | boolean | Always false: the whole window is counted. |
data.fromRollup | boolean | Part of the window was read from the daily rollup. |
data.byScreen | array of object | With detail=screens: one row per content and screen, by content name then screen name. |
data.byScreen[].contentId | string | |
data.byScreen[].contentName | string | |
data.byScreen[].screenId | string | |
data.byScreen[].screenName | string | The screen id when the screen no longer exists. |
data.byScreen[].played | integer | |
data.byScreen[].skipped | integer | |
data.byScreen[].failed | integer | |
data.byScreen[].totalDurationSec | integer | |
data.byScreen[].playedDurationSec | integer | The part of totalDurationSec from finished plays (not skipped or failed). A day whose daily total has no split counts its total. |
data.byScreen[].firstAt | string | ISO-8601 timestamp (UTC). |
data.byScreen[].lastAt | string | ISO-8601 timestamp (UTC). |
Response 401: Missing, expired or revoked bearer token.
Response 403: The token lacks the permission this operation needs (see x-brix-permission).
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/proof/advertisers
Get proof-of-play totals for a date range, one row per advertiser and venue. An advertiser is a tag on files and designs. A venue is the location that a screen is in; a screen with no location counts at the workspace. Content with two advertiser tags counts for each tag. Use advertisers or advertiser to filter, and format=csv to download a file. Only finished plays count in the played time.
An advertiser is a tag on files and designs. A venue is the location (org-tree node) a screen sits in; a screen with no location counts at the workspace. Content with two advertiser tags counts for each. With no advertisers filter, content with no tag is reported under an empty name. Only screens the caller can see are counted. format=csv returns a file with one row per advertiser and venue. Its finished_min and finished_sec columns and playedDurationSec count finished plays only; a skipped or failed play is not in them. For dates whose daily totals predate this change, they may include plays that did not finish.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
from | query | string | no | Window start (ISO-8601). Default: the start of the retention window. |
to | query | string | no | Window end (ISO-8601). Default: now. |
advertisers | query | string | no | Only these advertisers: tags separated by commas. Case does not matter. |
advertiser | query | string | no | Only this one advertiser (a tag). Use it to get one advertiser's CSV. |
screenIds | query | string | no | Only these screens: ids separated by commas. |
contentIds | query | string | no | Only this content: ids separated by commas. |
format | query | "json" | "csv" | no |
curl "https://api.brixsignage.com/v1/proof/advertisers" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | ProofOfPlayByAdvertiser | |
data.from | string | ISO-8601 timestamp (UTC). |
data.to | string | ISO-8601 timestamp (UTC). |
data.retentionDays | integer | |
data.fromRollup | boolean | Part of the window was read from the daily rollup. |
data.advertisers | array of object | By advertiser name; content with no tag comes last. |
data.advertisers[].advertiser | string | The tag, as most of its files spell it. Empty for content with no tag. |
data.advertisers[].played | integer | |
data.advertisers[].skipped | integer | |
data.advertisers[].failed | integer | |
data.advertisers[].totalDurationSec | integer | All plays, with skipped and failed plays. |
data.advertisers[].playedDurationSec | integer | Finished plays only: the report's minutes. A day whose daily total has no split counts its total. |
data.advertisers[].screens | integer | Distinct screens, each counted once. |
data.advertisers[].venues | integer | |
data.advertisers[].ads | integer | Distinct files and designs. |
data.advertisers[].firstAt | string | ISO-8601 timestamp (UTC). |
data.advertisers[].lastAt | string | ISO-8601 timestamp (UTC). |
data.advertisers[].byVenue | array of object | |
data.advertisers[].byVenue[].venueId | string | The location's id. Empty when the screen no longer exists. |
data.advertisers[].byVenue[].venueName | string | |
data.advertisers[].byVenue[].screens | integer | |
data.advertisers[].byVenue[].played | integer | |
data.advertisers[].byVenue[].skipped | integer | |
data.advertisers[].byVenue[].failed | integer | |
data.advertisers[].byVenue[].totalDurationSec | integer | |
data.advertisers[].byVenue[].playedDurationSec | integer | |
data.advertisers[].byVenue[].firstAt | string | ISO-8601 timestamp (UTC). |
data.advertisers[].byVenue[].lastAt | string | ISO-8601 timestamp (UTC). |
data.advertisers[].byVenue[].ads | array of object |
Response 401: Missing, expired or revoked bearer token.
Response 403: The token lacks the permission this operation needs (see x-brix-permission).
Response 422: A bad format, or an advertiser name longer than 120 characters.
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/proof/events
List individual playback events, one per play, for a date range. The number of events returned is capped. For totals rolled up by content item and screen, use GET /v1/proof instead.
Notes.
- rollup sits beside data, outside the usual envelope.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
from | query | string | no | ISO-8601 start (default: the start of the report window). |
to | query | string | no | ISO-8601 end (default: now). |
screenId | query | string | no |
curl "https://api.brixsignage.com/v1/proof/events" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | array of object | One row per play, newest first (at most 2000), from screens the caller can see. |
data[].id | string | |
data[].screenId | string | |
data[].screenName | string | The screen id when the screen no longer exists. |
data[].contentKind | string | media when not reported. |
data[].contentId | string | unknown when not reported. |
data[].contentName | string | Unknown content when not reported. |
data[].startedAt | string | ISO-8601 timestamp (UTC). |
data[].durationSec | integer | |
data[].result | "played" | "skipped" | "failed" | |
data[].reason | string | null | |
rollup | array of object | Daily totals for the part of the range older than the raw-event window; empty when from is inside it. |
rollup[].day | string | YYYY-MM-DD. |
rollup[].screenId | string | |
rollup[].contentId | string | |
rollup[].plays | integer | |
rollup[].totalDurationMs | integer | |
rollup[].played | integer | |
rollup[].skipped | integer | |
rollup[].failed | integer |
Response 401: Missing, expired or revoked bearer token.
Response 403: The token lacks the permission this operation needs (see x-brix-permission).
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/proof/export
Downloads the plays in a date range with the signature and chain status of each play, a summary of counts, a SHA-256 hash of the bundle and a detached server signature. Use from, to and screenId to filter and format=json or format=csv. The newest 5,000 plays are included. Available only to workspaces with digital-out-of-home enabled; other workspaces get 404.
curl "https://api.brixsignage.com/v1/proof/export" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 4XX: Client error. 404 rather than 403 for another tenant's resource, so account existence is not leaked.
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/proof/keys
Lists the proof-of-play signing keys that one screen has registered. screenId is required. Each key shows its key id, when it was first seen, the key it replaced and when it was revoked. Key material is never returned. Available only to workspaces with digital-out-of-home enabled.
curl "https://api.brixsignage.com/v1/proof/keys" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 4XX: Client error. 404 rather than 403 for another tenant's resource, so account existence is not leaked.
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/proof/keys/{keyId}/revoke
Marks one of a screen's signing keys as bad. Send the screenId in the body. From that time, plays signed with the key show as revoked, and the next new key from the screen registers as a replacement. Calling it again has no further effect. The change is recorded in the activity log.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
keyId | path | string | yes | Identifier for keyId. |
curl -X POST "https://api.brixsignage.com/v1/proof/keys/{keyId}/revoke" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 4XX: Client error. 404 rather than 403 for another tenant's resource, so account existence is not leaked.
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/proof/schedules
List the proof-of-play reports that you scheduled. Each one is sent by email every week or every month. You see only your own schedules.
curl "https://api.brixsignage.com/v1/proof/schedules" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | array of ProofReportSchedule | |
data[].id | string | |
data[].name | string | |
data[].cadence | "weekly" | "monthly" | |
data[].filters | object | |
data[].filters.screenIds | array of string | |
data[].filters.groupIds | array of string | Groups on the org tree; each covers the groups below it. |
data[].filters.contentIds | array of string | |
data[].filters.tags | array of string | Files and designs with any of these tags, on the day the report runs. |
data[].recipientUserIds | array of string | |
data[].nextRunAt | string | ISO-8601 timestamp (UTC). |
data[].lastRunAt | string | null | |
data[].lastStatus | string | null |
Response 401: Missing, expired or revoked bearer token.
Response 403: The token lacks the permission this operation needs (see x-brix-permission).
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/proof/schedules
Send a proof-of-play report by email every week or every month. Send a name, a cadence (weekly or monthly), optional filters and optional recipientUserIds (active people in this workspace; the default is you). The report shows only the screens that you can see. Only a signed-in person can schedule a report.
The report runs with your access at send time and goes only to active people in this workspace. The first one goes within the hour. A signed-in person only; an API key is refused.
Request body: application/json
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | At most 80 characters. |
cadence | "weekly" | "monthly" | yes | |
filters | object | no | |
filters.screenIds | array of string | no | |
filters.groupIds | array of string | no | Groups on the org tree; each covers the groups below it. |
filters.contentIds | array of string | no | |
filters.tags | array of string | no | Files and designs with any of these tags, on the day the report runs. |
recipientUserIds | array of string | no | 1 to 10 people in this workspace. Default: you. |
curl -X POST "https://api.brixsignage.com/v1/proof/schedules" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 201: Success.
| Field | Type | Description |
|---|---|---|
data | ProofReportSchedule | |
data.id | string | |
data.name | string | |
data.cadence | "weekly" | "monthly" | |
data.filters | object | |
data.filters.screenIds | array of string | |
data.filters.groupIds | array of string | Groups on the org tree; each covers the groups below it. |
data.filters.contentIds | array of string | |
data.filters.tags | array of string | Files and designs with any of these tags, on the day the report runs. |
data.recipientUserIds | array of string | |
data.nextRunAt | string | ISO-8601 timestamp (UTC). |
data.lastRunAt | string | null | |
data.lastStatus | string | null |
Response 401: Missing, expired or revoked bearer token.
Response 403: An API key cannot own a report.
Response 422: A bad name, cadence or filter, or a recipient who is not an active person in this workspace.
Response 5XX: Server error. The body carries a requestId to quote to support.
DELETE /v1/proof/schedules/{id}
Stop a proof-of-play report that you scheduled. You can stop only your own schedules.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
id | path | string | yes | Schedule id. |
curl -X DELETE "https://api.brixsignage.com/v1/proof/schedules/{id}" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.ok | boolean |
Response 401: Missing, expired or revoked bearer token.
Response 403: The token lacks the permission this operation needs (see x-brix-permission).
Response 404: You have no such schedule. Only its owner can stop it.
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/proof/verify-bundle
Checks a downloaded proof-of-play export against the published signing keys: the bundle hash, the server signature, and the device signature and chain of each play. No credential is needed. Requests are rate limited, and a bundle can be at most 8 MB and 5,000 plays.
curl -X POST "https://api.brixsignage.com/v1/proof/verify-bundle" Response 4XX: Client error. 404 rather than 403 for another tenant's resource, so account existence is not leaked.
Response 5XX: Server error. The body carries a requestId to quote to support.