# Account (part 4 of 4)

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

Account is split into 4 pages: [part 1](https://brixsignage.com/developers/api/account.md) (`/v1/account` to `/v1/account/brix-plan/screens/estimate`), [part 2](https://brixsignage.com/developers/api/account-2.md) (`/v1/account/brix-plan/screens/request` to `/v1/account/location-payment`), [part 3](https://brixsignage.com/developers/api/account-3.md) (`/v1/account/location-payment` to `/v1/account/payment-card/complete`), [part 4](https://brixsignage.com/developers/api/account-4.md) (`/v1/account/payment-card/setup` to `/v1/account/upgrade-annual/estimate`).

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

- [POST /v1/account/payment-card/setup](#post-v1-account-payment-card-setup)
- [POST /v1/account/payment-card/swap](#post-v1-account-payment-card-swap)
- [GET /v1/account/payment-methods](#get-v1-account-payment-methods)
- [POST /v1/account/payment-methods/{id}/role](#post-v1-account-payment-methods-id-role)
- [POST /v1/account/payment-methods/manage-url](#post-v1-account-payment-methods-manage-url)
- [PATCH /v1/account/payment-option](#patch-v1-account-payment-option)
- [PATCH /v1/account/prefs](#patch-v1-account-prefs)
- [GET /v1/account/provider](#get-v1-account-provider)
- [POST /v1/account/reactivate](#post-v1-account-reactivate)
- [GET /v1/account/retention](#get-v1-account-retention)
- [PATCH /v1/account/retention](#patch-v1-account-retention)
- [POST /v1/account/screen-pool](#post-v1-account-screen-pool)
- [POST /v1/account/screen-pool/estimate](#post-v1-account-screen-pool-estimate)
- [DELETE /v1/account/screen-pool/scheduled](#delete-v1-account-screen-pool-scheduled)
- [GET /v1/account/support-access](#get-v1-account-support-access)
- [PATCH /v1/account/support-access/policy](#patch-v1-account-support-access-policy)
- [POST /v1/account/support-access/revoke](#post-v1-account-support-access-revoke)
- [POST /v1/account/upgrade-annual](#post-v1-account-upgrade-annual)
- [GET /v1/account/upgrade-annual/estimate](#get-v1-account-upgrade-annual-estimate)

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

## POST /v1/account/payment-card/setup

Start card setup

Starts adding or replacing the saved card for a workspace billed directly by Brix. Returns a hosted checkout URL where the card is entered, unless `useLastPaid: true` is passed and the payment provider already holds a card that was last used to pay this workspace, in which case that card is saved directly. Returns 409 if the workspace is not billed directly by Brix, and 404 for white-label workspaces.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `useLastPaid` | boolean | no | Save the card the last invoice was paid with, when that is possible, instead of opening a page. |
| `role` | "primary" \| "backup" | no | `backup` saves a backup card, charged once when the card is declined. Default `primary`. |

```bash
curl -X POST "https://api.brixsignage.com/v1/account/payment-card/setup" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

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

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 404: A workspace billed by a partner.

Response 409: `not_brix_billed`, or `card_unavailable`.

Response 502: The card page could not be opened.

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

## POST /v1/account/payment-card/swap

Swap card and backup card

Makes the saved backup card the card that invoices are charged to, and the previous card the backup. Returns 409 `backup_required` when no backup card is saved.

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

```bash
curl -X POST "https://api.brixsignage.com/v1/account/payment-card/swap" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.swapped` | true |  |
| `data.payment` | AccountPayment | Payment settings of an account that Brix invoices directly. |
| `data.payment.option` | "card" \| "invoice" | How issued invoices are paid: charged to the saved card, or paid from the invoice email. |
| `data.payment.card` | object \| null |  |
| `data.payment.backupCard` | object \| null | Charged once when the card is declined. |
| `data.payment.lastPaid` | object \| null | The card the last invoice was paid with. |
| `data.payment.cardAvailable` | boolean | Card payment can be set up for this workspace. |
| `data.payment.invoiceEmail` | string \| null | One more address that gets every invoice. The owners always get them. |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 404: A workspace billed by a partner.

Response 409: `not_brix_billed`, or `backup_required` (no backup card saved).

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

## GET /v1/account/payment-methods

List payment methods

Returns the workspace's saved payment methods, including cards and ACH bank accounts. When there are two or more methods and none is the backup, one method that is not the primary is made the backup.

**Notes.**
- A read that can write: with two or more methods and no backup, the handler makes one non-primary method the backup and records it in the audit log.

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

```bash
curl "https://api.brixsignage.com/v1/account/payment-methods" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.configured` | boolean | False when billing is not set up (or could not be read, see `reason`). |
| `data.sources` | array of object |  |
| `data.sources[].id` | string |  |
| `data.sources[].type` | string | `card`, `bank_account`, or a wallet type (`apple_pay`, `paypal_express_checkout`, …). |
| `data.sources[].brand` | string \| null |  |
| `data.sources[].last4` | string \| null |  |
| `data.sources[].walletType` | string \| null |  |
| `data.sources[].gateway` | string \| null |  |
| `data.sources[].expiryMonth` | integer \| null |  |
| `data.sources[].expiryYear` | integer \| null |  |
| `data.sources[].status` | string |  |
| `data.sources[].primary` | boolean |  |
| `data.sources[].backup` | boolean | Charged when the primary fails. |
| `data.reason` | string |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

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

## POST /v1/account/payment-methods/{id}/role

Set payment method role

Sets a saved payment method as the primary or backup method for the workspace.

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

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Payment method id from the list. |

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `role` | "primary" \| "backup" | yes |  |

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.ok` | true |  |
| `data.id` | string |  |
| `data.role` | "primary" \| "backup" |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 404: Not one of this workspace's payment methods.

Response 409: `billing_not_configured`.

Response 422: Bad `role`.

Response 502: The billing provider did not answer; nothing changed.

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

## POST /v1/account/payment-methods/manage-url

Get payment methods management link

Returns a hosted page URL where the workspace can add, replace, or remove a saved card or bank account.

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

```bash
curl -X POST "https://api.brixsignage.com/v1/account/payment-methods/manage-url" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.url` | string | A hosted page to add, replace or remove a card or bank account. Open it in a browser. |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `billing_not_configured`.

Response 502: The billing provider did not answer; nothing changed.

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

## PATCH /v1/account/payment-option

Set payment option

Sets how a workspace billed directly by Brix pays: `card` or `invoice`. Choosing `card` requires a saved card and returns 409 if none exists; every invoice Brix issues is then charged to that card automatically. Returns 409 if the workspace is billed through the billing provider instead, and 404 for white-label workspaces.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `option` | "card" \| "invoice" | yes |  |

```bash
curl -X PATCH "https://api.brixsignage.com/v1/account/payment-option" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.changed` | boolean |  |
| `data.payment` | AccountPayment | Payment settings of an account that Brix invoices directly. |
| `data.payment.option` | "card" \| "invoice" | How issued invoices are paid: charged to the saved card, or paid from the invoice email. |
| `data.payment.card` | object \| null |  |
| `data.payment.backupCard` | object \| null | Charged once when the card is declined. |
| `data.payment.lastPaid` | object \| null | The card the last invoice was paid with. |
| `data.payment.cardAvailable` | boolean | Card payment can be set up for this workspace. |
| `data.payment.invoiceEmail` | string \| null | One more address that gets every invoice. The owners always get them. |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 404: A workspace billed by a partner.

Response 409: `not_brix_billed`, or `card_required` (save a card first).

Response 422: Bad `option`.

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

## PATCH /v1/account/prefs

Update workspace preferences

Updates workspace-level preferences such as locale, time zone, date and number formats, brand kit, and plan tier. Any field you include is overwritten; fields you omit keep their current value.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `kioskPin` | string \| null | no | Set (4–8 digits) or clear (null) the workspace Screen Lock PIN. Stored as a hash. |
| `requireSso` | boolean | no | Needs a working single sign-on connection with verified domains; until someone signs in through it, the request is held (`requireSsoPending`). |
| `requireTwoFactor` | boolean | no | Turning it on needs the calling user to have two-factor sign-in set up, so an API key cannot turn it on. |

```bash
curl -X PATCH "https://api.brixsignage.com/v1/account/prefs" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"timeFormat":"24h","timeZone":"America/Chicago"}'
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | WorkspacePrefs | Workspace preferences. Every key is present (defaults filled in). |
| `data.timeFormat` | "12h" \| "24h" |  |
| `data.weekStart` | "mon" \| "sun" |  |
| `data.dateFormat` | "mdy" \| "dmy" \| "ymd" |  |
| `data.tempUnits` | "f" \| "c" |  |
| `data.timeZone` | string | IANA time zone. Screens without their own zone use it, and so do schedules timed by the workspace. |
| `data.language` | string | BCP 47 language tag. |
| `data.multinational` | boolean | Shows the per-location and per-screen language settings. |
| `data.newLocationsPayFirst` | boolean | New locations pay for themselves before going live: each adds its own card, and its screens show a hold card (not billed to the account) until then. Default false. Turning it on needs Brix billing with a running plan (409 otherwise). |
| `data.navExtras` | array of string | Console pages switched on that the workspace size hides by default. |
| `data.appBranding` | object | The look of the on-screen apps. |
| `data.appBranding.accent` | string |  |
| `data.appBranding.accent2` | string |  |
| `data.appBranding.theme` | "dark" \| "light" |  |
| `data.appBranding.backdrop` | "brand" \| "wash" \| "plain" \| "aurora" \| "dots" \| "grid" \| "solid" |  |
| `data.appBranding.intensity` | number |  |
| `data.brandKits` | array of object | Saved looks. An app follows one with `config.brandKitId`. A write replaces the whole list (at most 50). |
| `data.brandKits[].id` | string |  |
| `data.brandKits[].name` | string |  |
| `data.brandKits[].accent` | string |  |
| `data.brandKits[].accent2` | string |  |
| `data.brandKits[].theme` | "dark" \| "light" |  |
| `data.brandKits[].backdrop` | "brand" \| "wash" \| "plain" \| "aurora" \| "dots" \| "grid" \| "solid" |  |
| `data.brandKits[].intensity` | number |  |
| `data.audio` | object | Default screen volume and a master mute. |
| `data.audio.volume` | number | 0–100. |
| `data.audio.muted` | boolean |  |
| `data.brand` | object |  |
| `data.brand.companyName` | string |  |
| `data.brand.logoUrl` | string |  |
| `data.requireAltText` | boolean |  |
| `data.showScreenLogo` | boolean |  |
| `data.keepTvOnInput` | boolean | Default for "Keep the TV on this input" on screens that have not set their own. |
| `data.standbyContentKind` | string \| null | What a screen with nothing to play shows; null = the default card. |
| `data.standbyContentId` | string \| null |  |
| `data.tier` | "simple" \| "team" \| "enterprise" | Workspace size. It sets console defaults, not access. |
| `data.industry` | string \| null |  |
| `data.onboardingCompletedAt` | string \| null |  |
| `data.setupStep` | string \| null | Walkthrough position (`s1`…`s5`, `l1`…`l6`, `done`). |
| `data.welcomeDeclinedAt` | string \| null | When the owner declined the setup questions. Null if never declined, or answered later. |
| `data.aboutYouDue` | boolean | The workspace is asked the first-sign-in questions (workspaces created from 2026-10-14). |
| `data.aboutYouAt` | string \| null | When the first-sign-in questions were answered. |
| `data.expectedScreens` | integer \| null | How many screens the owner said they expect. |
| `data.orgNameSet` | boolean |  |
| `data.tiers` | array of integer | Location tree levels in use. |
| `data.tierLabels` | object | Custom names for the location tree levels. |
| `data.requireTwoFactor` | boolean |  |
| `data.requireSso` | boolean |  |
| `data.requireSsoPending` | boolean | Single sign-on was required, and turns on after the first sign-in through the connection. |
| `data.requireSsoPendingSince` | string \| null |  |
| `data.ai` | object |  |
| `data.ai.enabled` | boolean |  |
| `data.ai.features` | object | Per feature (`tags`, `alt-text`, `moderation`, `transcription`, `translation`, `focal-region`, `embedding`); an absent feature follows `enabled`. |
| `data.ai.dailyCallLimit` | integer \| null |  |
| `data.ai.redactPersonalData` | boolean |  |
| `data.retention` | object | Days kept per stream, only for the streams the workspace has set. An absent stream uses the platform window. |
| `data.retention.offline` | number |  |
| `data.retention.screenshots` | number |  |
| `data.retention.playback` | number |  |
| `data.retention.deviceLogs` | number |  |
| `data.retention.vitals` | number |  |
| `data.retention.replays` | number |  |
| `data.retention.aiEvents` | number |  |
| `data.warehouse` | object | Data warehouse feed. Set by Brix; not writable here. |
| `data.warehouse.enabled` | boolean |  |
| `data.warehouse.bucketBinding` | string | Set by Brix when the data warehouse feed is provisioned. |
| `data.warehouse.tables` | array of string |  |
| `data.warehouse.lookbackDays` | integer |  |
| `data.supportAccess` | SupportAccessPolicy |  |
| `data.supportAccess.mode` | "open" \| "notify" \| "approve" | `open`: Brix support may open the workspace. `notify`: it may, and the owners are emailed. `approve`: a person here must approve each request. |
| `data.supportAccess.grantMinutes` | integer | How long an approval lasts. |
| `data.supportAccess.requestTtlMinutes` | integer | How long a request waits for an answer before it expires. |
| `data.kioskHasGlobalPin` | boolean | A workspace Screen Lock PIN is set. The PIN and its hash are never returned. |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 422: `sso_not_configured`, `two_factor_not_enrolled`, or a PIN that is not 4–8 digits.

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

## GET /v1/account/provider

Get the workspace provider

Returns the partner that provides this workspace, with its product name and the email addresses of its team, or `null` when no partner provides it. The partner always has access to the workspace, and this access cannot be turned off.

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

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

Reactivate account

Reverses a scheduled cancellation, or resumes an account that was paused for seasonal closure.

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

```bash
curl -X POST "https://api.brixsignage.com/v1/account/reactivate" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.status` | "active" |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `already_active`, `pending_deletion`, `payment_required`, `payment_method_required`, `not_reactivatable`, or `under_contract`.

Response 502: The billing provider did not answer; nothing changed.

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

## GET /v1/account/retention

Get retention settings

Returns the workspace's data retention schedule: every data stream that can be governed, the retention window currently in effect for it, and the allowed range for that window.

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

```bash
curl "https://api.brixsignage.com/v1/account/retention" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | RetentionSchedule |  |
| `data.policy` | object | Days kept per stream, only for the streams the workspace has set. An absent stream uses the platform window. |
| `data.policy.offline` | number |  |
| `data.policy.screenshots` | number |  |
| `data.policy.playback` | number |  |
| `data.policy.deviceLogs` | number |  |
| `data.policy.vitals` | number |  |
| `data.policy.replays` | number |  |
| `data.policy.aiEvents` | number |  |
| `data.effective` | object | Days kept per stream now. |
| `data.effective.offline` | integer |  |
| `data.effective.screenshots` | integer |  |
| `data.effective.playback` | integer |  |
| `data.effective.deviceLogs` | integer |  |
| `data.effective.vitals` | integer |  |
| `data.effective.replays` | integer |  |
| `data.effective.aiEvents` | integer |  |
| `data.bounds` | object |  |
| `data.bounds.offline` | object |  |
| `data.bounds.offline.min` | integer |  |
| `data.bounds.offline.max` | integer |  |
| `data.bounds.offline.platformDefault` | integer |  |
| `data.bounds.offline.label` | string |  |
| `data.bounds.offline.what` | string |  |
| `data.bounds.screenshots` | object |  |
| `data.bounds.screenshots.min` | integer |  |
| `data.bounds.screenshots.max` | integer |  |
| `data.bounds.screenshots.platformDefault` | integer |  |
| `data.bounds.screenshots.label` | string |  |
| `data.bounds.screenshots.what` | string |  |
| `data.bounds.playback` | object |  |
| `data.bounds.playback.min` | integer |  |
| `data.bounds.playback.max` | integer |  |
| `data.bounds.playback.platformDefault` | integer |  |
| `data.bounds.playback.label` | string |  |
| `data.bounds.playback.what` | string |  |
| `data.bounds.deviceLogs` | object |  |
| `data.bounds.deviceLogs.min` | integer |  |
| `data.bounds.deviceLogs.max` | integer |  |
| `data.bounds.deviceLogs.platformDefault` | integer |  |
| `data.bounds.deviceLogs.label` | string |  |
| `data.bounds.deviceLogs.what` | string |  |
| `data.bounds.vitals` | object |  |
| `data.bounds.vitals.min` | integer |  |
| `data.bounds.vitals.max` | integer |  |
| `data.bounds.vitals.platformDefault` | integer |  |
| `data.bounds.vitals.label` | string |  |
| `data.bounds.vitals.what` | string |  |
| `data.bounds.replays` | object |  |
| `data.bounds.replays.min` | integer |  |
| `data.bounds.replays.max` | integer |  |
| `data.bounds.replays.platformDefault` | integer |  |
| `data.bounds.replays.label` | string |  |
| `data.bounds.replays.what` | string |  |
| `data.bounds.aiEvents` | object |  |
| `data.bounds.aiEvents.min` | integer |  |
| `data.bounds.aiEvents.max` | integer |  |
| `data.bounds.aiEvents.platformDefault` | integer |  |
| `data.bounds.aiEvents.label` | string |  |
| `data.bounds.aiEvents.what` | string |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

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

## PATCH /v1/account/retention

Set retention window

Sets the retention window, in days, for one or more data streams. Sending `null` for a stream resets it to the platform default. Values are clamped to the allowed range for each stream.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `offline` | number \| null | no |  |
| `screenshots` | number \| null | no |  |
| `playback` | number \| null | no |  |
| `deviceLogs` | number \| null | no |  |
| `vitals` | number \| null | no |  |
| `replays` | number \| null | no |  |
| `aiEvents` | number \| null | no |  |

```bash
curl -X PATCH "https://api.brixsignage.com/v1/account/retention" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | RetentionSchedule |  |
| `data.policy` | object | Days kept per stream, only for the streams the workspace has set. An absent stream uses the platform window. |
| `data.policy.offline` | number |  |
| `data.policy.screenshots` | number |  |
| `data.policy.playback` | number |  |
| `data.policy.deviceLogs` | number |  |
| `data.policy.vitals` | number |  |
| `data.policy.replays` | number |  |
| `data.policy.aiEvents` | number |  |
| `data.effective` | object | Days kept per stream now. |
| `data.effective.offline` | integer |  |
| `data.effective.screenshots` | integer |  |
| `data.effective.playback` | integer |  |
| `data.effective.deviceLogs` | integer |  |
| `data.effective.vitals` | integer |  |
| `data.effective.replays` | integer |  |
| `data.effective.aiEvents` | integer |  |
| `data.bounds` | object |  |
| `data.bounds.offline` | object |  |
| `data.bounds.offline.min` | integer |  |
| `data.bounds.offline.max` | integer |  |
| `data.bounds.offline.platformDefault` | integer |  |
| `data.bounds.offline.label` | string |  |
| `data.bounds.offline.what` | string |  |
| `data.bounds.screenshots` | object |  |
| `data.bounds.screenshots.min` | integer |  |
| `data.bounds.screenshots.max` | integer |  |
| `data.bounds.screenshots.platformDefault` | integer |  |
| `data.bounds.screenshots.label` | string |  |
| `data.bounds.screenshots.what` | string |  |
| `data.bounds.playback` | object |  |
| `data.bounds.playback.min` | integer |  |
| `data.bounds.playback.max` | integer |  |
| `data.bounds.playback.platformDefault` | integer |  |
| `data.bounds.playback.label` | string |  |
| `data.bounds.playback.what` | string |  |
| `data.bounds.deviceLogs` | object |  |
| `data.bounds.deviceLogs.min` | integer |  |
| `data.bounds.deviceLogs.max` | integer |  |
| `data.bounds.deviceLogs.platformDefault` | integer |  |
| `data.bounds.deviceLogs.label` | string |  |
| `data.bounds.deviceLogs.what` | string |  |
| `data.bounds.vitals` | object |  |
| `data.bounds.vitals.min` | integer |  |
| `data.bounds.vitals.max` | integer |  |
| `data.bounds.vitals.platformDefault` | integer |  |
| `data.bounds.vitals.label` | string |  |
| `data.bounds.vitals.what` | string |  |
| `data.bounds.replays` | object |  |
| `data.bounds.replays.min` | integer |  |
| `data.bounds.replays.max` | integer |  |
| `data.bounds.replays.platformDefault` | integer |  |
| `data.bounds.replays.label` | string |  |
| `data.bounds.replays.what` | string |  |
| `data.bounds.aiEvents` | object |  |
| `data.bounds.aiEvents.min` | integer |  |
| `data.bounds.aiEvents.max` | integer |  |
| `data.bounds.aiEvents.platformDefault` | integer |  |
| `data.bounds.aiEvents.label` | string |  |
| `data.bounds.aiEvents.what` | string |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

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

## POST /v1/account/screen-pool

Buy screen licences

Sets how many screens the workspace pays for. An increase is charged now, prorated, to the payment method on file (a very small amount is added to the renewal instead). A reduction on a paid plan takes effect at the renewal and is not refunded; during the free trial a change takes effect at once. You cannot set the plan below the number of screens that are running.

**Notes.**
- An increase is charged now (prorated). A reduction on a paid plan is queued for the renewal and answers `scheduled: true`; in the trial it changes at once.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `quantity` | integer | yes |  |

```bash
curl -X POST "https://api.brixsignage.com/v1/account/screen-pool" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

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

Response 401: Missing, expired or revoked bearer token.

Response 402: `card_declined` or `payment_incomplete`: the plan did not change (or needs our team).

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `screens_in_use` (below the screens running), `no_subscription`, `account_cancelled`, or `under_contract`.

Response 422: `quantity` is not a whole number from 1 to 10000.

Response 502: The change could not be made.

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

## POST /v1/account/screen-pool/estimate

Estimate screen-pool change

Returns the prorated cost of changing the screen pool before committing to it, including the exact amount that would be charged today and which card would be used. This is read-only and does not change anything; it uses POST rather than GET because the requested quantity must never be cached.

**Notes.**
- A POST because it takes an argument; it changes nothing.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `quantity` | integer | yes |  |

```bash
curl -X POST "https://api.brixsignage.com/v1/account/screen-pool/estimate" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.lines` | array of object | Line items of the invoice raised today. |
| `data.lines[].description` | string |  |
| `data.lines[].amount` | number |  |
| `data.creditsApplied` | number | Credit for the unused part of the current term. |
| `data.subTotal` | number |  |
| `data.amountDueNow` | number | Charged now, after credits (currency units, not cents). |
| `data.currencyCode` | string |  |
| `data.nextBillingAt` | string \| null |  |
| `data.payWith` | string \| null | The payment method that is charged (`Visa •••• 4242`). |
| `data.currentQuantity` | integer |  |
| `data.newQuantity` | integer |  |
| `data.renewalAmount` | number \| null | What each term costs after the change. |
| `data.chargedToday` | boolean | False when the amount is too small to charge today (it is added to the renewal). |
| `data.invoiced` | boolean | The account pays by invoice; nothing is charged to a card. |
| `data.decreaseRequiresSupport` | false | Always false. Kept for older clients. |
| `data.scheduledAtRenewal` | boolean | A reduction on a paid plan: it takes effect at `renewsAt`. |
| `data.renewsAt` | string \| null |  |
| `data.inTrial` | boolean |  |
| `data.trialEndsAt` | string \| null |  |
| `data.minQuantity` | integer | The lowest allowed quantity: the screens running now (at least 1). |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `no_subscription`, `account_cancelled`, or `under_contract`.

Response 422: `quantity` is not a whole number from 1 to 10000.

Response 502: `estimate_unavailable`.

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

## DELETE /v1/account/screen-pool/scheduled

Cancel scheduled screen-pool change

Cancels a screen-pool reduction that is queued to take effect at renewal, keeping the current plan instead. Calling this when nothing is scheduled has no effect.

**Notes.**
- Succeeds when nothing is queued too.

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

```bash
curl -X DELETE "https://api.brixsignage.com/v1/account/screen-pool/scheduled" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.ok` | true |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `no_subscription`, `account_cancelled`, or `under_contract`.

Response 502: The billing provider did not answer; nothing changed.

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

## GET /v1/account/support-access

Get support access status

Returns the workspace's current Brix support access policy (always allowed, allowed with notification, or approval required), every access request Brix support has raised along with its decision, and every support session opened on the workspace, with any still in progress marked as live.

**Notes.**
- A read that can write: pending requests past their expiry are marked `expired` first.

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

```bash
curl "https://api.brixsignage.com/v1/account/support-access" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.policy` | SupportAccessPolicy |  |
| `data.policy.mode` | "open" \| "notify" \| "approve" | `open`: Brix support may open the workspace. `notify`: it may, and the owners are emailed. `approve`: a person here must approve each request. |
| `data.policy.grantMinutes` | integer | How long an approval lasts. |
| `data.policy.requestTtlMinutes` | integer | How long a request waits for an answer before it expires. |
| `data.modes` | array of object |  |
| `data.modes[].id` | "open" \| "notify" \| "approve" |  |
| `data.modes[].label` | string |  |
| `data.modes[].what` | string |  |
| `data.requests` | array of object | Newest 100. |
| `data.requests[].id` | string |  |
| `data.requests[].staffEmail` | string | The Brix support person who asked. |
| `data.requests[].reason` | string |  |
| `data.requests[].reasonCategory` | string \| null |  |
| `data.requests[].status` | "pending" \| "approved" \| "denied" \| "expired" \| "revoked" |  |
| `data.requests[].requestedAt` | string | ISO-8601 timestamp (UTC). |
| `data.requests[].requestExpiresAt` | string | ISO-8601 timestamp (UTC). |
| `data.requests[].decidedAt` | string \| null |  |
| `data.requests[].decidedByEmail` | string \| null |  |
| `data.requests[].decidedByName` | string \| null |  |
| `data.requests[].grantExpiresAt` | string \| null |  |
| `data.requests[].decisionNote` | string \| null |  |
| `data.requests[].grantLive` | boolean |  |
| `data.sessions` | array of object | Times Brix support opened the workspace, newest 100. |
| `data.sessions[].id` | string |  |
| `data.sessions[].staffEmail` | string |  |
| `data.sessions[].reason` | string |  |
| `data.sessions[].startedAt` | string | ISO-8601 timestamp (UTC). |
| `data.sessions[].endedAt` | string \| null |  |
| `data.sessions[].expiresAt` | string \| null |  |
| `data.sessions[].live` | boolean |  |
| `data.sessions[].recorded` | boolean | The session was screen-recorded. |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

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

## PATCH /v1/account/support-access/policy

Set support access policy

Sets whether Brix support may open the workspace: always allowed and recorded, allowed but the workspace is notified as it happens, or only with explicit approval for each request.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `mode` | "open" \| "notify" \| "approve" | no | `open`: Brix support may open the workspace. `notify`: it may, and the owners are emailed. `approve`: a person here must approve each request. |
| `grantMinutes` | integer | no | How long an approval lasts. |
| `requestTtlMinutes` | integer | no | How long a request waits for an answer before it expires. |

```bash
curl -X PATCH "https://api.brixsignage.com/v1/account/support-access/policy" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | SupportAccessPolicy |  |
| `data.mode` | "open" \| "notify" \| "approve" | `open`: Brix support may open the workspace. `notify`: it may, and the owners are emailed. `approve`: a person here must approve each request. |
| `data.grantMinutes` | integer | How long an approval lasts. |
| `data.requestTtlMinutes` | integer | How long a request waits for an answer before it expires. |

Response 401: Missing, expired or revoked bearer token.

Response 403: A Brix support session cannot change this. Also: You do not hold the permission for the whole workspace (a grant at one location is not enough).

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

## POST /v1/account/support-access/revoke

Revoke support access

Immediately withdraws consent for Brix support access: ends every live support session and cancels any outstanding approval, in that order.

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

```bash
curl -X POST "https://api.brixsignage.com/v1/account/support-access/revoke" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.sessionsEnded` | integer |  |
| `data.grantsRevoked` | integer |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: A Brix support session cannot do this. Also: You do not hold the permission for the whole workspace (a grant at one location is not enough).

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

## POST /v1/account/upgrade-annual

Switch to annual billing

Switches the workspace's monthly subscription to annual, upfront billing. Returns 409 if the workspace is already on annual billing or has no active subscription.

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

```bash
curl -X POST "https://api.brixsignage.com/v1/account/upgrade-annual" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.cadence` | "annual" |  |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `no_subscription`, `under_contract`, or `already_annual`.

Response 502: The switch failed.

Response 503: `annual_switch_unavailable`: the switch is not self-serve yet; contact support.

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

## GET /v1/account/upgrade-annual/estimate

Estimate annual upgrade cost

Returns the prorated cost of switching from monthly to annual billing before committing to it, including which card would be charged.

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

```bash
curl "https://api.brixsignage.com/v1/account/upgrade-annual/estimate" \
  -H "Authorization: Bearer $BRIX_API_KEY"
```

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.lines` | array of object | Line items of the invoice raised today. |
| `data.lines[].description` | string |  |
| `data.lines[].amount` | number |  |
| `data.creditsApplied` | number | Credit for the unused part of the current term. |
| `data.subTotal` | number |  |
| `data.amountDueNow` | number | Charged now, after credits (currency units, not cents). |
| `data.currencyCode` | string |  |
| `data.nextBillingAt` | string \| null |  |
| `data.payWith` | string \| null | The payment method that is charged (`Visa •••• 4242`). |

Response 401: Missing, expired or revoked bearer token.

Response 403: You do not hold the permission for the whole workspace (a grant at one location is not enough).

Response 409: `no_subscription` or `under_contract`.

Response 502: `estimate_unavailable`.

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