Skip to main content

Recent Measurements — Grid ID

Retrieve the latest hourly calibrated air quality measurements from all public monitoring sites within your city's Grid. This endpoint returns data from approximately the last 7 days.

Data freshness

Each measurement is an hourly average, so the newest record is for the most recent completed hour, not the last few minutes. See Data Freshness → to check how current a reading is and how often to poll.

Tier requirement

Available on all tiers including Free.


Endpoint​

GET https://api.airqo.net/api/v2/devices/measurements/grids/{GRID_ID}?token={SECRET_TOKEN}

Path parameters​

ParameterTypeRequiredDescription
GRID_IDstringYesYour city's Grid identifier

Query parameters​

ParameterTypeRequiredDescription
tokenstringYesYour SECRET TOKEN from Account Settings

Example request​

curl -X GET \
"https://api.airqo.net/api/v2/devices/measurements/grids/64b7ac8fd7249f0029feca80?token=YOUR_SECRET_TOKEN"

JavaScript (fetch):

const gridId = '64b7ac8fd7249f0029feca80'; // Nairobi example
const token = 'YOUR_SECRET_TOKEN';

const response = await fetch(
`https://api.airqo.net/api/v2/devices/measurements/grids/${gridId}?token=${token}`
);
const data = await response.json();

console.log(`City has ${data.meta.total} total measurements.`);
data.measurements.forEach(m => {
console.log(`[${m.time}] ${m.device}: PM2.5 = ${m.pm2_5?.value} μg/m³`);
});

Python:

import requests

grid_id = '64b7ac8fd7249f0029feca80' # Nairobi example
token = 'YOUR_SECRET_TOKEN'

response = requests.get(
f'https://api.airqo.net/api/v2/devices/measurements/grids/{grid_id}',
params={'token': token}
)
data = response.json()

for m in data['measurements']:
print(f"[{m['time']}] {m['device']}: PM2.5 = {m['pm2_5']['value']} μg/m³")

Example response​

{
"success": true,
"isCache": false,
"message": "successfully returned the measurements",
"meta": {
"total": 420,
"skip": 0,
"limit": 30,
"page": 1,
"pages": 14,
"startTime": "2025-09-21T11:00:00.000Z",
"endTime": "2025-09-28T11:00:00.000Z"
},
"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
},
"no2": {
"value": null
},
"aqi_category": "Moderate",
"aqi_color": "ffff00",
"aqi_index": 75,
"frequency": "hourly",
"siteDetails": {
"name": "Civic Centre, Nairobi",
"city": "Nairobi",
"country": "Kenya",
"approximate_latitude": -1.2921,
"approximate_longitude": 36.8219
}
}
]
}

This example is abbreviated to the most commonly used fields, so real rows contain more.

Reading the rows

Pollutant fields are objects, so read pm2_5.value rather than pm2_5.

Each row is the latest reading from one device, so time can differ between rows. To summarise a Grid, aggregate across rows or filter by site_id. Don't use only the first row, and don't chart the rows as a time series.


Response fields​

Top-level​

FieldDescription
successtrue if the request succeeded
isCacheWhether the response was served from cache
messageHuman-readable status message
metaPagination and query metadata
measurementsArray of measurement objects

meta object​

FieldDescription
totalTotal measurements matching the query
skipRecords skipped (pagination)
limitMax records per page
pageCurrent page
pagesTotal pages
startTimeQuery start (ISO 8601)
endTimeQuery end (ISO 8601)

Measurement object​

FieldDescription
deviceDevice name
device_idUnique device identifier
site_idLocation identifier
timeReading timestamp (ISO 8601)
pm2_5.valuePM2.5 concentration in μg/m³
pm10.valuePM10 concentration in μg/m³
no2.valueNO₂ reading. May be null.
aqi_categoryAQI category name for the reading
aqi_colorDisplay colour for the AQI category
aqi_indexAQI value for the reading
frequencyAlways "hourly" for this endpoint
siteDetailsDetails of the device's site. Useful fields include name, city, country, approximate_latitude, and approximate_longitude.

Pagination​

Large city Grids can return hundreds of measurements. Use limit (default 30, max 80) and skip to page through:

# Get next page (records 31–60)
curl "https://api.airqo.net/api/v2/devices/measurements/grids/{GRID_ID}?token={SECRET_TOKEN}&limit=30&skip=30"

Need data older than 7 days?​

Use the Analytics API for historical city data →.

Want a visual map of your city's air quality?​

See Spatial Heatmaps → for generating Base64-encoded PNG heatmap images.