ShieldGPS API v1

API Reference

A simple REST API for accessing your devices and their location data. Authenticate with an API key, hit JSON endpoints, build whatever you need.

Base URLhttps://shieldgps.com/api/public/v1

Introduction

The ShieldGPS Public API lets you programmatically access devices on your account and their GPS location data. It is organised around REST, accepts and returns application/json, uses standard HTTP verbs and response codes, and authenticates with a single API key per request.

All requests must be made over HTTPS. Calls made over plain HTTP will fail. All timestamps are returned in ISO-8601 format in UTC. JSON keys use camelCase.

Fields marked nullable in the reference tables may be returned as null in JSON responses — usually because the underlying value is not yet known (e.g. a device that has never reported a position). Non-nullable fields are always present and never null.

Authentication

The API authenticates requests using API keys. API access must first be enabled for your account. Then open Settings → API Access in your dashboard to enable a key. This section is only shown when account access is available; contact support if you don't see it. Requests with a valid key return 403 api_access_disabled if API access has been disabled for the account.

Each key grants read access to active devices on your account. A premium subscription is required on each device.

Provide your key in the Authorization header on every request, prefixed with Bearer:

Keys begin with sgps_live_ followed by a long random string. The full key is shown only once at creation time, so store it somewhere safe. If you lose a key, choose Regenerate API key. The old key stops working and the new key is shown once.

Keep keys secret. Treat your API key like a password. Never embed it in client-side code, mobile apps, or public repositories. If a key is compromised, turn off Enabled in Settings → API Access to revoke it immediately.
Example requestcURL
curl https://shieldgps.com/api/public/v1/devices \
  -H "Authorization: Bearer sgps_live_7Hk9...wQ"

Errors

The API uses conventional HTTP status codes to indicate success or failure. 2xx means success, 4xx means a problem with your request, 5xx means something went wrong on our end.

Errors return a JSON body with a stable machine-readable error code and a human-readable message:

StatusMeaning
200OK
400Malformed request
401Missing or invalid API key
403API key cannot access this resource
404Resource not found
422Request validation failed
429Rate limit exceeded
5xxServer-side error
Example errorJSON
{
  "error": "device_not_found",
  "message": "No device with id 6f7c...c4 for this API key."
}

Rate limits

The API allows up to 60 requests per minute per API key. Exceeding this returns 429 Too Many Requests. Every response includes the following headers so you can track your usage:

HeaderDescription
X-RateLimit-LimitMaximum requests allowed per minute.
X-RateLimit-RemainingRequests remaining in the current window.
X-RateLimit-ResetUnix timestamp when the window resets.

Pagination

List endpoints are cursor-paginated. Pass limit to control page size and next to fetch the following page using the cursor returned in the previous response.

ParamTypeDescription
limitinteger
optional
Items per page. Default 50, maximum varies per endpoint.
nextstring
optional
Opaque cursor returned as nextCursor on the previous response.

Every paginated response includes a hasMore boolean and a nextCursor string. Iterate until hasMore is false; on the final page, nextCursor is null.

Paginated responseJSON
{
  "data": [ /* ... */ ],
  "hasMore": true,
  "nextCursor": "c3RhcnQ6MTcxMjkxNjAwMA=="
}

Identifiers

All resource IDs in the public API are UUIDs (e.g. 6f7c2c84-2b3d-4e5a-9b1f-1a2b3c4d5ec4). They are stable, opaque strings — do not parse or generate them client-side. Where convenient, the device endpoints also accept an alias of the form imei:<imei> in place of a UUID, so you can address a device by its hardware IMEI directly.

The Device object

Represents a physical GPS device on your account.

AttributeTypeDescription
idstringUUID identifier for the device.
imeistring15-digit hardware IMEI.
namestringDisplay name set by the owner (e.g. "Van 3"). Falls back to an auto-generated name based on the model if the owner has not set one.
modelstringHardware model code (e.g. OB22, AT1).
statestringOne of new, active, suspended, cancel-pending.
isOnlinebooleanTrue if the device has communicated within the last 30 minutes. Always false for devices that have never been seen.
lastSeenAttimestamp
nullable
Most recent communication from the device. null if the device has never been seen.
lastMotionAttimestamp
nullable
Most recent motion detected by the device. null if no motion has been recorded, or if the model does not support motion detection.
batteryinteger
nullable
Battery level as a percentage 0–100. null if the device has not reported a battery reading yet, or does not support battery reporting.
lastLocationobject
nullable
Most recent Location object. null if the device has never reported a position. Does not include the reverse-geocoded address.
The Device objectJSON
{
  "id": "6f7c2c84-2b3d-4e5a-9b1f-1a2b3c4d5ec4",
  "imei": "860123456789012",
  "name": "Van 3",
  "model": "OB22",
  "state": "active",
  "isOnline": true,
  "lastSeenAt": "2026-04-12T10:25:05Z",
  "lastMotionAt": "2026-04-12T10:20:00Z",
  "battery": 85,
  "lastLocation": {
    "latitude": 37.7749,
    "longitude": -122.4194,
    "speed": 45.5,
    "heading": 90,
    "battery": 85,
    "positionAt": "2026-04-12T10:25:00Z"
  }
}

List devices

Returns a paginated list of eligible active premium devices on your account in a stable device order. Ineligible devices are omitted before pagination. Direct device and location requests for an ineligible device return 404 device_not_found, including requests using an IMEI alias.

GET/devices

Query parameters

