The Device API is a RESTful pull API providing a paginated list of devices and their latest readings in JSON format from the Geoforce platform (app.geoforce.com).
The Device API serves a different purpose than the Asset API. While the Asset API returns asset-centric data (names, IDs, telemetry tied to assets), the Device API returns device-centric data — hardware identifiers, device status, firmware versions, battery health, reporting schedules, and configuration details.
Access
-
Access User Settings
- Log in at https://app.geoforce.com
- Click Setup in the left-hand menu
- Click the Users tab
- Click the user's email address
- Open the API INTEGRATIONS tab
-
Create a "Geoforce Core Services" API token
- Under New API Key, select Geoforce Core Services API from the dropdown
- Under Device API, select the necessary scope permission (
device_api:read) - Click Create Key
- Your JSON Web Token will be generated and added to the list of API Keys
- Click Show under the Key and Secret columns. This Key and Secret combo is required to obtain a Device API JWT Token (see below).
Data Included
- Device Identity: UUID, Device Number (ESN), Device Type (GT2h, GT2c, AT4, etc.)
- Device Status: Active, Inactive, Retired, Hibernate, and other lifecycle statuses
- Latest Readings: Coordinates (latitude/longitude), last reported timestamp
-
Battery Level: An estimation based on typical device operating conditions, available on GT and AT3 devices. The API returns the raw level:
Full(100%–80%),High(80%–60%),Medium(60%–40%),Fair(40%–20%),Replace(20%–0%). Note: the Geoforce application UI maps "Full", "High", and "Medium" to "Good", but the API returns the granular value. (viainclude) -
Battery Condition: Available on AT2 devices. Values: Good (battery is healthy), Replace (battery is dead). (via
include) -
Battery Metadata: Last reported timestamp, estimated remaining life (via
include) -
Configuration: Firmware version, cellular and satellite reporting schedules, configuration name, expected readings per day (via
include) -
Hardware: SKU, device model name, device identifiers such as IMEI, ICCID, Bluetooth MAC (via
include) -
Asset Assignment: Whether the device has an assigned asset, and the legacy asset ID (via
include) - Filtering: By device UUIDs, ESNs, device status, device types, battery levels, asset assignment, and last reported date range
Getting Started
- Generate a "Geoforce Core Services" API Key and Secret for a user in the Geoforce Platform (See "Access" above)
-
Obtain a Device API JWT Token (token expires in 1 hour)
- POST to the User-Org API endpoint, Username = Your Key, Password = Your Secret, and Scope =
device_api:read. Details in the User-Org API authentication documentation
- POST to the User-Org API endpoint, Username = Your Key, Password = Your Secret, and Scope =
-
Make a POST request to the Device API endpoint using this JWT Token:
POST https://api.geoforce.com/device/v1/query - Use the request body to refine data (e.g., device status, device types, date range)
- Determine pull frequency for your integration
Documentation
Please refer to Geoforce Device API Documentation
You can also download the raw OpenAPI spec: Download OpenAPI JSON
Best Practices for Pulling Data
-
No matches: When no devices match the filters, the API returns 200 with
data: []andtotal: 0. It does not return 404. -
Pagination: Use a moderate
perPagein production (e.g., 100–500) to balance throughput and response size. Maximum is 1000. - Request volume: Consider limiting concurrency and request rate to avoid overloading the API or your own client.
Elements of a Request
Query Parameter
account_id (number, optional)
- Account ID to query devices for. Optional when the token already encodes an account.
- Example:
?account_id=1759
Page and Sort
page (number, default: 1)
- Page number (1-indexed).
perPage (number, default: 20, max: 1000)
- Number of items per page.
orderBy (string, default: deviceNumber)
- Field to sort by. Allowed values:
deviceNumber,deviceType,deviceStatus,lastReportedAt(timestamp of the most recent reading).
order (string, default: asc)
- Sort direction:
ascordesc.
Filters (optional)
Filters let you limit which devices are returned.
ids (string[])
- Filter to specific device UUIDs.
deviceNumbers (string[])
- Filter by device ESN numbers.
deviceStatus (string[])
- Filter by device status. Allowed values:
activation as needed,active,active demo,active demo - paid,active demo - unpaid,active non-billable,active replacement,customer hold,deactivation pending,hibernate,inactive,prepaid,promo period,replacement pending,retired,suspend billing,warranty return.
deviceTypes (string[])
- Filter by device type (e.g.,
GT2h,GT2c,AT4).
hasAssignedAsset (boolean)
-
true: only devices with an asset assigned -
false: only devices without an asset - Omit: all devices
batteryLevels (string[])
- Filter by battery level (GT and AT3 devices only). Allowed values:
Good,Fair,Replace. Note: the filter uses the UI-collapsed values — "Good" matches devices whose API-returned level is Full, High, or Medium.
lastReportedAt (object)
- Filter by the time when the device last reported a reading. Provide from/to as ISO 8601.
- from (ISO 8601 date/time) — only include devices that reported after this time
- to (ISO 8601 date/time) — only include devices that reported before this time
Include (optional)
The include array specifies additional fields to return beyond the defaults. When omitted, only the default fields are returned: id, deviceNumber, accountId, deviceStatus, deviceType, latestReadings.
Available include values:
-
asset.id— Legacy asset ID from Track and Trace (returns null when no asset is assigned) -
hasAssignedAsset— Whether the device has an asset assigned -
firmwareVersion— Current firmware version (null when unknown) -
sku— Device SKU from the device model version -
deviceModelName— Device model name from the device model version -
lastLocation— Last reported coordinates -
hasBattery— Whether the device spec supports battery reporting -
hasBatteryLevel— Whether the device spec supports reporting battery level -
hasBatteryCondition— Whether the device spec supports reporting battery condition -
battery.level— Battery level estimation (GT and AT3 devices only). Possible values: "Full" (100%–80%), "High" (80%–60%), "Medium" (60%–40%), "Fair" (40%–20%), "Replace" (20%–0%), or null. Note: the Geoforce UI maps Full/High/Medium to "Good", but the API returns the granular value. -
battery.condition— Battery condition (AT2 devices only). Values: "Good" (healthy), "Replace" (dead), or null. -
battery.lastReportedAt— When battery was last reported (ISO 8601) -
battery.estimatedRemainingLife— Estimated battery end-of-life date (ISO 8601, null when insufficient data) -
cellularReportingSchedule— Human-readable cellular reporting schedule (null when no configuration deployed) -
satelliteReportingSchedule— Human-readable satellite reporting schedule (null when no configuration deployed) -
configurationName— Name of the deployed configuration (null when none deployed) -
expectedReadingsPerDay— Expected readings per day from configuration (null when none deployed) -
identifiers— Array of device identifiers (IMEI, ICCID, Bluetooth MAC, etc.)
Sample Request
Simple query
{
"page": 1,
"perPage": 20
}Filtered query
{
"page": 1,
"perPage": 50,
"orderBy": "lastReportedAt",
"order": "desc",
"filters": {
"deviceStatus": ["active"],
"deviceTypes": ["GT2h", "AT4"],
"hasAssignedAsset": true
}
}Query with additional fields
{
"page": 1,
"perPage": 50,
"filters": {
"deviceStatus": ["active"]
},
"include": [
"firmwareVersion",
"battery.level",
"battery.condition",
"hasAssignedAsset"
]
}Query with battery details
{
"page": 1,
"perPage": 100,
"include": [
"battery.level",
"battery.condition",
"hasBatteryLevel",
"hasBatteryCondition"
]
}
Elements of a Response
Pagination Fields
total (number)
- Total number of devices matching the query.
- Used for paging:
total / perPage = number of pages
page (number)
- Current page of results.
perPage (number, nullable)
- Items per page. Nullable when no pagination is applied.
allPages (number)
- Total number of pages available.
data
Contains the array of device objects. Each device includes the following fields:
Default Fields (always returned)
- id (string) — Device UUID
- deviceNumber (string) — Device ESN (e.g., "70001320")
- accountId (number) — Account ID
-
deviceStatus (string) — Device status. Possible values:
activation as needed,active,active demo,active demo - paid,active demo - unpaid,active non-billable,active replacement,customer hold,deactivation pending,hibernate,inactive,prepaid,promo period,replacement pending,retired,suspend billing,warranty return - deviceType (string) — Device type (GT2h, GT2c, AT4, etc.)
-
latestReadings (object) — Most recent reading from the device:
-
coordinates (object, nullable) — GPS position
- latitude (number)
- longitude (number)
- reportedAt (string, nullable) — ISO 8601 timestamp when this reading was reported
- lastLocationReportedAt (string, nullable) — When the last location was reported. Returns null when no location has been reported.
-
coordinates (object, nullable) — GPS position
Fields Returned via include
-
asset (object, nullable) — Returned when include contains
asset.id. Returns null when no asset is assigned.- id (number) — Legacy asset ID from the Track and Trace system
- hasAssignedAsset (boolean) — Whether the device has an asset assigned
- firmwareVersion (string, nullable) — Current firmware version (null when unknown)
- sku (string, nullable) — Device SKU from the device model version
- deviceModelName (string, nullable) — Device model name
-
lastLocation (object) — Last reported coordinates
- latitude (number)
- longitude (number)
- hasBattery (boolean) — Whether the device specification supports battery reporting
- hasBatteryLevel (boolean) — Whether the device spec supports reporting battery level
- hasBatteryCondition (boolean) — Whether the device spec supports reporting battery condition
-
battery (object) — Returned when any
battery.*include field is requested. Only requested fields are populated; others are omitted.- level (string, nullable) — Battery level estimation, available on GT and AT3 devices only. Possible values: "Full" (100%–80%), "High" (80%–60%), "Medium" (60%–40%), "Fair" (40%–20%), "Replace" (20%–0%), or null. Note: the Geoforce UI maps Full/High/Medium to "Good", but the API returns the granular value.
- condition (string, nullable) — Battery condition, available on AT2 devices only. Values: "Good" (battery is healthy), "Replace" (battery is dead), or null.
- lastReportedAt (string, nullable) — When battery was last reported (ISO 8601)
- estimatedRemainingLife (string, nullable) — Estimated battery end-of-life date (ISO 8601). Calculated from battery level percentage and reporting frequency. Returns null when insufficient data.
- cellularReportingSchedule (string, nullable) — Human-readable cellular reporting schedule (e.g., "Every 15 minutes")
- satelliteReportingSchedule (string, nullable) — Human-readable satellite reporting schedule (e.g., "Every 4 hours")
- configurationName (string, nullable) — Name of the deployed configuration
- expectedReadingsPerDay (number, nullable) — Expected readings per day from configuration
-
identifiers (array) — Array of device identifier objects:
- id (string) — Identifier UUID
-
identifierType (string) — Type of identifier:
bluetooth_mac,esn,imei_cellular,imei_satellite,simid_cellular_one,simid_cellular_two,wifi_mac - value (string) — Identifier value
- createdAt (string) — When the identifier was created (ISO 8601)
Sample Response
{
"total": 342,
"allPages": 7,
"page": 1,
"perPage": 50,
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"deviceNumber": "70001320",
"accountId": 1759,
"deviceStatus": "active",
"deviceType": "GT2h",
"latestReadings": {
"coordinates": {
"latitude": 30.2672,
"longitude": -97.7431
},
"reportedAt": "2024-06-15T14:30:00.000Z",
"lastLocationReportedAt": "2024-06-15T14:30:00.000Z"
},
"hasAssignedAsset": true,
"firmwareVersion": "1.2.3",
"battery": {
"level": "High",
"condition": "Good"
}
},
{
"id": "7b3d9f1a-2c4e-4a8b-b5d6-9e0f1a2b3c4d",
"deviceNumber": "70001321",
"accountId": 1759,
"deviceStatus": "active",
"deviceType": "AT4",
"latestReadings": {
"coordinates": null,
"reportedAt": null,
"lastLocationReportedAt": null
}
}
]
}Note: The second device in the example shows a case where no readings have been reported — coordinates, reportedAt, and lastLocationReportedAt are all null.
Error Handling
Below are common issues, their status codes, and returned messages.
Invalid device status value
Status Code: 400 Message: each value in filters.deviceStatus must be one of the following values: activation as needed, active, active demo, active demo - paid, ... The deviceStatus filter array contains an unsupported value.
perPage exceeds limit
Status Code: 400 Message: perPage must not be greater than 1000 The perPage parameter cannot exceed 1000.
Unsupported value in include array
Status Code: 400 Message: each value in include must be one of the following values: asset.id, hasAssignedAsset, firmwareVersion, sku, deviceModelName, lastLocation, hasBattery, hasBatteryLevel, hasBatteryCondition, battery.level, battery.condition, battery.lastReportedAt, battery.estimatedRemainingLife, cellularReportingSchedule, satelliteReportingSchedule, configurationName, expectedReadingsPerDay, identifiers Happens when an invalid field name is passed in include.
Invalid or expired access token
Status Code: 401 Message: Unauthorized The access token is missing, invalid, or expired.
Forbidden account
Status Code: 403 Message: Account 12345 is not visible to the authenticated user The user attempted to query devices for an account they do not have access to.
Comments
0 comments
Article is closed for comments.