RainbowStats™ · Command reference

AQS Air Quality Data

Find a monitoring station, inspect its measurements, and bring historical air pollution observations into your analysis.

RainbowStats connects the U.S. Environmental Protection Agency’s Air Quality System (AQS) to its time-series tools. Explore particulate matter, ozone, nitrogen dioxide and other available measurements, then chart or analyze a consistently selected daily record.

Nine commands, from discovery to analysis
CommandPurposeReturns
AQSRetrieve one daily metric at one monitoring site.Daily data series
AQS_STATESList state names and their AQS codes.Metadata table
AQS_COUNTIESList counties within a state.Metadata table
AQS_CLASSESDiscover groups of measurement parameters.Metadata table
AQS_PARAMETERSList parameters in a selected class.Metadata table
AQS_SITESList monitoring sites in a county.Metadata table
AQS_SEARCHSearch a county’s site list by text.Metadata table
AQS_MONITORSInspect pollutant-specific monitors operating during a date range.Metadata table
AQS_VARIANTSDiscover the daily-summary combinations available at a site.Metadata table

Quick start: Beacon Hill, Seattle

sites = AQS_SEARCH("53", "033", "Beacon")
variants = AQS_VARIANTS("53", "033", "0080", "PM25", 20240101, 20241231)
pm25 = AQS("53", "033", "0080", "PM25", 20240101, 20241231, 8, "24-HR BLK AVG", "PM25 24-hour 2024", "No Events")
named = SET_NAME(pm25, "Beacon Hill daily PM2.5")
chart = SET_TITLE(LINE_CHART(named), "Beacon Hill — Daily PM2.5, 2024")

This tested selection retrieves monitor 8 at Seattle–Beacon Hill, site 53-033-0080, using the daily block-average summary associated with the PM25 24-hour 2024 standard. Values are reported in micrograms per cubic meter at local conditions.

For another station, pollutant or date range, inspect AQS_VARIANTS first. Copy its selector values exactly; the Beacon Hill combination is an example, not a nationwide default.

One site can produce many daily summaries. Multiple instruments, averaging durations, pollutant standards and event treatments can produce several rows for the same date. Select a consistent combination before constructing a series.

AQS — Retrieve daily observations

Supported forms

AQS("state", "county", "site", "parameter", start, end)
AQS("state", "county", "site", "parameter", start, end, poc, "duration", "standard", "event")
AQS("state", "county", "site", "parameter", start, end, poc, "duration", "standard", "event", "metric")

Returns one daily numeric series for the inclusive date range. The six-argument form succeeds only when the matching daily rows have a single combination of instrument, sample duration, pollutant standard, event treatment and units across the requested period. If several combinations exist, RainbowStats returns an ambiguity message rather than choosing one.

The ten-argument form selects these attributes explicitly and returns arithmetic_mean. The eleven-argument form also selects the numeric metric. These are the only supported argument counts: 6, 10 or 11. Dates are always required.

ArgumentMeaning and format
stateTwo-digit state FIPS code as a quoted string; "53" is Washington.
countyThree-digit county code within the state; "033" is King County, Washington. Do not use the combined five-digit county FIPS here.
siteFour-digit site number within that county; "0080" is Beacon Hill.
parameterQuoted pollutant alias or five-digit AQS parameter code. See the alias table.
start, endInclusive dates as YYYYMMDD integers, quoted basic dates such as "20240101", or quoted ISO dates such as "2024-01-01". Start must not follow end, and end must not be in the future.
pocParameter Occurrence Code: the instrument number for that parameter at the site. Supply an integer from 1 to 99, such as 8; a quoted numeric value is also accepted.
durationExact sample_duration from AQS_VARIANTS, such as "24-HR BLK AVG" or "24 HOUR".
standardExact pollutant_standard, such as "PM25 24-hour 2024". It identifies a summary definition, not the observation year.
eventExact event_type, such as "No Events", "Events Included" or "Events Excluded", when returned by the source.
metric"arithmetic_mean" (default), "first_max_value" or "aqi".

Codes and text selectors require quoted strings or variables holding strings. Dates and POC may also be passed through variables. Leading zeros are significant.

