Managing device records and identifiers
Register and manage GPS trackers, sensors, and other hardware devices.
A device in Business Data Repository represents a physical hardware unit: a GPS tracker, sensor, beacon, or any other piece of trackable hardware. Devices hold the identifying information, such as IMEI numbers and serial numbers, that connects physical hardware to the rest of your platform data. When linked to an asset through a DEVICE-type custom field, a device lets tracking data flow from the hardware into the platform. The link works in both directions: on the asset, primaryDevice returns the primary device and customFields returns every linked device, while on the device, the asset field returns the asset it belongs to.
This guide covers the full device lifecycle: looking up the required catalog records, registering a device, managing its identifiers, creating device relations, updating device properties, and decommissioning it.
Prerequisites
You need an access token for the workspace you work in. The API takes the workspace from the token, so no operation on this page asks for a workspace ID. See Authentication for how to get a token and how the API picks the workspace.
You also need IDs for two catalog records before you create a device:
Device type: one of the built-in types, such as GPS Tracker or Dashcam, or a type you create
Device model: the specific hardware model taken from the read-only model catalog
To check what device types already exist in your workspace, run this query:
query GetDeviceTypes {
bdr {
deviceTypes {
nodes { id title code }
}
}
}The platform provides nine built-in types, such as gps_tracker, obd_dongle, and ble_beacon, in every workspace. If none fits, create your own with a code that no built-in type uses:
mutation CreateDeviceType {
bdr {
deviceTypeCreate(input: {
title: "Trailer Sensor"
code: "trailer_sensor"
}) {
deviceType { id code }
}
}
}To look up a hardware model, query the read-only model catalog. You can filter by title or vendor:
If you want to browse models by manufacturer first, use the deviceVendors query to get vendor IDs, then filter deviceModels by them using filter.vendorIds.
Save the returned IDs. You'll need both to create a device.
How devices work
Device identifiers
A device can have zero or more hardware identifiers that connect the platform record to the physical hardware. Telematics servers and other systems use these identifiers to look up a device.
The available identifier types are defined by the DeviceIdType enum:
IMEI
15-digit International Mobile Equipment Identity
SERIAL_NUMBER
Manufacturer-assigned serial number
MAC_ADDRESS
Network interface MAC address
GUID
GUID/UUID identifier
MEID_HEX
Mobile Equipment Identifier, hexadecimal format
MEID_DEC
Mobile Equipment Identifier, decimal format
CUSTOM
Workspace-defined identifier
An identifier must be unique. Uniqueness is checked on the combination of type, value, and namespace, and the value comparison is case-insensitive. Leave namespace null for standard types (IMEI, SERIAL_NUMBER, MAC_ADDRESS, etc.) so the value is unique across the entire platform. The API doesn't enforce the rule. For CUSTOM identifiers, you can set a namespace string to limit where the value must be unique: two devices can share the same custom value as long as their namespaces differ. This is useful when integrating with external systems that have their own ID schemes and whose values may overlap.
Device status and properties
Devices don't support custom fields. The only properties you can change are title and modelId. Device status is controlled by the platform: every new device starts with the system status Not Activated. The platform provides four built-in statuses (Not Activated, Awaiting Connection, Active, Inactive) visible to all workspaces. You can create additional custom statuses with deviceStatusCreate, but status cannot be changed through the public API.
Asset link
The asset field returns the linked asset as a full Asset object, so you can query any of its fields directly, or null if the device isn't assigned to any asset. This is the same link seen from the device side: assets link to devices through custom fields of type DEVICE, and Device.asset follows that link back. The link is managed entirely from the asset side. See Creating assets and assigning devices for details.
Device relations
Two devices can be linked with a typed relation. Relation types are system-defined, so your workspace can't create new ones. There's one relation type, primary_secondary, with the title "Primary / Secondary". To get its ID, use the deviceRelationTypes query:
A relation has two endpoints: first and second. On the device the relation was created from (first), the relation appears in relationsFrom. On the device at the other end (second), the same relation appears in relationsTo. The first/second distinction only records the direction the relation was created in. The platform attaches no meaning to it, so your application decides what it means.
Example scenario: Onboarding a tracker shipment
FleetOps Ltd receives a shipment of Teltonika FMB003 GPS trackers for installation across their delivery fleet. This scenario walks through registering a device, recording its identifiers, linking it to a companion beacon, renaming it once installed, and decommissioning it at end of life.
Create a device
Register the first device using the type and model IDs from the prerequisites step
Run this mutation:
Identifiers are optional: a device may be registered before its hardware is known, and identifiers can be added later with deviceIdentifierAdd.
Response:
Save the id and version. You'll need both for later operations.
Add more identifiers
The IMEI was provided at creation. To register additional identifiers, such as a serial number, use deviceIdentifierAdd:
Response:
Both identifiers have namespace: null, so each value must be unique across the whole platform. Registering the same IMEI on another device returns a 409 DUPLICATE error.
To correct a mistakenly entered identifier, remove it using its id:
Assign device to an asset
FMB003 Unit 001 will track delivery truck DE-1049. To link the device, update the asset's DEVICE-type custom field. This example assumes the asset's type already has a custom field definition of the DEVICE type. See Defining and using custom fields for instructions on setting it up.
Response:
The code in set is the code of the DEVICE-type custom field defined on the asset type, not a fixed keyword. isPrimary is required on every DEVICE value, and setting it to true makes the device available through Asset.primaryDevice.
You can verify the link from the device side:
Each device can be linked to only one asset. Assigning a device that is already linked to a different asset fails with a validation error, unless you add reassign: true to the device value, which detaches it from the other asset and attaches it here in one step.
To unlink the device later without deleting it, use unset on the asset. That clears its primary status at the same time:
Create a device relation
FMB003 Unit 001 will be installed in the same vehicle as a Teltonika EYE beacon used for cargo monitoring. Link the two devices with a relation.
Start by looking up the available relation types for your workspace:
Then create the relation using the IDs of both devices and the relation type you want:
Response:
To remove the relation when the devices are separated, use deviceRelationRemove with the relation's id:
You now have a device record with several identifiers, assigned to an asset, related to a companion beacon, and renamed once installed.
Listing devices
To list all devices in a workspace:
Filtering
Use DeviceFilter to narrow down results. Conditions across different fields are combined with AND, while multiple values within a single field are combined with OR. For the full filter reference, see Filtering and sorting.
Common filter combinations:
DeviceFilter supports the following fields:
typeIds
One or more device type IDs
modelIds
One or more device model IDs
statusIds
One or more device status IDs
vendorIds
One or more manufacturer IDs
inventoryIds
One or more inventory IDs
titleContains
Partial, case-insensitive match on the device title
identifierContains
Partial, case-insensitive match on any identifier value
identifierContains is particularly useful for looking up a device by a partial IMEI or serial number:
Handling version conflicts
If you provide version in deviceUpdate or deviceDelete and the device has been modified by another request since your last fetch, the API returns a 409 CONFLICT error:
To resolve this, fetch the device again to get its current version and state, reconcile any differences with your intended changes, and retry the mutation with the updated version.
For a full explanation of how versioning works, see Optimistic locking.
Deleting a device
When a tracker reaches end of life and needs to be permanently removed, use deviceDelete. It hides the device from every query. Its identifiers stay reserved, so a new device can't reuse the same type, value and namespace.
deviceDelete doesn't close an active inventory assignment either. Unlink the device from its inventory first with deviceInventoryUnlink (see Managing device inventory), then delete it.
deviceDelete is refused with IN_USE while another device has a relation whose second is this device. extensions.blockers names those devices with the path relationsFrom. Remove the relations with deviceRelationRemove first. The relations that this device holds as first don't block the delete.
In a workspace that has IoT Logic, deviceDelete is also refused while a flow lists the device in its data source node. Every flow that isn't deleted counts, whether it's enabled or not. The blocker has entityType set to IOT_LOGIC_FLOW and path set to nodes.devices. Remove the device from the flow, or delete the flow, then delete the device.
Deleting a device automatically detaches it from every DEVICE-type custom field that points at it, on assets and geo objects alike, in the same transaction as the delete. The one exception is a required field: if any DEVICE field holding this device is isRequired, the delete is refused with IN_USE, and nothing is detached. extensions.blockers names the assets and geo objects with the path customFields.<code>. Put another device in the field, make the field not required, or delete the record that holds it. To put a replacement device in the field, update the asset's custom fields. The replacement must not be linked to another asset, unless you add reassign: true:
Then delete the device:
A device delete can fail because of a required DEVICE field on an entirely different entity. The IN_USE error names that entity and the field, so change the field there and retry.
See also
Devices: Complete reference for all device operations and types
Managing device inventory: Assign devices to inventories and track assignment history
Creating assets and assigning devices: Create and manage assets such as vehicles and equipment
Last updated
Was this helpful?