# Account (part 3 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).

- [PUT /v1/account/location-payment](#put-v1-account-location-payment)
- [PATCH /v1/account/look-prefs](#patch-v1-account-look-prefs)
- [GET /v1/account/me-prefs](#get-v1-account-me-prefs)
- [GET /v1/account/onboarding](#get-v1-account-onboarding)
- [POST /v1/account/onboarding](#post-v1-account-onboarding)
- [GET /v1/account/payers](#get-v1-account-payers)
- [POST /v1/account/payers](#post-v1-account-payers)
- [PATCH /v1/account/payers/{id}](#patch-v1-account-payers-id)
- [DELETE /v1/account/payers/{id}](#delete-v1-account-payers-id)
- [POST /v1/account/payers/{id}/card-link](#post-v1-account-payers-id-card-link)
- [POST /v1/account/payers/resolve](#post-v1-account-payers-resolve)
- [GET /v1/account/payers/search](#get-v1-account-payers-search)
- [DELETE /v1/account/payment-card](#delete-v1-account-payment-card)
- [POST /v1/account/payment-card/complete](#post-v1-account-payment-card-complete)

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

## PUT /v1/account/location-payment

Set whether new locations pay for themselves

Turn on or off the account setting that makes new locations pay for their own screens before they go live. Send `{ newLocationsPayFirst: true | false }`. Requires `billing.edit` on the whole account; an API key also needs the `location-payment.edit` scope, and a connected app cannot change it. Returns 409 when the account cannot use location payment. The change is recorded in the activity log.

Auth: Bearer token.

```bash
curl -X PUT "https://api.brixsignage.com/v1/account/location-payment" \
  -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.

## PATCH /v1/account/look-prefs

Update brand, tier and AI preferences

Updates the brand kit, the organization tiers and the AI settings. Needs permission to edit settings. Any other preference is refused: use the workspace preferences route, which needs permission to edit billing.

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

Request body: `application/json`

```bash
curl -X PATCH "https://api.brixsignage.com/v1/account/look-prefs" \
  -H "Authorization: Bearer $BRIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"showScreenLogo":true}'
```

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: A key that this route does not change.

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

## GET /v1/account/me-prefs

Get my preferences

Returns preferences in three layers: `workspace` (the shared defaults), `user` (only the values the calling user has changed; empty for an API key), and `effective` (the merged result to use for display).

**Notes.**
- `user` is returned as saved: the per-user write does not check its keys or values.

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

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

Response 200: Success.

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

Get welcome details

Returns what the welcome panel needs: how the owner signed up (email, Google or Microsoft), the workspace country, whether a phone number is on file, and the region where the workspace data is stored, with a plain place name.

Auth: Bearer token.

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

Complete onboarding

Finishes workspace onboarding in a single call: renames the workspace to the given name, records the industry and complexity tier, marks onboarding as complete, and seeds a starter set of ready-to-play content tailored to the chosen industry. Combining these into one call ensures the completion flag and the seeded content are never out of sync.

**Notes.**
- Every call adds the starter content again; it is not idempotent.
- `tier` is stored as sent without a check.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `workspaceName` | string | no | Renames the workspace and sets the brand company name (cut at 120). |
| `industry` | string \| null | no | Industry id (`cafe`, `qsr`, `gym`, …); picks the starter designs. |
| `tier` | "simple" \| "team" \| "enterprise" | no |  |
| `setupStep` | string | no | Walkthrough position to save with the answers. |
| `orientation` | "landscape" \| "portrait" | no | "portrait" seeds the starter designs on a portrait stage (the first screen hangs in portrait). Default landscape. |
| `welcomeDeclined` | boolean | no | The owner declined the setup questions: adds the generic starter set and records `prefs.welcomeDeclinedAt`. Any other call clears it. |

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

Response 200: Success.

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

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: Unknown `industry`.

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

## GET /v1/account/payers

List payers

Lists who pays for the screens. The main account comes first, with the screens it pays for, its price and how often it is billed. Then each payer follows with its status, card, targets (locations, screen groups and screens), screen count and price.

Auth: Bearer token.

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

Add a payer

Adds a payer, such as a franchise or a site that pays for its own screens. Send its name, finance email and targets. The payer starts to pay for its screens when its first invoice is paid. The change is recorded in the activity log.

Auth: Bearer token.

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

## PATCH /v1/account/payers/{id}

Edit a payer

Changes a payer's name, finance email, address or targets. New targets change which payer pays for each screen. Screens added during a term are invoiced to the payer now, for the remaining part of the term. The change is recorded in the activity log.

Auth: Bearer token.

Parameters:

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

```bash
curl -X PATCH "https://api.brixsignage.com/v1/account/payers/{id}" \
  -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.

## DELETE /v1/account/payers/{id}

Remove a payer

Removes a payer. Its screens go back to the main account from the next billing period, and its unpaid invoices stay open. Returns 409 `not_brix_billed` when the account is not billed by Brix. The change is recorded in the activity log.

Auth: Bearer token.

Parameters:

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

```bash
curl -X DELETE "https://api.brixsignage.com/v1/account/payers/{id}" \
  -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/payers/{id}/card-link

Get a payer's card link

Returns a signed link, valid for 90 days, to a page where the payer's finance team adds a card without signing in. Send `send: true` to email the link to the payer's finance email.

Auth: Bearer token.

Parameters:

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

```bash
curl -X POST "https://api.brixsignage.com/v1/account/payers/{id}/card-link" \
  -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/payers/resolve

Preview a payer change

Shows the result of a payer edit before you save it: the payer's screen count and price, the screens it would take from other payers, and the screens that two screen groups give to different payers. Nothing is saved.

Auth: Bearer token.

```bash
curl -X POST "https://api.brixsignage.com/v1/account/payers/resolve" \
  -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/account/payers/search

Search payer targets

Finds locations, screen groups and screens that match `q`, for use as payer targets. Each screen shows the payer that pays for it now. Locations are included only when the workspace has more than one. At most 50 results of each kind are returned.

Auth: Bearer token.

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

## DELETE /v1/account/payment-card

Remove saved card

Removes the workspace's saved card. If the payment option was set to card, it reverts to invoice billing.

**Notes.**
- Removing the card when a backup card is saved makes the backup the card. With no backup and the payment option `card`, the option goes back to `invoice`.

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

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `role` | query | "primary" \| "backup" | no | `backup` removes the backup card only. |

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.removed` | 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`.

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

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

Complete card setup

Saves the card from a finished hosted card-setup session, given its `sessionId`. Brix re-reads the session from the payment provider and confirms it belongs to the calling workspace, returning 404 otherwise. The same result also happens automatically when the payment provider notifies Brix that the session completed.

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

Request body: `application/json`

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `sessionId` | string | yes | The `card_session` value from the return URL (`cs_…`). |

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.outcome` | "saved" \| "already_saved" \| "incomplete" |  |
| `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: Not a card session of this workspace.

Response 409: `not_brix_billed`.

Response 422: `sessionId` missing or malformed.

Response 502: The session could not be read.

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