Empty selectors are wildcards. An empty duration, standard or event string leaves that field unspecified; it does not specifically select a blank source field. The remaining rows must still identify one unambiguous combination. Text selectors match exactly after trimming.

Choose the numeric metric

MetricInterpretationUnits
arithmetic_meanThe daily summary’s arithmetic mean for the selected sample duration.EPA-reported concentration units
first_max_valueThe highest value represented by that daily summary. Its meaning depends on the selected sample duration; it is not automatically a one-hour maximum.EPA-reported concentration units
aqiThe daily Air Quality Index reported for that summary, when available. This is not AirNow’s current NowCast.AQI

A duration label of 1 HOUR in a daily summary does not make the returned series hourly. AQS still returns one selected daily metric. Individual hourly or raw-sample retrieval is outside the current command set.

Discover states and counties

AQS_STATES — State codes

states = AQS_STATES()

Returns the states and their codes from the AQS list service. Use the two-digit code in subsequent commands, rather than the state postal abbreviation.

AQS_COUNTIES — Counties within a state

counties = AQS_COUNTIES("53")

Returns counties listed by AQS for Washington. Use the three-digit county code together with the state code. The same county code can occur in different states.

Identifier example: Washington "53" + King County "033" + Beacon Hill "0080" identifies site 53-033-0080. Supply the three parts separately in commands.

AQS_SITES — List a county’s sites

sites = AQS_SITES("53", "033")

Returns the AQS site list for the selected county. Typical list fields are code (the site number) and value_represented (the description). Some descriptions are blank. A blank description is an empty metadata field, not a failed request.

This list is not restricted to the selected year or pollutant and can include historical sites. Use AQS_MONITORS to investigate pollutant-specific instruments and their operation during a period.

AQS_CLASSES — Discover parameter groups

classes = AQS_CLASSES()

Lists the parameter classes available from EPA. Classes group related measurements. Copy a class code into AQS_PARAMETERS to list its members.

AQS_PARAMETERS — Discover measurements

parameters = AQS_PARAMETERS("CRITERIA")

Returns parameter codes and descriptions within a selected class. Class names are normalized to uppercase. Use the resulting five-digit parameter code in AQS_MONITORS, AQS_VARIANTS and AQS. Available parameters extend beyond the convenience aliases below; actual monitoring coverage varies.

Convenience aliases

MeasurementAccepted aliasesParameter code
Fine particulate matter, PM₂.₅ — local conditionsPM25, PM2.588101
OzoneOZONE, O344201
PM₁₀ — local conditionsPM1081102
Nitrogen dioxideNO242602
Sulfur dioxideSO242401
Carbon monoxideCO42101

Aliases are case-insensitive. Any five-digit parameter code is accepted syntactically, but it must identify data available at the selected site. Related codes remain distinct: for example, the adapter does not automatically combine other PM₂.₅ codes with 88101. The PM10 alias maps specifically to 81102; use a different explicit code if your study needs another PM₁₀ measurement definition.

AQS_MONITORS — Inspect instruments and coverage

AQS_MONITORS("state", "county", "parameter", start, end)

Returns monitor metadata for the selected pollutant in the county. The date range selects monitors that operated during the period; it does not guarantee a valid measurement on every day. All fields supplied by the service are retained in the table.

monitors = AQS_MONITORS("53", "033", "PM25", 20240101, 20241231)

Inspect site numbers, POC values, operating dates and other returned attributes. One site can contain multiple instruments measuring the same parameter. Use AQS_VARIANTS to inspect the actual daily-summary combinations before retrieving a numeric series.

AQS_VARIANTS — Choose a consistent series

AQS_VARIANTS("state", "county", "site", "parameter", start, end)

Examines the daily data over the requested range and returns the unique combinations below. It downloads daily records when they are not already cached; this is more than a station-catalog lookup.

Returned fieldUse
pocChoose one instrument for this parameter.
sample_durationChoose the observation or calculated averaging duration.
pollutant_standardChoose the daily summary definition.
event_typeChoose the source’s event-inclusion treatment.
units_of_measureVerify concentration units. Units are checked for consistency, not supplied as a selector argument.
variants = AQS_VARIANTS("53", "033", "0080", "PM25", 20240101, 20241231)

