Assets
Este conteúdo não está disponível em sua língua ainda.
An asset is a physical device (phone, laptop, console, etc.) tracked across repair visits. Assets are keyed by serial number within a tenant. Each asset optionally links to a customer and exposes a small customer summary so you can render a device without a second call. Archived assets are excluded from list results by default.
The asset object
Section titled “The asset object”{ "object": "asset", "id": "4821", "serial_number": "C02XG2JHJGH5", "imei": null, "asset_tag": "R-0042", "make": "Apple", "model": "MacBook Pro 14\"", "device_type": "Laptop", "notes": "Customer reported random shutdowns", "status": "active", "customer_id": "109", "customer_email": "jane@example.com", "customer": { "object": "asset_customer", "id": "109", "name": "Jane Smith", "email": "jane@example.com" }, "first_seen_at": "2024-03-10T14:22:00Z", "last_seen_at": "2025-01-08T09:45:00Z", "archived_at": null, "created_at": "2024-03-10T14:22:00Z", "updated_at": "2025-01-08T09:45:00Z"}| Field | Type | Description |
|---|---|---|
id | string | Unique asset id |
serial_number | string|null | Device serial number (unique per tenant) |
imei | string|null | Device IMEI. Device identity internally is serial or IMEI, so both are readable here. Read-only via the API, captured at ticket intake |
asset_tag | string|null | Internal shop tag (e.g. a barcode label) |
make | string|null | Manufacturer (e.g. Apple, Samsung) |
model | string|null | Model name |
device_type | string|null | Category (e.g. Phone, Laptop, Game Console) |
notes | string|null | Free-text notes about the device |
status | string|null | active, archived, or written_off |
customer_id | string|null | Linked customer id |
customer_email | string|null | Customer email address stored on the asset row (used to match a customer at create time) |
customer | object|null | Small customer summary (id, name, email) or null (present only when the linked customer record loads) |
first_seen_at | string|null | ISO-8601 timestamp of the first repair intake |
last_seen_at | string|null | ISO-8601 timestamp of the most recent repair intake |
archived_at | string|null | ISO-8601 timestamp when the asset was archived, or null |
created_at | string|null | ISO-8601 creation timestamp |
updated_at | string|null | ISO-8601 last-update timestamp |
List assets
Section titled “List assets”GET /api/v1/assetsReturns a cursor-paginated list of assets, newest first. Archived assets are hidden by default.
Scope required: assets.read
Query parameters
Section titled “Query parameters”| Parameter | Type | Description |
|---|---|---|
customer_id | string | Filter to a single customer’s devices |
status | string | Filter by status (active, archived, written_off) |
device_type | string | Filter by device type |
q | string | Full-text search across serial number, IMEI, asset tag, make, and model |
updated_since | string | Only assets updated at or after this time (ISO-8601 or Unix timestamp in seconds/milliseconds) |
include_archived | boolean | Set to true to include archived assets (default false). Accepted values: true/false/1/0/yes/no. Any other value returns 400 invalid_filter |
limit | integer | Page size, 1–100 (default 25) |
cursor | string | Opaque cursor from a previous response |
curl "https://app.benchkey.com/api/v1/assets?limit=10&q=macbook" \ -H "Authorization: Bearer bk_live_<tenantId>_<secret>"Node.js
Section titled “Node.js”const res = await fetch( "https://app.benchkey.com/api/v1/assets?limit=10&q=macbook", { headers: { Authorization: "Bearer bk_live_<tenantId>_<secret>" } });const { data, has_more, next_cursor } = await res.json();console.log(`Got ${data.length} assets, has_more=${has_more}`);Response
Section titled “Response”{ "object": "list", "data": [ { "object": "asset", "id": "4821", "serial_number": "C02XG2JHJGH5", "make": "Apple", "model": "MacBook Pro 14\"", "status": "active", "customer_id": "109", "customer": { "object": "asset_customer", "id": "109", "name": "Jane Smith", "email": "jane@example.com" }, "created_at": "2024-03-10T14:22:00Z", "updated_at": "2025-01-08T09:45:00Z" } ], "has_more": false, "next_cursor": null}Retrieve an asset
Section titled “Retrieve an asset”GET /api/v1/assets/:idFetch a single asset by its numeric id.
Scope required: assets.read
curl https://app.benchkey.com/api/v1/assets/4821 \ -H "Authorization: Bearer bk_live_<tenantId>_<secret>"Node.js
Section titled “Node.js”const res = await fetch("https://app.benchkey.com/api/v1/assets/4821", { headers: { Authorization: "Bearer bk_live_<tenantId>_<secret>" },});const asset = await res.json();console.log(asset.serial_number); // "C02XG2JHJGH5"Response
Section titled “Response”Returns a single asset object. Returns 404 if no asset with that id exists.
Archived assets return 404 by default.
GET /:idapplies the same visibility filter as the list: archived assets are hidden unless you pass?include_archived=true. Pass a typo’d value (e.g.include_archived=ture) and the endpoint returns400 invalid_filterrather than silently using the default.
Register an asset
Section titled “Register an asset”POST /api/v1/assetsCreates a new asset and links it to a customer. You must supply at least one of customer_id or customer_email to identify the owning customer, plus serial_number. Returns 409 if the serial number is already registered for the tenant.
Scope required: assets.write
Request body
Section titled “Request body”| Field | Type | Required | Description |
|---|---|---|---|
serial_number | string | Yes | Device serial number, must be unique per tenant |
customer_id | string | One of customer_id/customer_email | Link to an existing customer by id, must be a positive integer and the customer must exist; an unknown id returns 400 invalid_field |
customer_email | string | One of customer_id/customer_email | Match a customer by email if customer_id is not known, must be a valid email address (user@domain.tld); malformed values return 400 invalid_field |
asset_tag | string | No | Internal barcode/label |
make | string | No | Manufacturer |
model | string | No | Model name |
device_type | string | No | Device category |
notes | string | No | Free-text notes |
curl -X POST https://app.benchkey.com/api/v1/assets \ -H "Authorization: Bearer bk_live_<tenantId>_<secret>" \ -H "Content-Type: application/json" \ -d '{ "customer_id": "109", "serial_number": "C02XG2JHJGH5", "make": "Apple", "model": "MacBook Pro 14\"", "device_type": "Laptop" }'Node.js
Section titled “Node.js”const res = await fetch("https://app.benchkey.com/api/v1/assets", { method: "POST", headers: { Authorization: "Bearer bk_live_<tenantId>_<secret>", "Content-Type": "application/json", }, body: JSON.stringify({ customer_id: "109", serial_number: "C02XG2JHJGH5", make: "Apple", model: 'MacBook Pro 14"', device_type: "Laptop", }),});const asset = await res.json();console.log(asset.id); // "4821"Response
Section titled “Response”201 Created with the new asset object. The Location header points to the created resource.
Update an asset
Section titled “Update an asset”PATCH /api/v1/assets/:idUpdates one or more mutable fields on an asset. At least one field must be supplied. Returns the re-read asset object.
Transitioning status to archived or written_off automatically stamps archived_at; transitioning back to active clears it.
Scope required: assets.write
Writable fields
Section titled “Writable fields”| Field | Type | Notes |
|---|---|---|
asset_tag | string | Internal label |
make | string | Manufacturer |
model | string | Model name |
device_type | string | Device category |
serial_number | string | Must remain unique per tenant |
notes | string | Free-text notes |
status | string | active, archived, or written_off |
curl -X PATCH https://app.benchkey.com/api/v1/assets/4821 \ -H "Authorization: Bearer bk_live_<tenantId>_<secret>" \ -H "Content-Type: application/json" \ -d '{"status": "archived", "notes": "Beyond economic repair"}'Node.js
Section titled “Node.js”const res = await fetch("https://app.benchkey.com/api/v1/assets/4821", { method: "PATCH", headers: { Authorization: "Bearer bk_live_<tenantId>_<secret>", "Content-Type": "application/json", }, body: JSON.stringify({ status: "archived", notes: "Beyond economic repair" }),});const asset = await res.json();console.log(asset.archived_at); // "2025-06-14T12:00:00Z"Response
Section titled “Response”Returns the updated asset object.
Error codes
Section titled “Error codes”| HTTP status | Code | Meaning |
|---|---|---|
400 | invalid_id | The :id path segment is not a valid integer |
400 | missing_customer | Neither customer_id nor customer_email was supplied (a blank or whitespace-only customer_id also counts as absent) |
400 | missing_field | serial_number is required but was not provided |
400 | invalid_field | A field value is the wrong type, serial_number is blank, customer_email is not a valid email address, or customer_id does not match any customer in this tenant |
400 | invalid_query | A list filter parameter (including updated_since) was supplied as an array or object instead of a single scalar string |
400 | invalid_filter | updated_since is not a parseable date/timestamp, or include_archived is not a recognized boolean (true/false/1/0/yes/no) |
400 | no_fields | PATCH body contained no writable fields |
400 | invalid_request | The backend rejected the request (invalid input from the internal route) |
401 | unauthorized | Missing or invalid API key |
403 | insufficient_scope | API key lacks assets.read or assets.write scope |
404 | not_found | No asset with that id in this tenant |
409 | serial_conflict | That serial number is already registered for this tenant |
422 | create_failed | The asset could not be created |
422 | unprocessable | The write operation could not be processed (fallback) |
422 | write_failed | The asset operation could not be completed (update or delete) |