GDPR API
GDPR endpoints in the Brix REST API for digital signage: 3 operations (POST, GET). Each lists its path, auth, required permission and a curl example.
View as Markdown · For AI agents: the full docs index is at /llms.txt
Base URL https://api.brixsignage.com. Send Authorization: Bearer $BRIX_API_KEY unless an operation says Auth: none or Auth: no API key. The Permission line names what the key must hold. See Authentication and scopes, Errors and rate limits and Pagination.
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/gdpr/erase
Permanently anonymizes a user's profile and deletes their associated personal data, including linked identities, passkeys, sessions, and pending email verifications, to satisfy a right-to-be-forgotten request. You cannot erase your own account or the last remaining account owner. Only an account owner can do this to an owner, and you cannot do it to a person who holds a permission you do not hold. An API key is never an owner.
Notes.
- Irreversible. Unlike POST /v1/users/:id/erase, the person does not have to be deactivated first.
Request body: application/json
| Field | Type | Required | Description |
|---|---|---|---|
userId | string | yes |
curl -X POST "https://api.brixsignage.com/v1/gdpr/erase" \
-H "Authorization: Bearer $BRIX_API_KEY" \
-H "Content-Type: application/json" Response 200: Success.
| Field | Type | Description |
|---|---|---|
data | object | |
data.userId | string | |
data.erased | 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, or in a franchise workspace, is not enough). Also owner_required or outranked: the person is an owner, or holds a permission you do not hold.
Response 404: No such person in this workspace.
Response 409: cant_erase_self or last_owner.
Response 422: userId is missing.
Response 5XX: Server error. The body carries a requestId to quote to support.
GET /v1/gdpr/export
Assembles a data subject access request export for the whole workspace: every person, screen and piece of content, and the last 365 days of the activity log, as one JSON file with secret values withheld. The key or person must have billing.export for the whole workspace. Each table is capped; complete is false when one was cut.
Notes.
- Exports the whole workspace, not one person: every person, screen and piece of content, and the last 365 days of the activity log.
- No { data } envelope: the body is the export file (Content-Disposition: attachment).
- Credentials are never exported: their columns are kept with null or a [secret; not exported] / [encrypted; not exported] marker.
curl "https://api.brixsignage.com/v1/gdpr/export" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
schemaVersion | 1 | |
generatedAt | string | ISO-8601 timestamp (UTC). |
subject | object | |
subject.spaceId | string | The workspace exported. |
subject.requestedByUserId | string | null | Null for an API key. |
limits | object | |
limits.perTable | integer | At most this many rows per table. |
limits.auditEvents | integer | At most this many activity log events. |
limits.auditWindowDays | integer | Activity log events from this many days back. |
truncated | object | The tables cut at the limit; empty when none. |
complete | boolean | False when a table was cut at the limit. |
tables | object | |
tables.workspace | object | null | The workspace record, every column (the Screen Lock PIN hash replaced by kioskHasGlobalPin inside prefs). |
tables.users | array of object | |
tables.users[].id | string | |
tables.users[].name | string | |
tables.users[].email | string | |
tables.users[].title | string | null | |
tables.users[].phone | string | null | |
tables.users[].status | string | |
tables.users[].lastLoginAt | string | null | |
tables.users[].emailVerifiedAt | string | null | |
tables.users[].createdAt | string | ISO-8601 timestamp (UTC). |
tables.users[].updatedAt | string | ISO-8601 timestamp (UTC). |
tables.users[].deletedAt | string | null | |
tables.screens | array of object | Every column; credentials withheld, and kioskHasCustomPin / kioskHasRecovery added. |
tables.media | array of object | |
tables.playlists | array of object | |
tables.schedules | array of object | |
tables.layouts | array of object | |
tables.creatives | array of object | |
tables.appInstances | array of object | |
tables.dataSources | array of object | config is [encrypted; not exported] (or null). |
tables.banners | array of object | |
tables.auditEvents | array of object | Newest first. |
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, or in a franchise workspace, is not enough).
Response 5XX: Server error. The body carries a requestId to quote to support.
POST /v1/gdpr/export
Same as the GET version of this operation: assembles a data subject access request export for the whole workspace as one JSON file, with secret values withheld. The key or person must have billing.export for the whole workspace. Takes no request body.
Notes.
- Exports the whole workspace, not one person: every person, screen and piece of content, and the last 365 days of the activity log.
- No { data } envelope: the body is the export file (Content-Disposition: attachment).
- Credentials are never exported: their columns are kept with null or a [secret; not exported] / [encrypted; not exported] marker.
- Takes no body; the same export as the GET.
curl -X POST "https://api.brixsignage.com/v1/gdpr/export" \
-H "Authorization: Bearer $BRIX_API_KEY" Response 200: Success.
| Field | Type | Description |
|---|---|---|
schemaVersion | 1 | |
generatedAt | string | ISO-8601 timestamp (UTC). |
subject | object | |
subject.spaceId | string | The workspace exported. |
subject.requestedByUserId | string | null | Null for an API key. |
limits | object | |
limits.perTable | integer | At most this many rows per table. |
limits.auditEvents | integer | At most this many activity log events. |
limits.auditWindowDays | integer | Activity log events from this many days back. |
truncated | object | The tables cut at the limit; empty when none. |
complete | boolean | False when a table was cut at the limit. |
tables | object | |
tables.workspace | object | null | The workspace record, every column (the Screen Lock PIN hash replaced by kioskHasGlobalPin inside prefs). |
tables.users | array of object | |
tables.users[].id | string | |
tables.users[].name | string | |
tables.users[].email | string | |
tables.users[].title | string | null | |
tables.users[].phone | string | null | |
tables.users[].status | string | |
tables.users[].lastLoginAt | string | null | |
tables.users[].emailVerifiedAt | string | null | |
tables.users[].createdAt | string | ISO-8601 timestamp (UTC). |
tables.users[].updatedAt | string | ISO-8601 timestamp (UTC). |
tables.users[].deletedAt | string | null | |
tables.screens | array of object | Every column; credentials withheld, and kioskHasCustomPin / kioskHasRecovery added. |
tables.media | array of object | |
tables.playlists | array of object | |
tables.schedules | array of object | |
tables.layouts | array of object | |
tables.creatives | array of object | |
tables.appInstances | array of object | |
tables.dataSources | array of object | config is [encrypted; not exported] (or null). |
tables.banners | array of object | |
tables.auditEvents | array of object | Newest first. |
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, or in a franchise workspace, is not enough).
Response 5XX: Server error. The body carries a requestId to quote to support.