openaqi docs

Catalogue and status

GET /v1/meta and /v1/status — reference data and dataset freshness. Neither needs a key.

GET/v1/metano key required

Units, plausible ranges, severity bands and the published standard behind each one.

curl https://openaqi.net/api/v1/meta

Read this instead of hardcoding thresholds

Gating it behind a key would only make every integration keep a private copy of our bands — which is how a client ends up still grading against a standard that was retired two years ago.

{
  "data": {
    "metrics": [
      {
        "key": "pm2p5",
        "label": "PM2.5",
        "unit": "µg/m³",
        "range": { "min": 0, "max": 1000 },
        "graded": true,
        "thresholds": { "kind": "rising", "steps": [{ "upTo": 12, "level": "good" }] },
        "source": "US EPA 24-hour PM2.5 breakpoints",
        "aliases": ["pm25", "pm2_5", "pm2.5"],
        "accepts_units": ["mg/m3"]
      }
    ],
    "severity": { "order": ["good", "…"], "labels": {}, "colors": {} },
    "tiers": [],
    "cells": { "system": "H3", "resolution": 7, "approx_area_km2": 5.16 }
  }
}

GET/v1/statusno key required

Is data flowing?

{
  "data": {
    "ok": true,
    "api_version": "v1",
    "cells": 226,
    "sensors": 252,
    "readings_24h": 27503,
    "latest": "2026-08-02T09:42:16.000Z",
    "stale": false
  }
}

Unauthenticated on purpose: the first question when an integration goes quiet is "is it me or is it them", and needing a working key to ask is the wrong answer.

stale is the field that matters — the API can be perfectly healthy while nothing has arrived for an hour.


OpenAPI

GET/v1/openapi.jsonno key required

Generated from the same catalogue and tier table the API enforces, so it cannot drift. Import it into Postman, or generate a client:

npx openapi-typescript https://openaqi.net/api/v1/openapi.json -o openaqi.d.ts

On this page