Partner Integration

Device Data API

Push air-quality readings from your devices to MyAQI over HTTP. We ingest them into our Apache Kafka pipeline and return enriched, hyperlocal data. We can also build a custom adapter to your own format, provided it carries the mandatory fields.

⬇ Download the API spec (Markdown)
We support HTTP GET (URL parameters) for simple or legacy devices — but we prefer HTTPS POST with a JSON body. It is encrypted (TLS), supports batching to save device battery, and keeps data and tokens out of URLs and server logs. New integrations should use HTTPS + POST + JSON where possible.

Authentication

Every request must carry a per-device API token issued by MyAQI during onboarding. Send it as a Bearer token in the Authorization header:

Authorization: Bearer <apitoken>
  • The token is issued per device (or vendor fleet) and maps to the device’s imei.
  • Preferred: token in the Authorization header over HTTPS — never exposed in URLs or logs.
  • Legacy fallback: for devices that cannot set headers, pass ?apitoken=<apitoken> on a GET. Discouraged (tokens in URLs can leak into logs/proxies); HTTPS only.
  • Missing/invalid/revoked token → 401 Unauthorized. Token not matching the payload imei403 Forbidden.

Endpoints

MethodURLBodyUse
POST preferredhttps://devices.myaqi.org/readingsJSONNew integrations; single or batch
GET supportedhttp(s)://devices.myaqi.org/readings?…query paramsSimple / legacy devices; one reading

Success: 200 OK / 202 Accepted.  Errors: 401 bad/missing token, 403 token/imei mismatch, 400 malformed or missing mandatory field.

Field reference

FieldTypeUnitReq.Notes
imeistringYesDevice id (<=30 chars); is a unique id for each device.
latnumberdegreesYesLatitude, e.g. 18.55348.
lonnumberdegreesYesLongitude, e.g. 73.807503.
timestampstringISO 8601YesYYYY-MM-DDThh:mm:ss.sssZ (UTC, ms).
pm1numberµg/m³NoPM1.0.
pm25numberµg/m³NoPM2.5.
pm10numberµg/m³NoPM10.
so2numberµg/m³NoSulphur dioxide.
no2numberµg/m³NoNitrogen dioxide (NOx accepted in lieu).
conumberppmNoCarbon monoxide.
co2numberppmNoCarbon dioxide.
hchonumberµg/m³NoFormaldehyde.
tempnumber°CNoTemperature (Celsius).
humidnumberg/m³NoHumidity.
altnumbermNoAltitude (AGL).
rssi_4gnumberdBmNo4G signal; negative (e.g. -75).
rssi_5gnumberdBmNo5G signal; negative.
batnumber%NoBattery level, 0–100.

Measurement values are JSON numbers (e.g. 33.0, not "33.0"); only imei and timestamp are strings. Optional fields may be omitted (preferred) or sent as null — never as empty strings. New fields may be added over time; unknown fields are ignored.

Preferred — HTTPS POST + JSON recommended

Single reading

curl --location 'https://devices.myaqi.org/readings' \ --header 'Authorization: Bearer <apitoken>' \ --header 'Content-Type: application/json' \ --data '{ "imei": "E868E7C7CA23", "lat": 18.55348, "lon": 73.807503, "timestamp": "2026-05-06T14:01:00.000Z", "pm1": 21.0, "pm25": 33.0, "pm10": 43.0, "temp": 33.9, "humid": 28.1, "rssi_4g": -75, "bat": 85 }'

Batch upload (recommended for low-power devices)

To conserve battery, cache readings and upload several at once (e.g. every 5–15 min). Send identity once and an array of time-stamped readings.

curl --location 'https://devices.myaqi.org/readings' \ --header 'Authorization: Bearer <apitoken>' \ --header 'Content-Type: application/json' \ --data '{ "imei": "E868E7C7CA23", "lat": 18.55348, "lon": 73.807503, "readings": [ { "timestamp": "2026-05-06T14:01:00.000Z", "pm25": 33.0, "pm10": 43.0, "temp": 33.9, "humid": 28.1, "bat": 85 }, { "timestamp": "2026-05-06T14:16:00.000Z", "pm25": 35.0, "pm10": 46.0, "temp": 34.1, "humid": 27.4, "bat": 84 } ] }'

imei required at top level. lat/lon once at top level (stationary device) or per reading. Each readings element needs a timestamp.

Supported — HTTP GET + URL legacy

For simple or legacy devices. Prefer HTTPS; prefer the Authorization header over the apitoken query parameter.

Token in header (preferred, over HTTPS)

curl --location --get 'https://devices.myaqi.org/readings' \ --header 'Authorization: Bearer <apitoken>' \ --data-urlencode 'imei=E868E7C7CA23' \ --data-urlencode 'lat=18.55348' \ --data-urlencode 'lon=73.807503' \ --data-urlencode 'timestamp=2026-05-06T14:01:00.000Z' \ --data-urlencode 'pm25=33.0' \ --data-urlencode 'pm10=43.0' \ --data-urlencode 'temp=33.9' \ --data-urlencode 'humid=28.1' \ --data-urlencode 'rssi_4g=-75' \ --data-urlencode 'bat=85'

Token in URL (discouraged — only if headers are impossible, HTTPS only)

https://devices.myaqi.org/readings?apitoken=<apitoken> &imei=E868E7C7CA23&lat=18.55348&lon=73.807503 &timestamp=2026-05-06T14%3A01%3A00.000Z &pm25=33.0&pm10=43.0&temp=33.9&humid=28.1&rssi_4g=-75&bat=85

Omit optional parameters entirely (don’t send empty so2=). Colons in the timestamp are percent-encoded (%3A) in a raw URL.

Rules & conventions

⬇ Download this spec (Markdown)   Request an API token →