# Media (part 2 of 3)

> For AI agents: the full docs index is at https://brixsignage.com/llms.txt, and every page has a markdown twin (add .md to the path).

Media is split into 3 pages: [part 1](https://brixsignage.com/developers/api/media.md) (`/v1/media` to `/v1/media/{id}`), [part 2](https://brixsignage.com/developers/api/media-2.md) (`/v1/media/{id}` to `/v1/media/{id}/web-secrets`), [part 3](https://brixsignage.com/developers/api/media-3.md) (`/v1/media/backfill-avif` to `/v1/media/upload/package`).

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](https://brixsignage.com/developers/authentication.md), [Errors and rate limits](https://brixsignage.com/developers/errors-and-rate-limits.md) and [Pagination](https://brixsignage.com/developers/pagination.md).

- [DELETE /v1/media/{id}](#delete-v1-media-id)
- [GET /v1/media/{id}/captions](#get-v1-media-id-captions)
- [POST /v1/media/{id}/captions](#post-v1-media-id-captions)
- [POST /v1/media/{id}/captions/transcribe](#post-v1-media-id-captions-transcribe)
- [POST /v1/media/{id}/captions/upload](#post-v1-media-id-captions-upload)
- [POST /v1/media/{id}/captions/visibility](#post-v1-media-id-captions-visibility)
- [GET /v1/media/{id}/delta](#get-v1-media-id-delta)
- [GET /v1/media/{id}/file](#get-v1-media-id-file)
- [POST /v1/media/{id}/focal-region](#post-v1-media-id-focal-region)
- [GET /v1/media/{id}/lan-preview](#get-v1-media-id-lan-preview)
- [POST /v1/media/{id}/lan-preview](#post-v1-media-id-lan-preview)
- [GET /v1/media/{id}/lan-preview/file](#get-v1-media-id-lan-preview-file)
- [GET /v1/media/{id}/playback-quality](#get-v1-media-id-playback-quality)
- [GET /v1/media/{id}/poster](#get-v1-media-id-poster)
- [POST /v1/media/{id}/poster](#post-v1-media-id-poster)
- [POST /v1/media/{id}/render](#post-v1-media-id-render)
- [GET /v1/media/{id}/render-frame](#get-v1-media-id-render-frame)
- [POST /v1/media/{id}/restore](#post-v1-media-id-restore)
- [POST /v1/media/{id}/rotate](#post-v1-media-id-rotate)
- [POST /v1/media/{id}/suggest](#post-v1-media-id-suggest)
- [GET /v1/media/{id}/usage](#get-v1-media-id-usage)
- [PUT /v1/media/{id}/web-secrets](#put-v1-media-id-web-secrets)

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

## DELETE /v1/media/{id}

Delete a media asset

Move a media asset to the recycle bin. Playlists and screens that reference it show a gap where the asset was until it is restored or replaced.

Moves the asset to the recycle bin (restorable for 30 days) and removes it from every playlist. Screens casting it return to their schedule.

Auth: Bearer token. Permission: `media.delete`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Media asset id. |
| `force` | query | "true" | no | Delete even when it is shared into other places. |

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.id` | string |  |
| `data.deleted` | true |  |
| `data.sharesRemoved` | integer | Shares removed with it. |

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No such asset in this workspace.

Response 409: `content_shared`: the item is shared into other places; `shareCount`, `crossSpaceShares`, `contentShares` say where. Repeat with `?force=true` to delete it and those shares.

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

## GET /v1/media/{id}/captions

Get a video's captions

Return a video's caption track as WebVTT. Add ?lang= to request a machine-translated version, for example ?lang=es for Spanish. This URL is stable, so it can be referenced directly by a player.

Auth: Bearer token. Permission: `media.view`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Media asset id. |
| `lang` | query | string | no | Two- or three-letter language code: a machine translation of the track (default: the original). |

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

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or it has no captions.

Response 429: More than 60 reads a minute.

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

## POST /v1/media/{id}/captions

Generate captions for a video

Automatically generate a caption track for a video from its audio and attach it to the asset. To upload a caption file instead, use the caption upload operation. To show or hide an existing caption track, use the caption visibility operation.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.ok` | true |  |
| `data.key` | string | Storage path of the caption track. |
| `data.state` | "ready" |  |

Response 400: `wrong_kind`: not a video.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or no bytes.

Response 413: Over 40 MB: send the audio to /captions/transcribe instead.

Response 502: `transcription_failed`.

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

## POST /v1/media/{id}/captions/transcribe

Generate captions from a video's audio

Convert a short audio clip, extracted from a video as 16 kHz mono WAV, into a caption track. Use this instead of the standard caption-generation operation when the full video file is too large to process directly.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

Request body: `application/octet-stream`

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.ok` | true |  |
| `data.key` | string | Storage path of the caption track. |
| `data.state` | "ready" |  |

Response 400: `wrong_kind`: not a video.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

Response 413: Over 20 MB.

Response 422: Empty body.

Response 502: `transcription_failed`.

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

## POST /v1/media/{id}/captions/upload

Upload a caption file

Attach a caption file to a video. SRT files are converted to WebVTT; WebVTT files are stored as-is. This is the alternative to automatic caption generation.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

Request body: `text/vtt`

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.ok` | true |  |
| `data.key` | string | Storage path of the caption track. |
| `data.state` | "ready" |  |

Response 400: `wrong_kind`: not a video.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

Response 413: Over 5 MB.

Response 415: Not a .vtt or .srt track.

Response 422: Empty body.

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

## POST /v1/media/{id}/captions/visibility

Show or hide a video's captions

Turn a video's caption track on or off for playback. Hiding the track keeps it in storage so it can be shown again later. If no caption track exists yet, the response indicates that one must be generated first.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `show` | boolean | no | True shows captions; anything else hides them. |

```bash
curl -X POST "https://api.brixsignage.com/v1/media/{id}/captions/visibility" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.state` | "hidden" \| "ready" \| "needs_audio" | `needs_audio`: shown, but the video has no caption track yet. |

Response 400: `wrong_kind`: not a video.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

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

## GET /v1/media/{id}/delta

Check for a media delta download

Used by playback devices to check whether their cached copy of a file is current. The caller sends the checksum of its cached copy and receives either the data needed to update it, or a flag indicating no partial update is available along with a URL to download the full file.

**Notes.**
- Reserved: delta downloads are not offered yet, so this always answers `deltaAvailable: false`.

Auth: Bearer token. Permission: `media.view`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.deltaAvailable` | false |  |
| `data.downloadUrl` | 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.

## GET /v1/media/{id}/file

Download a media file

Stream the media asset's file bytes. Supports HTTP Range requests for partial downloads.

**Notes.**
- HTML, SVG and script files are served as `application/octet-stream` attachments, never inline.

Auth: Bearer token. Permission: `media.view`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Media asset id. |
| `w` | query | string | no | Images: resize to this width (a thumbnail). |
| `h` | query | string | no | Images: resize to this height. |
| `fit` | query | "cover" \| "contain" \| "scale-down" \| "crop" \| "pad" | no | How a resized copy fits `w` × `h` (default `cover`). |

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

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or the file is not in storage.

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

## POST /v1/media/{id}/focal-region

Detect an image's focal region

Detect the main subject of an image and cache its position as a normalized x, y, width, and height. This lets the image be cropped around its subject when shown in a differently shaped area, instead of being cropped from the center.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.region` | object \| null | Fractions (0–1) of the image. Null when nothing stood out; the stored region is then unchanged. |

Response 400: `wrong_kind`: not an image.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or no bytes.

Response 413: Over 32 MB.

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

## GET /v1/media/{id}/lan-preview

Get the preview of an on-network page

Read the newest picture a screen took of this on-network web page, and the state of the newest request for one. A web page on a local network cannot be reached from the cloud, so only a screen on that network can take the picture.

Auth: Bearer token. Permission: `media.view`.

Parameters:

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

```bash
curl "https://api.brixsignage.com/v1/media/{id}/lan-preview" \
  -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/media/{id}/lan-preview

Ask a screen for a preview of an on-network page

Ask an online screen to take a picture of this on-network web page. Screens the page is assigned to are tried first, then its location, then the workspace. A second request within 30 seconds joins the one already running. Answers 422 for a page that is not on-network.

Auth: Bearer token. Permission: `screen.command-sent`.

Parameters:

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

```bash
curl -X POST "https://api.brixsignage.com/v1/media/{id}/lan-preview" \
  -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/media/{id}/lan-preview/file

Download the preview of an on-network page

Download the newest picture a screen took of this on-network web page.

Auth: Bearer token.

Parameters:

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

```bash
curl "https://api.brixsignage.com/v1/media/{id}/lan-preview/file" \
  -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/media/{id}/playback-quality

Get a video's playback quality

Return dropped-frame data reported by screens that have played this video, used to flag videos that are not playing smoothly. A null health value means the asset has not been measured yet, not that it is playing well.

Auth: Bearer token. Permission: `media.view`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.failures` | object \| null | Null when the item failed on no screen in the window. |
| `data.health` | object \| null | Null until a screen reports on this video. |
| `data.stutterDropPct` | number | Dropped-frame percentage above which a screen counts as struggling. |
| `data.minSamplesToWarn` | integer |  |
| `data.screens` | array of object |  |
| `data.screens[].screenId` | string |  |
| `data.screens[].worstDropPct` | number |  |
| `data.screens[].meanDropPct` | number |  |
| `data.screens[].samples` | integer |  |
| `data.screens[].videoWidth` | integer \| null |  |
| `data.screens[].videoHeight` | integer \| null |  |
| `data.screens[].lastSeenAt` | 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/media/{id}/poster

Get a media poster image

Return the poster image attached to a media asset, used as its thumbnail for videos and PDFs.

Auth: Bearer token. Permission: `media.view`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Media asset id. |
| `w` | query | string | no | Resize to this width. |
| `h` | query | string | no | Resize to this height. |
| `fit` | query | "cover" \| "contain" \| "scale-down" \| "crop" \| "pad" | no |  |

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

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or it has no poster.

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

## POST /v1/media/{id}/poster

Set or generate a media poster

Attach a poster image to a media asset, used as its thumbnail. The file must be an image and no larger than 4 MB.

**Notes.**
- With `?generate=1` the body is `{ thumbnailUrl, generated }` and no request body is read.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Media asset id. |
| `generate` | query | "1" | no | `1`: generate the poster from the media itself (send no body). |

Request body: `image/*`

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object \| object |  |

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

Response 413: Over 4 MB.

Response 415: Not a recognised image.

Response 422: Empty body.

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

## POST /v1/media/{id}/render

Render a web link now

Capture and store a screenshot of a web or link asset. If screenshot rendering is not available for this workspace, the response reports that it is not configured rather than failing.

**Notes.**
- Usually queued (`queued: true`); the frame is then at GET /v1/media/{id}/render-frame.
- A second request while a render of the same link with the same settings is still queued or running returns `queued: true` and adds nothing. After an edit, the request queues a render of the new settings.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object \| object |  |

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

Response 429: More than 60 renders a minute, or the workspace already has 4 web renders queued (`renders_busy`, retry after the Retry-After).

Response 502: The render failed.

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

## GET /v1/media/{id}/render-frame

Get a web link's latest render

Return the most recent screenshot generated for a web or link asset by the render operation.

Auth: Bearer token. Permission: `media.view`.

Parameters:

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

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

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or the link has not been rendered yet (a render is then queued).

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

## POST /v1/media/{id}/restore

Restore a deleted media item

Bring back a deleted media asset. Any playlist or screen still referencing it resumes rendering it.

Auth: Bearer token. Permission: `media.delete`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.id` | string |  |
| `data.restored` | true |  |

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

Response 409: `not_deleted`: it is not in the recycle bin.

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

## POST /v1/media/{id}/rotate

Rotate a photo or video 90, 180, or 270 degrees clockwise. This rewrites the stored file rather than only changing how it is displayed, since playback devices cannot rotate video at display time. Images are rotated immediately; video rotation is queued, and the asset keeps playing its current version until the rotated file is ready.

**Notes.**
- Photos rotate now (`rotated`); videos are re-encoded in the background (`queued`).

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `degrees` | 90 \| 180 \| 270 | yes | Clockwise. |

```bash
curl -X POST "https://api.brixsignage.com/v1/media/{id}/rotate" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object \| object |  |

Response 400: `degrees` is not 90, 180 or 270, or the item is not a photo or video.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or its bytes are gone.

Response 409: A rotation is already running.

Response 502: The image service failed.

Response 503: Rotation is not available.

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

## POST /v1/media/{id}/suggest

Suggest alt text and tags for an image

Analyze an image asset and return suggested altText and tags. This only returns suggestions; it does not save them, so use the update-media-asset operation to accept them. Only images are supported. If this feature is temporarily unavailable, the response returns empty values rather than failing.

**Notes.**
- Suggestions only: nothing is saved.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.altText` | string \| null |  |
| `data.tags` | array of string |  |

Response 400: `wrong_kind`: not an image.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id, or no bytes.

Response 413: Over 32 MB.

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

## GET /v1/media/{id}/usage

Show where a media asset is used

Return where a media asset is used, across playlists, creatives, and layouts, along with when it was last played.

Auth: Bearer token. Permission: `media.view`.

Parameters:

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | MediaUsage |  |
| `data.containers` | array of object |  |
| `data.containers[].id` | string |  |
| `data.containers[].name` | string |  |
| `data.containers[].kind` | "playlist" \| "schedule" \| "layout" \| "creative" \| "signage" | `signage` = a signage template (board). |
| `data.containers[].itemCount` | integer | Playlists only: total items in the playlist. |
| `data.screens` | array of object | Active screens showing it now, directly or through one of the containers. |
| `data.screens[].id` | string |  |
| `data.screens[].name` | string |  |
| `data.screens[].location` | string \| null |  |
| `data.screens[].status` | string | `online`, `offline` or `pairing`. |
| `data.lastPlayedAt` | string \| null | Last completed play reported by a screen; null if never played. |

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No such asset in this workspace.

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

## PUT /v1/media/{id}/web-secrets

Set a web link's secrets

Store credentials, such as authentication tokens or login passwords, for a web asset. Values are encrypted at rest and write-only: send an object mapping reference names to values, where a null value deletes that reference. Only the reference names, never the values, can be read back later. This merges with any existing secrets rather than replacing them.

Auth: Bearer token. Permission: `media.edit`.

Parameters:

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `secrets` | object | yes | Secret name → value (at most 50, values ≤ 8192 characters). `null` or `""` removes one; names not sent are kept. |
| `expect` | object | no | The link's `url` and `webConfig` as you last read them. Send it: the secrets are stored only if the link still sends them to that address and those sign-in steps, else 409. |
| `expect.url` | string | yes |  |
| `expect.webConfig` | any | yes |  |

```bash
curl -X PUT "https://api.brixsignage.com/v1/media/{id}/web-secrets" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.ok` | true |  |
| `data.refs` | array of string | The secret NAMES now stored. Values are never returned. |

Response 400: Too many secrets, a name or value too long, or a malformed `expect`.

Response 401: Missing, expired or revoked bearer token.

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

Response 404: No media with this id.

Response 409: The link's address or sign-in steps changed (or are not what `expect` says). Nothing was stored.

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