{"openapi":"3.0.0","paths":{"/v1/query":{"post":{"description":"Returns a paginated list of devices matching the specified filters. Uses POST to support complex filter criteria in the request body.","operationId":"DeviceController_queryDevices[1]_v1","parameters":[{"name":"account_id","required":false,"in":"query","description":"Account ID to query devices for. Optional when the token already encodes an account.","schema":{"example":1759,"type":"number"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DeviceQuery"},"examples":{"simple":{"summary":"Simple query","value":{"page":1,"perPage":20},"description":"Basic paginated query with default sorting"},"filtered":{"summary":"Filtered query","value":{"page":1,"perPage":50,"orderBy":"lastReportedAt","order":"desc","filters":{"deviceStatus":["active"],"deviceTypes":["GT2h","AT4"],"hasAssignedAsset":true}},"description":"Query with filters and custom sorting"},"queryWithIncludes":{"summary":"Query with additional fields","description":"Query requesting additional fields beyond the defaults. Available include values: asset.id, hasAssignedAsset, firmwareVersion, sku, deviceModelName, lastLocation, hasBattery, hasBatteryLevel, hasBatteryCondition, battery.level, battery.condition, battery.lastReportedAt, battery.estimatedRemainingLife, cellularReportingSchedule, satelliteReportingSchedule, configurationName, expectedReadingsPerDay, identifiers","value":{"page":1,"perPage":50,"filters":{"deviceStatus":["active"]},"include":["firmwareVersion","battery.level","battery.condition","hasAssignedAsset"]}},"queryWithAsset":{"summary":"Query with asset info","description":"Query including asset assignment information","value":{"page":1,"perPage":50,"include":["asset.id","hasAssignedAsset"]}},"queryWithBattery":{"summary":"Query with battery details","description":"Query including battery level and condition from device readings, plus device specification battery capabilities","value":{"page":1,"perPage":100,"include":["battery.level","battery.condition","hasBatteryLevel","hasBatteryCondition"]}}}}}},"responses":{"200":{"description":"Devices retrieved successfully. When no devices match, returns 200 with data: [] and total: 0.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/DevicesResponse"}}}},"400":{"description":"Invalid request parameters","content":{"application/json":{"example":{"statusCode":400,"message":["each value in filters.deviceStatus must be one of the following 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","perPage must not be greater than 1000","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"],"error":"Bad Request"}}}},"401":{"description":"Unauthorized - Invalid or missing access token","content":{"application/json":{"example":{"statusCode":401,"message":"Unauthorized","error":"Unauthorized"}}}},"403":{"description":"Forbidden - Account not visible to user","content":{"application/json":{"example":{"statusCode":403,"message":"Account 12345 is not visible to the authenticated user","error":"Forbidden"}}}}},"security":[{"access-token":[]}],"summary":"Query devices","tags":["Devices"]}}},"info":{"title":"Device API","description":"[Download OpenAPI JSON](https://api.geoforce.com/device/docs-json)\n\n**Note:** The legacy hostname `device.api.geoforce.com` is not recommended for new implementations and will be obsoleted by the end of 2027. New integrations should use the gateway URL (`https://api.geoforce.com/device`).\n\n### Authentication\n\nTo obtain an access token for this API, please follow the instructions in the [User-Org API authentication documentation](https://org.api.geoforce.com/docs/auth).\n\nThen click **Authorize** below and enter the access token to try the endpoints.\n\n### Best practices for pulling data\n\n- **No matches:** When no devices match the filters, the API returns **200** with `data: []` and `total: 0` (see the \"No matches\" response example). It does not return 404.\n\n- **Pagination:** Use a moderate `perPage` in production (e.g. 100–500) to balance throughput and response size.\n\n- **Request volume:** Consider limiting concurrency and request rate to avoid overloading the API or your own client.\n\n","version":"1.0","contact":{}},"tags":[],"servers":[{"url":"https://api.geoforce.com/device","description":"This environment"}],"components":{"securitySchemes":{"access-token":{"scheme":"bearer","bearerFormat":"JWT","type":"http"}},"schemas":{"DeviceQuery":{"type":"object","properties":{"page":{"type":"number","description":"Page number (1-indexed)","default":1,"minimum":1,"example":1},"perPage":{"type":"number","description":"Number of items per page.","default":20,"minimum":1,"maximum":1000,"example":50},"orderBy":{"type":"string","enum":["deviceNumber","deviceType","deviceStatus","lastReportedAt"],"default":"deviceNumber","example":"deviceNumber","description":"Field to sort the result list by. Allowed values: deviceNumber, deviceType, deviceStatus, lastReportedAt (timestamp of the most recent reading)."},"order":{"type":"string","description":"Sort order for the orderBy field: asc or desc.","enum":["asc","desc"],"default":"asc","example":"asc"},"filters":{"$ref":"#/components/schemas/DeviceFilters"},"include":{"type":"array","description":"Specifies additional fields to include in the response. When omitted, only the default fields are returned (id, deviceNumber, accountId, deviceStatus, deviceType, latestReadings).","example":["firmwareVersion","batteryLevel","hasAssignedAsset","configurationName"],"items":{"type":"string","enum":["asset.id","hasAssignedAsset","firmwareVersion","sku","deviceModelName","lastLocation","hasBattery","hasBatteryLevel","hasBatteryCondition","battery.level","battery.condition","battery.lastReportedAt","battery.estimatedRemainingLife","cellularReportingSchedule","satelliteReportingSchedule","configurationName","expectedReadingsPerDay","identifiers","latestReadings.locationSource","latestReadings.locationMethod","latestReadings.locationAccuracy"]}}}},"DevicesResponse":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/Device"}},"total":{"type":"number","description":"Total matching records","example":1},"page":{"type":"number","description":"Current page","example":1},"perPage":{"type":"number","description":"Items per page.","nullable":true},"allPages":{"type":"number","description":"Total pages","example":1},"filterCounts":{"$ref":"#/components/schemas/FilterCounts"}},"description":"Paginated list of devices. data contains the devices for the current page.","required":["data","total","page","perPage","allPages"]},"DateRange":{"type":"object","properties":{"from":{"type":"string","description":"Start date (ISO 8601)","example":"2024-01-01T00:00:00Z"},"to":{"type":"string","description":"End date (ISO 8601)","example":"2024-12-31T23:59:59Z"}},"description":"Filter by the time when the device last reported. Uses the timestamp of the device's most recent reading (e.g. location). Provide from/to as ISO 8601."},"DeviceFilters":{"type":"object","properties":{"ids":{"description":"Filter to specific device UUIDs","example":["550e8400-e29b-41d4-a716-446655440000"],"type":"array","items":{"type":"string"}},"deviceNumbers":{"description":"Filter by device ESN numbers","example":["70001320","70001321"],"type":"array","items":{"type":"string"}},"deviceStatus":{"type":"array","description":"Filter by device status. Allowed values: active, inactive, active demo, retired, etc. (same values as in the response deviceStatus field).","example":["active"],"items":{"type":"string","enum":["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":{"description":"Device types (GT2h, GT2c, AT4, etc.)","example":["GT2h","AT4"],"type":"array","items":{"type":"string"}},"hasAssignedAsset":{"type":"boolean","description":"Filter by asset assignment","example":true},"batteryLevels":{"type":"array","description":"Filter by battery level. Allowed values: Full, High, Medium, Fair, Replace.","example":["Full","Medium","Fair"],"items":{"type":"string","enum":["Full","High","Medium","Fair","Replace"]}},"lastReportedAt":{"$ref":"#/components/schemas/DateRange"}},"description":"Filter criteria for devices (e.g. ids, deviceNumbers, deviceStatus, deviceTypes, lastReportedAt range)."},"Coordinates":{"type":"object","properties":{"latitude":{"type":"number","description":"Latitude of the device's latest reported location.","example":30.2672},"longitude":{"type":"number","description":"Longitude of the device's latest reported location.","example":-97.7431}},"description":"Latitude and longitude of a location (e.g. device's latest reported position).","required":["latitude","longitude"]},"LatestReadings":{"type":"object","properties":{"coordinates":{"$ref":"#/components/schemas/Coordinates"},"reportedAt":{"type":"string","description":"ISO 8601 timestamp when this latest reading (e.g. location) was reported by the device.","example":"2024-06-15T14:30:00.000Z"},"lastLocationReportedAt":{"type":"string","description":"When the last location was reported (ISO 8601 datetime). Returns null when no location has been reported.","example":"2024-06-15T14:30:00.000Z"},"locationSource":{"type":"string","description":"Communication network used to resolve the device location. Only returned when include contains \"latestReadings.locationSource\". Null for readings ingested before this field was rolled out.","enum":["satellite","cellular","bluetooth"],"example":"cellular","nullable":true},"locationMethod":{"type":"string","description":"Positioning method used to determine the device coordinates. Only returned when include contains \"latestReadings.locationMethod\". Null for readings ingested before this field was rolled out.","enum":["gps","wifi","wifi+cell-tower","wifi_fallback","cell-tower","bluetooth"],"example":"wifi","nullable":true},"locationAccuracy":{"type":"number","description":"Estimated radius of the device location in meters, as returned by the Wi-Fi geolocation provider. Only returned when include contains \"latestReadings.locationAccuracy\". Only present for Wi-Fi-based positioning (cellular+wifi and cellular+wifi_fallback); null for all other source/method combinations and for pre-launch readings.","example":23.41,"nullable":true}},"description":"Most recent reading from the device: location (if available) and the time that reading was reported."},"DeviceAsset":{"type":"object","properties":{"id":{"type":"number","description":"Legacy asset ID from the Track and Trace system","example":376860}},"description":"Associated asset information. Returns null when no asset is assigned. Only returned when include contains \"asset.id\".","required":["id"]},"Battery":{"type":"object","properties":{"level":{"type":"string","description":"Current battery level label. Possible values: \"Full\", \"High\", \"Medium\", \"Fair\", \"Replace\", or null when not available.","example":"High"},"condition":{"type":"string","description":"Current battery condition. Possible values: \"Normal\", \"Fault\", or null when not available.","example":"Normal"},"lastReportedAt":{"type":"string","description":"When the battery was last reported (ISO 8601 datetime).","example":"2024-06-15T14:30:00.000Z"},"estimatedRemainingLife":{"type":"string","description":"Estimated battery end-of-life date (ISO 8601 datetime). Calculated from battery level percentage and reporting frequency. Returns null when battery data is insufficient for estimation.","example":"2027-03-15T00:00:00.000Z"}},"description":"Battery readings from the device. Only returned when any battery.* include field is requested (battery.level, battery.condition, battery.lastReportedAt, battery.estimatedRemainingLife). Only requested fields are populated; others are omitted."},"DeviceIdentifier":{"type":"object","properties":{"id":{"type":"string","description":"Identifier UUID","example":"550e8400-e29b-41d4-a716-446655440000"},"identifierType":{"type":"string","description":"Type of identifier. Possible values: bluetooth_mac, esn, imei_cellular, imei_satellite, simid_cellular_one, simid_cellular_two, wifi_mac","example":"imei_cellular"},"value":{"type":"string","description":"Identifier value","example":"353456789012345"},"createdAt":{"type":"string","description":"When the identifier was created (ISO 8601 datetime)","example":"2024-01-01T00:00:00.000Z"}},"description":"Device identifier (IMEI, ICCID, serial number, etc.). Only returned when include contains \"identifiers\".","required":["id","identifierType","value","createdAt"]},"Device":{"type":"object","properties":{"id":{"type":"string","description":"Device UUID","example":"550e8400-e29b-41d4-a716-446655440000"},"deviceNumber":{"type":"string","description":"Device ESN (e.g., \"70001320\")","example":"70001320"},"accountId":{"type":"number","description":"Account ID","example":1},"deviceStatus":{"type":"string","description":"Device status","enum":["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"],"example":"active"},"deviceType":{"type":"string","description":"Device type name. Uses the device model version name when available (e.g. \"GT1s\", \"GT2c\"), falling back to the device specification type name (e.g. \"GT1\", \"GT2\").","example":"GT2c"},"latestReadings":{"$ref":"#/components/schemas/LatestReadings"},"asset":{"$ref":"#/components/schemas/DeviceAsset"},"hasAssignedAsset":{"type":"boolean","description":"Whether the device has an asset assigned to it. Only returned when include contains \"hasAssignedAsset\".","example":true},"firmwareVersion":{"type":"string","description":"Current firmware version installed on the device. Returns null when firmware version is unknown. Only returned when include contains \"firmwareVersion\".","example":"1.2.3"},"sku":{"type":"string","description":"Device SKU from the device model version. Returns null when not available. Only returned when include contains \"sku\".","example":"GT2h-001"},"deviceModelName":{"type":"string","description":"Device model name from the device model version. Returns null when not available. Only returned when include contains \"deviceModelName\".","example":"GT2h Standard"},"lastLocation":{"$ref":"#/components/schemas/Coordinates"},"hasBattery":{"type":"boolean","description":"Whether the device specification supports battery reporting. Determined by the device specification, not the device itself. Only returned when include contains \"hasBattery\".","example":true},"hasBatteryLevel":{"type":"boolean","description":"Whether the device specification supports reporting battery level. Determined by the device specification, not the device itself. Only returned when include contains \"hasBatteryLevel\".","example":true},"hasBatteryCondition":{"type":"boolean","description":"Whether the device specification supports reporting battery condition. Determined by the device specification, not the device itself. Only returned when include contains \"hasBatteryCondition\".","example":true},"battery":{"$ref":"#/components/schemas/Battery"},"cellularReportingSchedule":{"type":"string","description":"Human-readable cellular reporting schedule from the device configuration. Returns null when no configuration is deployed. Only returned when include contains \"cellularReportingSchedule\".","example":"Every 15 minutes"},"satelliteReportingSchedule":{"type":"string","description":"Human-readable satellite reporting schedule from the device configuration. Returns null when no configuration is deployed. Only returned when include contains \"satelliteReportingSchedule\".","example":"Every 4 hours"},"configurationName":{"type":"string","description":"Name of the currently deployed configuration. Returns null when no configuration is deployed. Only returned when include contains \"configurationName\".","example":"Standard Tracking"},"expectedReadingsPerDay":{"type":"number","description":"Expected number of readings per day from the device configuration. Returns null when no configuration is deployed. Only returned when include contains \"expectedReadingsPerDay\".","example":96},"identifiers":{"type":"array","items":{"$ref":"#/components/schemas/DeviceIdentifier"}}},"required":["id","deviceNumber","deviceStatus","deviceType","latestReadings"]},"AssetAssignmentCounts":{"type":"object","properties":{"assigned":{"type":"number"},"unassigned":{"type":"number"}},"required":["assigned","unassigned"]},"BatteryPresenceCounts":{"type":"object","properties":{"hasBattery":{"type":"number","description":"Number of devices with battery support.","example":42},"noBattery":{"type":"number","description":"Number of devices without battery support.","example":18}},"description":"Count of devices grouped by battery support (has battery vs no battery).","required":["hasBattery","noBattery"]},"BatteryLevelCounts":{"type":"object","properties":{"Full":{"type":"number","description":"Number of devices with \"Full\" battery level.","example":18},"High":{"type":"number","description":"Number of devices with \"High\" battery level.","example":12},"Medium":{"type":"number","description":"Number of devices with \"Medium\" battery level.","example":30},"Fair":{"type":"number","description":"Number of devices with \"Fair\" battery level.","example":8},"Replace":{"type":"number","description":"Number of devices with \"Replace\" battery level.","example":4}},"description":"Count of devices grouped by battery level (Full, High, Medium, Fair, Replace).","required":["Full","High","Medium","Fair","Replace"]},"BatteryConditionCounts":{"type":"object","properties":{"Normal":{"type":"number","description":"Number of devices with \"Normal\" battery condition.","example":35},"Fault":{"type":"number","description":"Number of devices with \"Fault\" battery condition.","example":5}},"description":"Count of devices grouped by battery condition (Normal, Fault).","required":["Normal","Fault"]},"FilterCounts":{"type":"object","properties":{"assetAssignment":{"$ref":"#/components/schemas/AssetAssignmentCounts"},"batteryPresence":{"$ref":"#/components/schemas/BatteryPresenceCounts"},"batteryLevel":{"$ref":"#/components/schemas/BatteryLevelCounts"},"batteryCondition":{"$ref":"#/components/schemas/BatteryConditionCounts"}},"description":"Filter counts (only when includeFilterCounts=true) (internal)"}}}}