Devices Domain
The Devices domain provides endpoints for querying devices registered within a client organization. Devices are machines running the desktop agent. They are identified by a stable id and may be associated with one or more users over time via the user_devices junction table.
For embedding and endpoint design decisions, see the Design Guidelines.
Endpoints
| Endpoint | Method | Description |
|---|---|---|
| List Devices | GET | Paginated list of devices. Use for inventory tables and search. |
| Get Device | GET | Fetch a single device directly by ID. |
| Device Summary | GET | Fleet-level aggregate stats: total count, agent versions, deployment errors. |
| Device Users | GET | Users observed on a specific device. |
| Device Deployments | GET | Enrollment deployment history for a device. |
Getting Devices by User
To retrieve devices used by a specific user, use the List Devices endpoint with the user_id filter:
GET /clients/{client_id}/devices?user_id=a1d97031-04e2-4907-a249-093f7436207b
Devices are not embedded in user responses because a user can use many devices over time -- an unbounded, paginated relationship. See Why devices are not embedded below.
Data Transfer Objects (DTOs)
DeviceRef
Minimal device reference for embedding inside other domain responses (e.g. as a cross-domain link). Contains only fields available directly from the devices table that are useful in a reference context. No joins required.
{
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"name": "DESKTOP-DEV-ALICE",
"status": "active",
"os_name": "Windows",
"os_version": "10.0.19045",
"last_seen_at": "2026-02-24T21:23:53.082Z"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string (uuid) | No | Stable unique identifier for the device |
name | string | Yes | Device hostname or friendly name |
status | string | Yes | Last known device status: active, inactive, pending |
os_name | string | Yes | Operating system name (e.g. Windows, macOS, Linux) |
os_version | string | Yes | Operating system version string |
last_seen_at | string (ISO 8601) | Yes | When the device last sent a heartbeat |
DB source: devices.id, devices.name, devices.status, devices.os_name, devices.os_version, devices.last_seen_at_utc
Used in: Any domain response that references a device as a non-primary resource.
Device
Full device representation returned by device-primary endpoints. Extends DeviceRef with hardware specs, browser extension versions, agent info, and audit timestamps.
{
"id": "f1e2d3c4-b5a6-7890-abcd-ef1234567890",
"name": "DESKTOP-DEV-ALICE",
"status": "active",
"serial_number": "5CG1234567",
"unique_key": "DESKTOP-DEV-ALICE-HWID-5CG1234567",
"os_name": "Windows",
"os_version": "10.0.19045",
"last_seen_at": "2026-02-24T21:23:53.082Z",
"installed_at": "2025-11-01T08:00:00.000Z",
"agent_version": "1.2.3",
"hardware": {
"manufacturer": "Dell Inc.",
"model": "XPS 15 9520",
"cpu_model": "Intel(R) Core(TM) i7-12700H",
"cpu_cores": 8,
"ram": 17179869184
},
"extensions": {
"chrome": {
"version": "1.11.0",
"installed": true,
"auto_update": true,
"last_activity_at": "2026-02-24T21:23:53.082Z"
},
"edge": {
"version": "1.11.0",
"installed": true,
"auto_update": false,
"last_activity_at": "2026-02-24T21:22:00.000Z"
},
"firefox": {
"version": null,
"installed": false,
"auto_update": false,
"last_activity_at": null
}
},
"created_at": "2025-11-01T08:00:00.000Z",
"updated_at": "2026-02-24T21:23:53.082Z"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
All DeviceRef fields | id, name, status, os_name, os_version, last_seen_at -- see DeviceRef | ||
serial_number | string | Yes | Device serial number reported by the agent |
unique_key | string | Yes | Unique hardware fingerprint used to identify the device |
installed_at | string (ISO 8601) | Yes | When the agent was first installed on this device |
agent_version | string | Yes | Currently installed agent version |
hardware | object | No | Hardware specifications |
hardware.manufacturer | string | Yes | Device manufacturer (e.g. Dell Inc., Apple Inc.) |
hardware.model | string | Yes | Device model name |
hardware.cpu_model | string | Yes | CPU model string |
hardware.cpu_cores | integer | Yes | Number of CPU cores |
hardware.ram | integer | Yes | Total RAM in bytes |
extensions | object | No | Browser extension installation status |
extensions.chrome | object | No | Chrome extension details |
extensions.edge | object | No | Edge extension details |
extensions.firefox | object | No | Firefox extension details |
extensions.{browser}.version | string | Yes | Installed extension version. null if not installed. |
extensions.{browser}.installed | boolean | No | Whether the extension is installed |
extensions.{browser}.auto_update | boolean | No | Whether the extension is set to auto-update |
extensions.{browser}.last_activity_at | string (ISO 8601) | Yes | Last activity timestamp for this extension |
created_at | string (ISO 8601) | No | When this device record was first created |
updated_at | string (ISO 8601) | No | When this device record was last modified |
DB source:
| DTO Field | DB Column |
|---|---|
| (DeviceRef fields) | see DeviceRef |
serial_number | devices.serial_number |
unique_key | devices.unique_key |
installed_at | devices.installed_at_utc |
agent_version | devices.agent_version |
hardware.manufacturer | devices.manufacturer |
hardware.model | devices.model |
hardware.cpu_model | devices.cpu_model |
hardware.cpu_cores | devices.cpu_cores |
hardware.ram | devices.ram |
extensions.chrome.version | devices.chrome_extension_version |
extensions.chrome.installed | devices.chrome_extension_installed |
extensions.chrome.auto_update | devices.chrome_extension_auto_update |
extensions.chrome.last_activity_at | devices.last_chrome_activity_utc |
extensions.edge.version | devices.edge_extension_version |
extensions.edge.installed | devices.edge_extension_installed |
extensions.edge.auto_update | devices.edge_extension_auto_update |
extensions.edge.last_activity_at | devices.last_edge_activity_utc |
extensions.firefox.version | devices.firefox_extension_version |
extensions.firefox.installed | devices.firefox_extension_installed |
extensions.firefox.auto_update | devices.firefox_extension_auto_update |
extensions.firefox.last_activity_at | devices.last_firefox_activity_utc |
created_at | devices.created_at |
updated_at | devices.updated_at |
Omitted internal fields: client_id (in URL path), partner_id, created_by, updated_by, cpu_avg_percent, cpu_min_percent, cpu_max_percent, ram_avg_mb, ram_min_mb, ram_max_mb, resource_recorded_at_utc (metrics -- not device identity)
Used in: Get Device, List Devices
DeviceUserRef
A user observed on a device, returned by Device Users. Wraps UserRef with the junction-level last_seen_at from user_devices.
The user identity fields (UserRef) come from the users table. The enrolled_at and last_seen_at fields come from the user_devices junction table and are specific to this device-user pairing.
{
"id": "a1d97031-04e2-4907-a249-093f7436207b",
"username": "mikechang",
"user_key": "mikechang",
"last_activity": {
"at": "2026-02-24T21:23:53.082Z",
"desktop_at": "2026-02-22T08:00:00.000Z",
"web_at": "2026-02-24T21:23:53.082Z"
},
"enrolled_at": "2025-11-01T08:00:00.000Z",
"last_seen_at": "2026-02-24T21:23:53.082Z"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
All UserRef fields | id, username, user_key, last_activity -- see UserRef | ||
enrolled_at | string (ISO 8601) | No | When this user was first associated with this device |
last_seen_at | string (ISO 8601) | Yes | When this user was last seen on this device |
DB source:
| DTO Field | DB Column |
|---|---|
| (UserRef fields) | see UserRef |
enrolled_at | user_devices.created_at |
last_seen_at | user_devices.last_seen_at_utc |
Used in: Device Users
DeviceDeploymentRef
Minimal deployment reference for list views. Represents a single enrollment deployment event for a device.
{
"id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
"status": "success",
"enrollment_date": "2026-01-30T14:30:00.000Z"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
id | string (uuid) | No | Unique deployment event identifier |
status | string | Yes | Deployment status: success, error, pending |
enrollment_date | string (ISO 8601) | Yes | When the device was enrolled via this deployment |
DB source: device_deployments.id, device_deployments.status, device_deployments.enrollment_date
Used in: Deployment list endpoint
DeviceDeployment
Full deployment record returned by the deployment detail endpoint. Extends DeviceDeploymentRef with the enrollment token reference, error logs, and audit timestamps.
{
"id": "d1e2f3a4-b5c6-7890-abcd-ef1234567890",
"status": "error",
"enrollment_date": "2026-01-30T14:30:00.000Z",
"enrollment_token_id": "e1f2a3b4-c5d6-7890-abcd-ef1234567890",
"user_id": "a1d97031-04e2-4907-a249-093f7436207b",
"error_logs": [
"2026-01-30T14:30:05Z: Downloading agent package...",
"2026-01-30T14:30:15Z: Installation failed - insufficient permissions",
"2026-01-30T14:30:15Z: Deployment aborted"
],
"created_at": "2026-01-30T14:30:00.000Z",
"updated_at": "2026-01-30T14:30:15.000Z"
}
| Field | Type | Nullable | Description |
|---|---|---|---|
All DeviceDeploymentRef fields | id, status, enrollment_date -- see DeviceDeploymentRef | ||
enrollment_token_id | string (uuid) | No | The enrollment token used for this deployment |
user_id | string (uuid) | Yes | The user associated with this deployment |
error_logs | string[] | Yes | Deployment log entries (chronological). null or empty for successful deployments. |
created_at | string (ISO 8601) | No | When this deployment record was created |
updated_at | string (ISO 8601) | No | When this deployment record was last modified |
DB source:
| DTO Field | DB Column |
|---|---|
| (DeviceDeploymentRef fields) | see DeviceDeploymentRef |
enrollment_token_id | device_deployments.enrollment_token_id |
user_id | device_deployments.user_id |
error_logs | device_deployments.error_logs |
created_at | device_deployments.created_at |
updated_at | device_deployments.updated_at |
Omitted internal fields: device_id (in URL path), created_by, updated_by
Used in: Deployment detail endpoint
Why devices are not embedded
User does not include a devices array. This is intentional:
| Relationship | Cardinality | Strategy | Reason |
|---|---|---|---|
| User → Devices | 1:many (unbounded) | GET /devices?user_id= | Unbounded, needs pagination |
| Device → Users | 1:many (usually 1–3) | GET /devices/{id}/users | Sub-resource with junction context |
The device-to-user relationship uses a sub-resource endpoint (/devices/{id}/users) rather than a filter because it is device-primary -- the device is the subject. The user-to-device direction uses the filter pattern (/devices?user_id=) to stay consistent with V2's filter-based cross-resource queries.
To get devices for a user:
GET /clients/{client_id}/devices?user_id=a1d97031-04e2-4907-a249-093f7436207b