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
argumentdescriptioninput requirements
sensors_idint OpenAQ’s unique ID for the sensor from which measurements should be retrieved.Required
datastr The base measurement unit to query.Required, must be one of: measurements, hours, days, years
rollupstr | None The period by which to roll up the base measurement data.Must be one of: hourly, daily, monthly, yearly, hourofday, dayofweek, monthofyear
datetime_fromdatetime.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_todatetime.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_fromdatetime.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_todatetime.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
pageint The page number to retrieve, defaults to 1Must be greater than zero
limitint The number of results returned per page, defaults to 1,000Must 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.

measurementshoursdaysyears
hourly
daily
monthly
yearly
hourofday
dayofweek
monthofyear
datadescriptionnote
measurementsRetrieve the raw measurement values as reported by the upstream providers.
hoursRetrieve 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.
daysRetrieve the daily average measurements, computed from the hourly average values from 01:00 to 0:00 in local time.
yearsRetrieve the yearly average measurements, computed from the hourly average values from January 01 at 01:00 to December 31 0:00 in local time.
rollupdescriptionnote
hourlyAggregates 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.
dailyAggregates 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.
monthlyAggregates across the selected base measurement and returns the average value for each month.
yearlyAggregates 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.
hourofdayAggregates across the selected base measurement and returns the average value for each hour in a 24-hour day.
dayofweekAggregates across the selected base measurement and returns the average value for each day in a week (Monday-Sunday).
monthofyearAggregates 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