Skip to content

Measurements

The Measurements resources provide measurements data from sensors. OpenAQ attempts to ingest raw measurements at least hourly, but also hosts data at a much higher frequency (e.g. five minute interval). In addition to providing raw measurement values as reported by providers, we also provide options for accessing the data at different levels of aggregation.

The Measurements resource provides the following methods:

  • list() - For accessing measurements data.

The list() method takes 2 required arguments and multiple optional arguments, ultimately returning measurements data on the OpenAQ platform that meet all the conditions specified in a MeasurementsResponse object. While it is possible to leave arguments unspecified, because the Measurements resource contains a large amount of data, we recommend that you limit queries using arguments as constaints, such as using a smaller time period with the date_from and date_to, or choosing hours or greater frequencies for data to avoid Request Timeout error.

list(
sensors_id: int,
data: str,
rollup: str | None = None,
datetime_from: datetime.datetime | str | None = None,
datetime_to: datetime.datetime | str | None = None,
date_from: datetime.date | str | None = None,
date_to: datetime.date | str | None = None,
page: int = 1,
limit: int = 1000
) -> MeasurementsResponse
argument description input requirements
sensors_id int OpenAQ’s unique ID for the sensor from which measurements should be retrieved. Required
data str The base measurement unit to query. Required, must be one of: measurements, hours, days, years
rollup str | None The period by which to roll up the base measurement data. Must be one of: hourly, daily, monthly, yearly, hourofday, dayofweek, monthofyear
datetime_from datetime.datetime | str | None Starting datetime to retrieve measurements. Defaults to local time unless timezone information is included. If not a datetime object then must be a ISO-8601 formatted datetime string i.e. YYYY-MM-DDTHH:mm:ss. Can only be used when data is either measurements or hours. Cannot be used with date_from or date_to
datetime_to datetime.datetime | str | None Ending datetime to retrieve measurements. Defaults to local time unless timezone information is included. If not a datetime object then must be a ISO-8601 formatted datetime string i.e. YYYY-MM-DDTHH:mm:ss. Can only be used when data is either measurements or hours. Cannot be used with date_from or date_to
date_from datetime.date | str | None Starting date to retrieve measurements. Defaults to local time unless timezone information is included. If not a datetime object then must be a ISO-8601 formatted date string i.e. YYYY-MM-DD. Can only be used when data is either days or years. Cannot be used with datetime_from or datetime_to
date_to datetime.date | str | None Ending date to retrieve measurements. Defaults to local time unless timezone information is included. If not a datetime object then must be a ISO-8601 formatted date string i.e. YYYY-MM-DD. Can only be used when data is either days or years. Cannot be used with datetime_from or datetime_to
page int The page number to retrieve, defaults to 1 Must be greater than zero
limit int The number of results returned per page, defaults to 1,000 Must be between 1 and 1,000
from openaq import OpenAQ
# Retrieve days measurements data for the first three months of 2026 for sensor
# with ID 10330999
with OpenAQ(api_key="replace-me-with-a-valid-key") as client:
client.measurements.list(sensors_id=10330999,
data="days",
date_from="2026-01-01",
date_to="2026-03-31")

Understanding data and rollup concepts is the key to using the Measurements resource effectively. While data gives you the benefit of speed as it fetches pre-computed measurements data, it is limited in the level of aggregation (covering only measurements, hours, days, and years data) and the base measurement from which data is aggregated (i.e. the hourly average values).

On the other hand, adding the argument rollup allows you the flexibility of choosing among a variety of aggregation periods from any base measurements input in data. However, because rollups are computed on the fly, it will be slower and more resources-consuming than simply using data, especially when rolling up from data=“measurements”. As such, prioritize data where you can and if you need to use rollup for a customized aggregation:

  • double check to see if it’s a query that could be done just using data
  • limit your queries to smaller time periods

The table below presents acceptable combinations of data and rollup values. The columns are data values whereas the rows are rollup values.

measurements hours days years
hourly
daily
monthly
yearly
hourofday
dayofweek
monthofyear
data description note
measurements Retrieve the raw measurement values as reported by the upstream providers.
hours Retrieve the hourly average value of raw measurements. If the upstream reporting period is hourly, the query with data=“hours” and that with data=“measurements” would return the same results.
days Retrieve the daily average measurements, computed from the hourly average values from 01:00 to 0:00 in local time.
years Retrieve the yearly average measurements, computed from the hourly average values from January 01 at 01:00 to December 31 0:00 in local time.
rollup description note
hourly Aggregates across the selected base measurement and returns the average value for each hour. If “measurements” is your base measurement, opt for simply using data=“hours” without using the rollup argument.
daily Aggregates across the selected base measurement and returns the average value for each day. If “hours” is your base measurement, opt for simply using data=“days” without using the rollup argument.
monthly Aggregates across the selected base measurement and returns the average value for each month.
yearly Aggregates across the selected base measurement and returns the average value for each year. If “hours” is your base measurement, opt for simply using data=“years” without using the rollup argument.
hourofday Aggregates across the selected base measurement and returns the average value for each hour in a 24-hour day.
dayofweek Aggregates across the selected base measurement and returns the average value for each day in a week (Monday-Sunday).
monthofyear Aggregates across the selected base measurement and returns the average value for each month in a year (January-December).
from openaq import OpenAQ
from datetime import datetime
# Retrieve monthly measurements data aggregated from the hours base
# measurements for the first three months of 2026 for sensor with ID 10330999
with OpenAQ(api_key="your-api-key") as client:
client.measurements.list(sensors_id=10330999,
data="hours",
rollup="monthly",
datetime_from=datetime(2026, 1, 1),
datetime_to=datetime(2026, 3, 31)
)

The Measurements objects in the results of the MeasurementsResponse contain attributes that have all data about them. The hierarchy below presents the depth of the attributes and their datatypes.

results[]
├── value: float
├── parameter
│ ├── id: int
│ ├── name: str
│ ├── units: str
│ └── display_name: str | None
├── period
│ ├── label: str
│ ├── interval: str
│ └── datetime_from:
│ ├── utc: str
│ └── local: str
├── coordinates
│ ├── latitude: float
│ └── longitude: float
├── summary
│ ├── min: float
│ ├── q02: float
│ ├── q25: float
│ ├── median: float
│ ├── q75: float
│ ├── q98: float
│ ├── max: float
│ └── sd: float
└── coverage:
├── expected_count: int
├── expected_interval: str
├── observed_count: int
├── observed_interval: str
├── percent_complete: float
├── percent_coverage: float
├── datetime_from
│ ├── utc: str
│ └── local: str
└── datetime_to
├── utc: str
└── local: str