# Proof

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

## GET /v1/proof

Get a proof-of-play report

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.

Auth: Bearer token. Permission: `playback-log.view`.

Parameters:

| Name | 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. |

```bash
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. |

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. |

## GET /v1/proof/events

List proof-of-play 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.

Auth: Bearer token. Permission: `playback-log.view`.

```bash
curl "https://api.brixsignage.com/v1/proof/events" \
  -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.

| 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. |