statestring
optional
Filter by device state. Accepts new, active, suspended, cancel-pending; only active can return devices.
limitinteger
optional
Page size. Default 50, maximum 200.
nextstring
optional
Pagination cursor.
RequestcURL
curl https://shieldgps.com/api/public/v1/devices?state=active \
  -H "Authorization: Bearer sgps_live_7Hk9...wQ"
Response200 OK
{
  "data": [
    {
      "id": "6f7c2c84-2b3d-4e5a-9b1f-1a2b3c4d5ec4",
      "imei": "860123456789012",
      "name": "Van 3",
      "model": "OB22",
      "state": "active",
      "isOnline": true,
      "lastSeenAt": "2026-04-12T10:25:05Z",
      "lastMotionAt": "2026-04-12T10:20:00Z",
      "battery": 85,
      "lastLocation": { "...": "..." }
    }
  ],
  "hasMore": false,
  "nextCursor": null
}

Retrieve a device

Fetch a single device by its UUID, or by its IMEI using the imei:<imei> alias.

GET/devices/{id}

Path parameters

idstring
required
The device UUID, or imei:<imei>.

Returns a Device object. Returns 404 with device_not_found if no device on your account matches.

RequestcURL
curl https://shieldgps.com/api/public/v1/devices/imei:860123456789012 \
  -H "Authorization: Bearer sgps_live_7Hk9...wQ"

The Location object

Represents a single GPS fix reported by a device.

AttributeTypeDescription
latitudenumberDecimal degrees, WGS84.
longitudenumberDecimal degrees, WGS84.
speednumber
nullable
Speed in kilometres per hour (kph) at the time of the fix. Always returned in kph regardless of the device or account locale. null if the device did not report a speed.
headinginteger
nullable
Course in degrees from true north, 0–359. null if heading was not reported (typically when stationary).
batteryinteger
nullable
Battery level 0–100 at the time of the fix. null if the device did not report a battery reading with this position.
positionAttimestampWhen the device recorded the fix.
addressobject
latest only
nullable
Reverse-geocoded address. Only returned by the Latest location endpoint, and may be null if the geocoder cannot resolve the coordinates.

The address object contains formatted, street, city, region, postalCode, and country (ISO-3166 alpha-2). Any field may be null if the geocoder cannot resolve it.

The Location objectJSON
{
  "latitude": 37.7749,
  "longitude": -122.4194,
  "speed": 45.5,
  "heading": 90,
  "battery": 85,
  "positionAt": "2026-04-12T10:25:00Z",
  "address": {
    "formatted": "1 Market St, San Francisco, CA 94105, USA",
    "street": "1 Market St",
    "city": "San Francisco",
    "region": "CA",
    "postalCode": "94105",
    "country": "US"
  }
}

Latest location

Returns the most recent Location reported by a device, including a reverse-geocoded street address. Use this endpoint when you want a single “where is it now?” answer.

GET/devices/{id}/locations/latest

Path parameters

idstring
required
The device UUID, or imei:<imei>.

Returns a single Location object. Returns 404 with no_location_available if the device has never reported a position.

Reverse geocoding. The address field is computed on-demand from the latest coordinates and may add a small amount of latency to this endpoint compared to the historical endpoint.
RequestcURL
curl https://shieldgps.com/api/public/v1/devices/{id}/locations/latest \
  -H "Authorization: Bearer sgps_live_7Hk9...wQ"
Response200 OK
{
  "latitude": 37.7749,
  "longitude": -122.4194,
  "speed": 45.5,
  "heading": 90,
  "battery": 85,
  "positionAt": "2026-04-12T10:25:00Z",
  "address": {
    "formatted": "1 Market St, San Francisco, CA 94105, USA",
    "street": "1 Market St",
    "city": "San Francisco",
    "region": "CA",
    "postalCode": "94105",
    "country": "US"
  }
}

Historical locations

Returns every location reported by a device within a given time range, ordered oldest-first. Use this endpoint to build trip replays, draw routes on a map, or export data for analysis.

GET/devices/{id}/locations

Path parameters

idstring
required
The device UUID, or imei:<imei>.

Query parameters

starttimestamp
required
Inclusive start of the range, ISO-8601 UTC.
endtimestamp
optional
Exclusive end of the range, ISO-8601 UTC. Defaults to the current time.
limitinteger
optional
Page size. Default 500, maximum 1000.
nextstring
optional
Pagination cursor returned by the previous response.

Constraints

  • Maximum range per request is 31 days. To pull more, page through using next or split into multiple calls.
  • Locations are retained for 90 days. Requesting a start older than this returns 422 range_outside_retention.
  • Reverse-geocoded address is not included in this response. Use the Latest location endpoint when you need the address.
RequestcURL
curl -G https://shieldgps.com/api/public/v1/devices/{id}/locations \
  -H "Authorization: Bearer sgps_live_7Hk9...wQ" \
  --data-urlencode "start=2026-04-01T00:00:00Z" \
  --data-urlencode "end=2026-04-12T00:00:00Z" \
  --data-urlencode "limit=500"
Response200 OK
{
  "data": [
    {
      "latitude": 37.7749,
      "longitude": -122.4194,
      "speed": 45.5,
      "heading": 90,
      "battery": 85,
      "positionAt": "2026-04-01T08:14:32Z"
    },
    {
      "latitude": 37.7751,
      "longitude": -122.4189,
      "speed": 47.1,
      "heading": 92,
      "battery": 85,
      "positionAt": "2026-04-01T08:14:42Z"
    }
  ],
  "hasMore": true,
  "nextCursor": "cG9zOjE3MTI5MTYwODI="
}
Error422 Unprocessable
{
  "error": "range_outside_retention",
  "message": "start must be within the last 90 days."
}