Skip to main content

Response Structure

This page documents the response format for each category of AirQo API endpoint.


Hourly measurements (GET endpoints)

Used by: Site ID, Device ID, Cohort ID, and Grid ID recent measurement endpoints.

{
"success": true,
"isCache": false,
"message": "successfully returned the measurements",
"meta": {
"total": 168,
"skip": 0,
"limit": 50,
"page": 1,
"pages": 4,
"startTime": "2025-09-21T11:00:00.000Z",
"endTime": "2025-09-28T11:00:00.000Z",
"optimized": true
},
"measurements": [
{
"device": "airqo_bx2847",
"device_id": "65c8d4a2f1b45c0012a3e789",
"site_id": "64f7b3e8c9d25a0013f2d456",
"time": "2025-09-25T14:00:00.000Z",
"pm2_5": { "value": 23.45 },
"pm10": { "value": 31.82 },
"frequency": "hourly",
"deviceDetails": {
"_id": "65c8d4a2f1b45c0012a3e789",
"cohorts": ["64b9c7d5e3f82b0014c5a123"],
"isOnline": true,
"status": "deployed",
"isPrimaryInLocation": true,
"category": "lowcost",
"network": "airqo",
"name": "airqo_bx2847",
"serial_number": "3456789",
"latitude": 0.3476,
"longitude": 32.5825,
"lastActive": "2025-09-25T14:00:00.000Z",
"lastRawData": "2025-09-28T08:45:00.000Z",
"rawOnlineStatus": true
}
}
]
}

Field reference

Top-level

FieldTypeDescription
successbooleantrue if request succeeded
isCachebooleanWhether response was served from cache
messagestringHuman-readable status
metaobjectPagination and query metadata
measurementsarrayMeasurement records

meta object

FieldTypeDescription
totalnumberTotal matching records
skipnumberRecords skipped
limitnumberRecords per page
pagenumberCurrent page
pagesnumberTotal pages
startTimestringQuery start (ISO 8601)
endTimestringQuery end (ISO 8601)
optimizedbooleantrue when the query used an optimized execution path (e.g. index scan, caching, or approximation)

Measurement record

FieldTypeDescription
devicestringDevice name
device_idstringUnique device identifier
site_idstringLocation identifier
timestringReading timestamp (ISO 8601)
pm2_5.valuenumberPM2.5 in μg/m³
pm10.valuenumberPM10 in μg/m³
frequencystringAlways "hourly"

deviceDetails object (key fields)

FieldTypeDescription
isOnlinebooleanWhether device is currently active
statusstring"deployed", "maintenance", etc.
categorystring"lowcost" or "reference"
latitudenumberDevice latitude
longitudenumberDevice longitude
lastActivestringLast calibrated reading timestamp
lastRawDatastringLast raw reading timestamp

Analytics API responses (POST endpoints)

Used by: raw-data and data-download endpoints.

{
"status": "success",
"message": "Data downloaded successfully",
"data": [
{
"site_name": "Kampala Road",
"device_name": "airqo_bx2847",
"datetime": "2025-01-01 10:00:00Z",
"pm2_5": 12.45,
"pm10": 15.32,
"latitude": 0.33,
"longitude": 32.56,
"temperature": 24.5,
"humidity": 65.4,
"network": "airqo",
"frequency": "hourly"
}
],
"metadata": {
"total_count": 500,
"has_more": false,
"next": null
}
}

Top-level

FieldTypeDescription
statusstring"success" or "error"
messagestringHuman-readable status
dataarrayData records
metadataobjectPagination metadata

metadata object

FieldTypeDescription
total_countnumberTotal matching records
has_morebooleanWhether additional pages exist
nextstring or nullCursor for the next page (pass as cursor parameter)

Heatmap response

Used by: /api/v2/spatial/heatmaps endpoints.

[
{
"bounds": [
[-1.444, 36.650],
[-1.163, 37.102]
],
"city": "nairobi_city",
"id": "64b7ac8fd7249f0029feca80",
"image": "data:image/png;base64,iVBORw0KGgo...",
"message": "✅ AQI image generated for nairobi_city"
}
]
FieldTypeDescription
boundsarray[[sw_lat, sw_lng], [ne_lat, ne_lng]] bounding box
citystringCity slug
idstringGrid ID
imagestringBase64-encoded PNG (data:image/png;base64,...)
messagestringGeneration status

Forecast response

Used by: /api/v2/predict/daily-forecasting/ and /api/v2/predict/hourly-forecasting/.

See Forecast API → for the full response schema, field reference, and scope-based variants.

Daily forecasting — abbreviated example:

{
"success": true,
"data": {
"start_date": "2026-06-03",
"end_date": "2026-06-09",
"days": 7,
"total": 1,
"units": { "pm2_5": "ug/m3", "forecast_confidence": "%" },
"forecasts": [
{
"site_details": { "site_id": "64f7b3e8c9d25a0013f2d456", "site_name": "Kampala Central" },
"forecasts": [
{
"date": "2026-06-03",
"forecast": { "pm2_5_mean": 28.4, "forecast_confidence": 84.5 },
"aqi": { "category": "Moderate", "label": "Air quality is acceptable for most people." },
"met": { "air_temperature": 24.7, "relative_humidity": 72.1 }
}
]
}
]
}
}

Hourly forecasting uses the same envelope but with start_timestamp, end_timestamp, hours, and pagination fields (page, pages). Individual forecast items use timestamp instead of date and include pm2_5_q10 / pm2_5_q90 uncertainty bounds instead of pm2_5_low / pm2_5_high.