# Device preassignments

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

## GET /v1/device-preassignments

List pre-assigned devices

List devices pre-assigned to locations in your workspace. Each entry shows the end of the device serial number, the location, the screen name, and whether the device is still waiting to be claimed or has already been claimed. Results are limited to the organization nodes you can see.

**Notes.**
- Carries `available` beside `data`.

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

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

Response 200: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | array of object |  |
| `data[].id` | string |  |
| `data[].serialHint` | string \| null | The last 4 characters of the serial. The full serial is not stored. |
| `data[].nodeId` | string |  |
| `data[].locationName` | string \| null |  |
| `data[].locationId` | string \| null | The location's own id (its Location ID), when set. |
| `data[].name` | string \| null |  |
| `data[].status` | "waiting" \| "claimed" |  |
| `data[].claimedAt` | string \| null |  |
| `data[].claimedScreenId` | string \| null |  |
| `data[].createdAt` | string | ISO-8601 timestamp (UTC). |
| `available` | boolean | False when the workspace's data region does not support pre-assignment yet (`data` is then empty). |

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

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

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

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

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

## POST /v1/device-preassignments

Pre-assign devices to locations

Pre-assign device serial numbers to locations, identified by Location ID or `nodeId`, so each device pairs automatically into its assigned location the first time it is plugged in. Submit up to 1000 rows in one request; all rows are validated before any are saved. Re-uploading the same rows is safe and does not create duplicates, and `dryRun` validates rows without saving them. A serial number already assigned to another workspace is refused with a conflict error, and the action is recorded in the activity log.

Auth: Bearer token. Permission: `screen.create`.

Request body (`application/json`):

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `rows` | array of object | yes |  |
| `rows[].serial` | string | yes | The device serial number. |
| `rows[].locationId` | string | no | The location's Location ID (case-insensitive). Give this or `nodeId`. |
| `rows[].nodeId` | string | no |  |
| `rows[].name` | string | no | Screen name; default: the location name and the serial's last 4 characters. |
| `dryRun` | boolean | no | True: check and report, change nothing (answers 200). |

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

Response 200: Success: a dry run (`dryRun: true`): the same report, nothing changed.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.dryRun` | boolean |  |
| `data.counts` | object |  |
| `data.counts.claimed` | integer |  |
| `data.counts.created` | integer |  |
| `data.counts.updated` | integer |  |
| `data.counts.unchanged` | integer |  |
| `data.rows` | array of object |  |
| `data.rows[].index` | integer |  |
| `data.rows[].serial` | string | The serial's last 4 characters. |
| `data.rows[].outcome` | "claimed" \| "created" \| "updated" \| "unchanged" |  |
| `data.rows[].nodeId` | string |  |
| `data.rows[].locationName` | string |  |
| `data.rows[].locationId` | string \| null |  |
| `data.rows[].name` | string |  |

Response 201: Success.

| Field | Type | Description |
| --- | --- | --- |
| `data` | object |  |
| `data.dryRun` | boolean |  |
| `data.counts` | object |  |
| `data.counts.claimed` | integer |  |
| `data.counts.created` | integer |  |
| `data.counts.updated` | integer |  |
| `data.counts.unchanged` | integer |  |
| `data.rows` | array of object |  |
| `data.rows[].index` | integer |  |
| `data.rows[].serial` | string | The serial's last 4 characters. |
| `data.rows[].outcome` | "claimed" \| "created" \| "updated" \| "unchanged" |  |
| `data.rows[].nodeId` | string |  |
| `data.rows[].locationName` | string |  |
| `data.rows[].locationId` | string \| null |  |
| `data.rows[].name` | string |  |

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

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

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 409: A serial is held by another workspace, or the data region does not support pre-assignment.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

Response 422: No rows, too many rows, or a row is invalid; `data.errors` lists each by `index` and `code`.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

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

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

## DELETE /v1/device-preassignments/{id}

Cancel a device pre-assignment

Cancel a pending device pre-assignment. If the device has already been claimed and turned into a screen, that screen is not affected. The action is recorded in the activity log.

Auth: Bearer token. Permission: `screen.create`.

Parameters:

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `id` | path | string | yes | Pre-assignment id. |

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

Response 200: Success.

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

Response 401: Missing, expired or revoked bearer token.

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

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

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |

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

| Field | Type | Description |
| --- | --- | --- |
| `error` | string | Machine-readable code: `unauthorized`, `forbidden`, `not_found`, `validation_error`, `conflict`, `rate_limited`, `internal_error`, … |
| `message` | string | Human-readable explanation. Safe to show an operator. |
| `requestId` | string | Present on 5xx: quote it to support. |
