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.
| Command | Purpose | Returns |
|---|---|---|
AQS | Retrieve one daily metric at one monitoring site. | Daily data series |
AQS_STATES | List state names and their AQS codes. | Metadata table |
AQS_COUNTIES | List counties within a state. | Metadata table |
AQS_CLASSES | Discover groups of measurement parameters. | Metadata table |
AQS_PARAMETERS | List parameters in a selected class. | Metadata table |
AQS_SITES | List monitoring sites in a county. | Metadata table |
AQS_SEARCH | Search a county’s site list by text. | Metadata table |
AQS_MONITORS | Inspect pollutant-specific monitors operating during a date range. | Metadata table |
AQS_VARIANTS | Discover 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.
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.
| Argument | Meaning and format |
|---|---|
state | Two-digit state FIPS code as a quoted string; "53" is Washington. |
county | Three-digit county code within the state; "033" is King County, Washington. Do not use the combined five-digit county FIPS here. |
site | Four-digit site number within that county; "0080" is Beacon Hill. |
parameter | Quoted pollutant alias or five-digit AQS parameter code. See the alias table. |
start, end | Inclusive 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. |
poc | Parameter 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. |
duration | Exact sample_duration from AQS_VARIANTS, such as "24-HR BLK AVG" or "24 HOUR". |
standard | Exact pollutant_standard, such as "PM25 24-hour 2024". It identifies a summary definition, not the observation year. |
event | Exact 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.
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
| Metric | Interpretation | Units |
|---|---|---|
arithmetic_mean | The daily summary’s arithmetic mean for the selected sample duration. | EPA-reported concentration units |
first_max_value | The 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 |
aqi | The 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.
"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_SEARCH — Find sites by text
AQS_SEARCH("state", "county", "search_text")
Performs a case-insensitive substring search over the returned county site-list fields. Search by station-name text or site code. The search uses the cached county list and returns a metadata table.
beacon = AQS_SEARCH("53", "033", "Beacon")
seattle = AQS_SEARCH("53", "033", "Seattle")
by_code = AQS_SEARCH("53", "033", "0080")
all_sites = AQS_SEARCH("53", "033", "")
An empty search string returns the full county site list. This searches site-list text; it does not search pollutant names or guarantee daily observations for a particular 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
| Measurement | Accepted aliases | Parameter code |
|---|---|---|
| Fine particulate matter, PM₂.₅ — local conditions | PM25, PM2.5 | 88101 |
| Ozone | OZONE, O3 | 44201 |
| PM₁₀ — local conditions | PM10 | 81102 |
| Nitrogen dioxide | NO2 | 42602 |
| Sulfur dioxide | SO2 | 42401 |
| Carbon monoxide | CO | 42101 |
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 field | Use |
|---|---|
poc | Choose one instrument for this parameter. |
sample_duration | Choose the observation or calculated averaging duration. |
pollutant_standard | Choose the daily summary definition. |
event_type | Choose the source’s event-inclusion treatment. |
units_of_measure | Verify 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.
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
- Historical observations. AQS is a historical monitoring database, not a real-time feed. EPA notes that reporting can lag collection by six months or more. Recent records may be incomplete or revised.
- Daily local dates. The series uses the source’s
date_local, not a UTC date. Check this when combining observations with weather or other timestamped sources. - Missing is not zero. Missing metric values are omitted. Valid zero and negative numeric values are retained; the adapter does not fill missing dates or interpolate.
- Gaps can be common. The current line-chart path may connect observations across missing dates. A straight segment does not establish that measurements exist on the intervening days.
- Check completeness. The data-source layer retains the full daily row, including observation counts and percentages when present. The numeric series does not carry those fields, and the command applies no automatic completeness threshold.
- Respect calendar spacing. Missing days can affect lagged models, changes and autocorrelation. Verify that an operation’s lag refers to the intended elapsed time rather than simply the next available observation.
- Monthly averages need coverage checks. These commands do not provide a dedicated monthly endpoint or automatically require a minimum number of days before aggregation.
- Do not pool alternative summaries. The adapter rejects different POCs, durations, standards, event treatments or units in a single selected series. Duplicate dates remaining after selection also produce an error.
- Event treatment matters. Use the returned labels deliberately. An events-excluded summary answers a different question from one retaining event-related observations.
No Eventsis a source label; it does not by itself establish the absence of smoke or other pollution sources. - Units are preserved. Concentrations use EPA’s units; AQI uses an AQI label. Compare compatible measurements and units across stations.
- Quality information has limits. Retaining daily metadata does not reproduce all raw-sample qualifiers or certify every record as final. No automatic certification filter is applied.
- Coverage varies. A site may monitor one pollutant but not another, change instruments, or stop operating. A site-list match is not proof of a usable daily series.
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 symptom | What to do |
|---|---|
| Multiple AQS variants match | Run AQS_VARIANTS for the same station, parameter and dates. Use the ten- or eleven-argument form with the exact returned selectors. |
| No numeric observations match | Check pollutant, period, instrument and selector strings. A metric such as AQI can be missing even when concentration data exist. |
| Duplicate AQS date | Inspect the source rows. The adapter refuses to silently choose or average duplicate observations. |
| Codes and selectors require quoted strings | Quote identifiers and labels, preserving leading zeros. Use "033", not 33. |
| Usage message | Check the command’s argument count. AQS accepts exactly 6, 10 or 11 arguments; selectors cannot be supplied as a partial group. |
| HTTP 429 / service unavailable | Allow time before retrying. Reuse cached requests and avoid repeated broad downloads. |
| Credential configuration message | The 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.
- EPA AQS API documentation and usage limits
- AQS API specification
- EPA Air Quality System
- EPA outdoor air quality data
- RainbowStats USGS water observations
- RainbowStats USBR reservoir observations
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.