The tested Beacon Hill result includes POC 1 with 24 HOUR summaries and POC 8 with 1 HOUR and 24-HR BLK AVG summaries. Several pollutant-standard labels appear. These are alternative summaries of monitoring records, not independent observations to pool.

Annual in a standard name does not mean annual data. A variant labeled PM25 Annual 2024 is still a row from the daily-summary service. The command returns daily values; the label describes the applicable standard.

A listed combination need not have observations throughout the full requested period. For longer histories, inspect variants across that full history: instruments and summary definitions may change.

Examples: concentration, AQI and reusable inputs

Retrieve a daily maximum metric

maximum = AQS("53", "033", "0080", "PM25", 20240101, 20241231, 8, "24-HR BLK AVG", "PM25 24-hour 2024", "No Events", "first_max_value")

This requests first_max_value for the selected block-average summary. To investigate within-day peaks, inspect the site’s other duration variants rather than interpreting this automatically as an hourly peak.

Plot the reported daily AQI

aqi = AQS("53", "033", "0080", "PM25", 20240101, 20241231, 8, "24-HR BLK AVG", "PM25 24-hour 2024", "No Events", "aqi")
chart = SET_TITLE(LINE_CHART(aqi), "Beacon Hill — Daily PM2.5 AQI, 2024")

AQI availability depends on the selected summary. Missing AQI values are omitted. AQI and concentration are different metrics and should not share a concentration-unit label.

Use variables and quoted dates

state = "53"
county = "033"
site = "0080"
start = "2024-01-01"
end = "2024-12-31"
variants = AQS_VARIANTS(state, county, site, "PM25", start, end)
pm25 = AQS(state, county, site, "PM25", start, end, 8, "24-HR BLK AVG", "PM25 24-hour 2024", "No Events")

Once retrieved, the numeric series can be used with RainbowStats charting, descriptive statistics, date alignment, aggregation and regression tools. Check coverage and the interpretation of time intervals before fitting a model.

Working with the data

Retrieval and caching

RainbowStats divides daily retrieval into calendar-year requests, even when an equation spans several years. It requests the current year only through today and clips the returned observations to your inclusive date range. Repeated or overlapping requests can reuse the same yearly download.

The default cache freshness is one day, including historical years so that revisions can be retrieved. Cached data do not make the upstream reporting delay disappear. Network requests are sequential within the running application, with a six-second pause after each response; an initial multi-year retrieval can therefore take time.

Unsuccessful HTTP responses, API-level failures, malformed JSON and inconsistent row counts are rejected rather than cached as valid observations. A failed refresh returns an error; the adapter does not automatically fall back to stale data.

Messages and next steps

Message or symptomWhat to do
Multiple AQS variants matchRun AQS_VARIANTS for the same station, parameter and dates. Use the ten- or eleven-argument form with the exact returned selectors.
No numeric observations matchCheck pollutant, period, instrument and selector strings. A metric such as AQI can be missing even when concentration data exist.
Duplicate AQS dateInspect the source rows. The adapter refuses to silently choose or average duplicate observations.
Codes and selectors require quoted stringsQuote identifiers and labels, preserving leading zeros. Use "033", not 33.
Usage messageCheck the command’s argument count. AQS accepts exactly 6, 10 or 11 arguments; selectors cannot be supplied as a partial group.
HTTP 429 / service unavailableAllow time before retrying. Reuse cached requests and avoid repeated broad downloads.
Credential configuration messageThe application administrator must configure the registered EPA API email and key. Credentials are not equation arguments.

Data source and further reading

Source: U.S. Environmental Protection Agency, Air Quality System (AQS). The current RainbowStats command set supports geographic and parameter discovery, monitor metadata, daily variants and selected daily metrics. It does not expose all services in EPA’s broader API, such as raw samples, quarterly/annual retrieval or QA audit endpoints.

Administrator setup: register for the public AQS API and configure EPA_AQS_EMAIL and EPA_AQS_KEY in the application environment. The default cache is under user.home/.rainbowstats/cache/aqs. Keys are excluded from published equations and cached response headers.