Skip to content

Devices API

Device ingestion API for machine collectors. Collectors authenticate by exchanging their authentication-api client_id/client_secret for a bearer token, then POST readings here with that token. The bearer must identify a system user that has devices WRITE access in exactly one showroom. The collector does not send showroom/customer context; the ingestion worker resolves the target showroom from the authenticated system user's active membership. The ingestion endpoint is intentionally tolerant of weak collector payloads: it validates the envelope and required routing fields strictly, stores raw payloads for audit/debugging, and returns item-level errors and warnings so collector operators can see exactly which rows need repair.

Server

URLDescription
https://api.neogt.com.au/devicesProduction

Ingest a batch of device readings from a collector.

http
POST /readings

Queues readings for ingestion. The authenticated token must belong to a system user with devices WRITE access. The API validates the batch envelope and reading shape, then stores valid readings in an AWS SQS queue. A worker Lambda resolves the showroom from the system user and writes to Hasura, so transient database outages do not lose collector data. Recommended collector flow: 1. POST client_id/client_secret to authentication-api /auth/api-client/authenticate. 2. Use the returned access_token as Authorization: Bearer <token>. 3. POST batches to this endpoint. collector_row_id is optional but strongly recommended. When present, duplicates are detected by the worker per (device, sensor, collector_row_id).

Authentication

http
Authorization: Bearer <token>

Request body

FieldTypeRequiredDescription
sourcestringnoCollector source used for sync cursor/audit grouping. Default: collector.
readingsarray&lt;ReadingInput&gt;yes

Examples

Tiltmeter collector batch
json
{
  "source": "collector",
  "readings": [
    {
      "device_external_id": "TILT-0001",
      "device_type_key": "tiltmeter",
      "device_name": "North wall tiltmeter",
      "occurred_at": "2026-07-19T04:30:00.000Z",
      "collector_row_id": 12801,
      "payload": [
        {
          "type": "tilt",
          "store": "sensor",
          "sensor_type": "tilt",
          "label": "Tilt",
          "unit": "deg",
          "status": "valid_sensor_data",
          "payload": {
            "tilt_x_deg": 0.12,
            "tilt_y_deg": -0.03
          }
        },
        {
          "type": "compass",
          "store": "sensor",
          "sensor_type": "compass",
          "label": "Compass",
          "unit": "deg",
          "status": "valid_sensor_data",
          "payload": {
            "compass_heading_deg": 181.4
          }
        },
        {
          "type": "temperature",
          "store": "sensor",
          "sensor_type": "temperature",
          "label": "Temperature",
          "unit": "c",
          "status": "valid_sensor_data",
          "payload": {
            "temperature_c": 22.8
          }
        },
        {
          "type": "displacement",
          "store": "sensor",
          "sensor_type": "displacement",
          "label": "Displacement",
          "unit": "mm",
          "status": "valid_sensor_data",
          "payload": {
            "displacement_x_mm": 1.2,
            "displacement_y_mm": -0.4,
            "displacement_z_mm": 0.8
          }
        },
        {
          "type": "battery",
          "store": "sensor",
          "sensor_type": "battery",
          "label": "Battery",
          "unit": null,
          "status": "normal",
          "payload": {
            "battery_charge_percent": 87,
            "battery_voltage_v": 3.91
          }
        }
      ]
    }
  ]
}
GPS collector batch
json
{
  "source": "collector",
  "readings": [
    {
      "device_external_id": "TILT-0001",
      "device_type_key": "tiltmeter",
      "occurred_at": "2026-07-19T04:31:00.000Z",
      "collector_row_id": 12802,
      "payload": [
        {
          "type": "gps",
          "store": "config",
          "status": "fix",
          "payload": {
            "latitude_deg": -31.9523,
            "longitude_deg": 115.8613,
            "altitude_m": 42.4,
            "ehpe_m": 3,
            "satellite_count": {
              "satellites_in_view": 10,
              "satellites_in_use": 8
            }
          }
        }
      ]
    }
  ]
}

Responses

StatusDescription
202Valid readings were queued. Inspect item results for queued and rejected rows.
400Request envelope failed OpenAPI validation.
401Missing, expired or invalid bearer token.
403Token is valid, but the caller cannot write devices for the showroom.
409The target showroom cannot accept device readings in its current state.
413Request body exceeded the service payload limit.

Neotech Geotechnical Engineering documentation.