# EPA Air Quality System (AQS) Scraper (`parseforge/epa-aqs-air-quality-scraper`) Actor

Export U.S. ambient air-quality measurements from EPA's Air Quality System: daily summaries by county, hourly sample readings by monitor site, and active monitor inventory by state. Covers PM2.5, PM10, NO2, O3, CO, SO2, lead, VOCs and meteorological data from 10,000+ monitoring stations.

- **URL**: https://apify.com/parseforge/epa-aqs-air-quality-scraper.md
- **Developed by:** [ParseForge](https://apify.com/parseforge) (community)
- **Categories:** Developer tools, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $19.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).


# README

![ParseForge Banner](https://github.com/ParseForge/apify-assets/blob/ad35ccc13ddd068b9d6cba33f323962e39aed5b2/banner.jpg?raw=true)

## 🌬️ EPA Air Quality System (AQS) Scraper

> 🚀 **Export U.S. air quality measurements in seconds.** Pull PM2.5, PM10, NO2, O3, CO, SO2, lead, and meteorological readings from **10,000+ EPA monitoring stations** nationwide. No signup required for demo data.

> 🕒 **Last updated:** 2026-05-21 · **📊 24 fields** per record · **🏭 10,000+ monitoring stations** · **🇺🇸 All 50 states + DC** · **🧪 11 pollutant parameters**

The **EPA AQS Scraper** connects directly to the U.S. Environmental Protection Agency's Air Quality System (AQS) API and delivers real ambient air-quality data in three collection modes: daily county summaries, hourly site-level samples, and an active monitor inventory. The underlying AQS database is the authoritative federal reference for U.S. ambient air monitoring and has been maintained by the EPA and state/local agencies since the 1970s.

The data covers all 50 states, the District of Columbia, and U.S. territories. It spans criteria pollutants regulated under the Clean Air Act - PM2.5, PM10, carbon monoxide, sulfur dioxide, nitrogen dioxide, ozone, and lead - plus meteorological parameters and volatile organic compounds from over 10,000 monitoring stations. This Actor makes that data downloadable as CSV, Excel, JSON, or XML in seconds. No parsing engineering required.

| 🎯 Target Audience | 💡 Primary Use Cases |
|---|---|
| Environmental engineers, public health researchers, climate scientists, city planners, journalists, compliance teams, GIS analysts | AQI dashboards, health impact studies, regulatory compliance reporting, air-quality mapping, trend analysis, research datasets |

---

### 📋 What the EPA AQS Scraper does

Three dataset modes in a single Actor:

- 📅 **Daily Summary by County.** Statistical daily summaries (arithmetic mean, first max value, AQI, observation count) for any county, pollutant, and date range up to one year.
- ⏱️ **Hourly Samples by Site.** Individual sample measurements with local and GMT timestamps for any specific monitoring site.
- 🗺️ **Active Monitor Inventory.** Directory of all active or historical monitoring stations in a state, including coordinates, agency, monitor type, and operational dates.

Each record includes geographic identifiers (state, county, city, site address, CBSA), measurement metadata (units, sample duration, method, AQI), and precise coordinates (latitude/longitude).

> 💡 **Why it matters:** the EPA AQS is the gold standard for U.S. air quality data, but navigating its raw API requires knowing parameter codes, FIPS codes, date formats, and credential setup. This Actor handles all of that so researchers, engineers, and analysts can access the data immediately without writing a single line of code.

---

### 🎬 Full Demo

_🚧 Coming soon: a 3-minute walkthrough showing how to go from sign-up to a downloaded dataset._

---

### ⚙️ Input

<table>
<thead>
<tr><th>Input</th><th>Type</th><th>Default</th><th>Behavior</th></tr>
</thead>
<tbody>
<tr><td><code>maxItems</code></td><td>integer</td><td><code>10</code></td><td>Records to return. Free plan caps at 10, paid plan at 1,000,000.</td></tr>
<tr><td><code>endpoint</code></td><td>select</td><td><code>dailyDataByCounty</code></td><td>Which EPA dataset to export: Daily Summary, Hourly Samples, or Monitor Inventory.</td></tr>
<tr><td><code>parameter</code></td><td>select</td><td><code>88101</code></td><td>Pollutant parameter code (e.g. PM2.5, NO2, O3, CO).</td></tr>
<tr><td><code>stateCode</code></td><td>select</td><td><code>06</code></td><td>Two-digit state FIPS code. Required for all endpoints.</td></tr>
<tr><td><code>countyCode</code></td><td>textfield</td><td><code>037</code></td><td>Three-digit county FIPS code. Required for dailyDataByCounty and sampleDataBySite.</td></tr>
<tr><td><code>siteNumber</code></td><td>textfield</td><td><code>0080</code></td><td>Four-digit site number. Required for sampleDataBySite.</td></tr>
<tr><td><code>startDate</code></td><td>textfield</td><td><code>20240101</code></td><td>Start date in YYYYMMDD format. Required for all endpoints.</td></tr>
<tr><td><code>endDate</code></td><td>textfield</td><td><code>20240131</code></td><td>End date in YYYYMMDD format. Max one year per query.</td></tr>
<tr><td><code>email</code></td><td>textfield</td><td>(demo account)</td><td>Optional. Your registered EPA AQS email. Defaults to shared demo account.</td></tr>
<tr><td><code>accessKey</code></td><td>textfield</td><td>(demo key)</td><td>Optional. Your EPA AQS access key. Personal keys get higher quotas.</td></tr>
</tbody>
</table>

**Example 1 - Daily PM2.5 summary for Los Angeles County:**

```json
{
  "endpoint": "dailyDataByCounty",
  "parameter": "88101",
  "stateCode": "06",
  "countyCode": "037",
  "startDate": "20240101",
  "endDate": "20240131",
  "maxItems": 100
}
````

**Example 2 - Active PM2.5 monitors in California:**

```json
{
  "endpoint": "monitorsByState",
  "parameter": "88101",
  "stateCode": "06",
  "startDate": "20240101",
  "endDate": "20240131",
  "maxItems": 500
}
```

> ⚠️ **Good to Know:** The Actor uses a shared demo EPA account by default. Demo credentials have low rate limits and may return limited results. For production use, register a free account at <https://aqs.epa.gov/data/api/signup> and supply your own email + access key. The EPA AQS API accepts a maximum date range of one year per query.

***

### 📊 Output

| Field | Type | Description |
|---|---|---|
| `stateCode` | string | Two-digit state FIPS code |
| `countyCode` | string | Three-digit county FIPS code |
| `siteNumber` | string | Four-digit monitoring site number |
| `stateName` | string | Full state name |
| `countyName` | string | Full county name |
| `cityName` | string | City where the monitor is located |
| `localSiteName` | string | EPA-assigned local site name |
| `siteAddress` | string | Street address of the monitor |
| `parameterCode` | string | EPA parameter code (e.g. 88101) |
| `parameterName` | string | Full pollutant name |
| `poc` | number | Parameter occurrence code (distinguishes co-located monitors) |
| `datum` | string | Coordinate datum (NAD83, WGS84) |
| `pollutantStandard` | string | NAAQS standard the measurement applies to (daily only) |
| `sampleDuration` | string | Averaging period (e.g. 24 HOUR, 1 HOUR) |
| `units` | string | Unit of measure |
| `value` | number | Measured concentration or reading |
| `date` | string | Measurement date (YYYY-MM-DD) |
| `time` | string | Measurement time in local timezone (hourly only) |
| `datetimeLocal` | string | Combined local date-time (hourly only) |
| `datetimeGmt` | string | Combined GMT date-time (hourly only) |
| `aqi` | number | Air Quality Index (daily only) |
| `observationCount` | number | Number of valid observations (daily only) |
| `eventType` | string | Exceptional event type (daily only) |
| `method` | string | Sampling method description |
| `latitude` | number | Monitor latitude |
| `longitude` | number | Monitor longitude |
| `cbsaCode` | string | Core Based Statistical Area code |
| `cbsaName` | string | CBSA name |
| `openDate` | string | Monitor open date (monitors endpoint only) |
| `closeDate` | string | Monitor close date if inactive (monitors endpoint only) |
| `monitoringAgency` | string | Agency operating the monitor (monitors endpoint only) |
| `monitorType` | string | Monitor classification (e.g. SLAMS, monitors endpoint only) |
| `measurementScale` | string | Geographic measurement scale (monitors endpoint only) |
| `sampleFrequency` | string | Sample collection frequency (hourly only) |
| `qualifier` | string | Data qualifier flags (hourly only) |
| `methodType` | string | FRM/FEM classification (hourly only) |
| `scrapedAt` | string | ISO timestamp when the record was collected |
| `error` | string | Error message if extraction failed |

**Sample records (dailyDataByCounty, PM2.5, Los Angeles 2024-01-01):**

```json
[
  {
    "stateCode": "06",
    "countyCode": "037",
    "siteNumber": "4008",
    "stateName": "California",
    "countyName": "Los Angeles",
    "cityName": "Long Beach",
    "localSiteName": "Long Beach-Route 710 Near Road",
    "siteAddress": "5895 Long Beach Blvd.",
    "parameterCode": "88101",
    "parameterName": "PM2.5 - Local Conditions",
    "poc": 1,
    "datum": "NAD83",
    "pollutantStandard": "PM25 24-hour 2006",
    "sampleDuration": "24 HOUR",
    "units": "Micrograms/cubic meter (LC)",
    "value": 30.7,
    "date": "2024-01-01",
    "aqi": 91,
    "observationCount": 1,
    "eventType": "No Events",
    "method": "R & P Model 2025 PM-2.5 Sequential Air Sampler w/VSCC - Gravimetric",
    "latitude": 33.859662,
    "longitude": -118.200707,
    "cbsaCode": "31080",
    "cbsaName": "Los Angeles-Long Beach-Anaheim, CA",
    "scrapedAt": "2026-05-21T10:00:00.000Z",
    "error": null
  },
  {
    "stateCode": "06",
    "countyCode": "037",
    "siteNumber": "4008",
    "stateName": "California",
    "countyName": "Los Angeles",
    "cityName": "Long Beach",
    "localSiteName": "Long Beach-Route 710 Near Road",
    "siteAddress": "5895 Long Beach Blvd.",
    "parameterCode": "88101",
    "parameterName": "PM2.5 - Local Conditions",
    "poc": 1,
    "datum": "NAD83",
    "pollutantStandard": "PM25 24-hour 2006",
    "sampleDuration": "24 HOUR",
    "units": "Micrograms/cubic meter (LC)",
    "value": 16.7,
    "date": "2024-01-02",
    "aqi": 65,
    "observationCount": 1,
    "eventType": "No Events",
    "method": "R & P Model 2025 PM-2.5 Sequential Air Sampler w/VSCC - Gravimetric",
    "latitude": 33.859662,
    "longitude": -118.200707,
    "cbsaCode": "31080",
    "cbsaName": "Los Angeles-Long Beach-Anaheim, CA",
    "scrapedAt": "2026-05-21T10:00:01.000Z",
    "error": null
  },
  {
    "stateCode": "06",
    "countyCode": "013",
    "siteNumber": "0002",
    "stateName": "California",
    "countyName": "Contra Costa",
    "cityName": "Concord",
    "localSiteName": "Concord",
    "siteAddress": "2956-A TREAT BOULEVARD",
    "parameterCode": "88101",
    "parameterName": "PM2.5 - Local Conditions",
    "poc": 1,
    "datum": "WGS84",
    "openDate": "1999-01-08",
    "closeDate": null,
    "monitoringAgency": "Bay Area Air Quality Management District",
    "monitorType": "SLAMS",
    "measurementScale": "NEIGHBORHOOD",
    "method": "R & P Model 2025 PM-2.5 Sequential Air Sampler w/VSCC - Gravimetric",
    "latitude": 37.936013,
    "longitude": -122.026154,
    "cbsaCode": "41860",
    "cbsaName": "San Francisco-Oakland-Hayward, CA",
    "scrapedAt": "2026-05-21T10:00:02.000Z",
    "error": null
  }
]
```

***

### ✨ Why choose this Actor

| Feature | Detail |
|---|---|
| 🏛️ **Authoritative source** | Connects directly to the EPA's official AQS API - the federal gold standard for U.S. ambient air quality data |
| 🧪 **11 pollutant parameters** | PM2.5, PM10, NO2, O3, CO, SO2, lead, VOCs, reactive nitrogen oxides, wind, and temperature |
| 🗺️ **3 collection modes** | Daily county summaries, hourly site samples, and active monitor inventory in one Actor |
| 📍 **10,000+ stations** | Full coverage of all state, local, and federal air monitoring networks |
| 🇺🇸 **50 states + DC** | Every U.S. jurisdiction with FIPS-coded filters |
| 📦 **Instant export** | CSV, Excel, JSON, and XML via Apify dataset download with no extra steps |
| 🔑 **No key required** | Demo credentials built-in for immediate use; personal keys unlock higher quotas |
| 💰 **Pay only for results** | Pay-per-event pricing - you are billed only for records actually delivered |

***

### 📈 How it compares to alternatives

| Method | Setup time | EPA access | Structured output | Filters |
|---|---|---|---|---|
| **This Actor** | ~2 min | Direct API | Yes | State, county, site, parameter, date |
| Manual API calls | 30-60 min | Direct | Manual | Requires knowing all FIPS and param codes |
| Data.gov downloads | 10-20 min | Bulk CSV | Partial | Limited, no per-county/site filter |
| Third-party AQI APIs | 5-10 min | Aggregated only | Yes | Limited historical depth |
| Python/R scripts | 1-4 hours | Direct | Custom | Full, but requires coding |

***

### 🚀 How to use

1. **Create a free account** - [Create a free account w/ $5 credit](https://console.apify.com/sign-up?fpr=vmoqkp)
2. **Open the Actor** - Search "EPA AQS" in the Apify Store or use the direct link.
3. **Select your dataset** - Choose Daily Summary, Hourly Samples, or Monitor Inventory.
4. **Set your filters** - Pick state, county, pollutant parameter, and date range.
5. **Run** - Click Start. Results appear in the dataset within seconds.
6. **Export** - Download as CSV, Excel, JSON, or XML from the dataset page.

***

### 💼 Business use cases

#### Environmental compliance monitoring

Regulatory teams and legal departments use daily PM2.5 and NO2 summaries to verify compliance with NAAQS standards, prepare air quality reports, and support permit applications. The daily county endpoint returns observation counts and validity flags that document data completeness.

#### Public health and epidemiology research

Researchers correlating air pollution exposure with health outcomes need clean, date-aligned measurement series. This Actor produces ready-to-join datasets keyed by FIPS codes that merge directly with census health data, hospital admissions records, and mortality tables.

#### Real estate and urban planning

Developers and planners assessing site suitability often need historical AQI profiles for neighborhoods. Daily summaries by county with AQI fields let analysts build multi-year exposure profiles and support environmental impact statements.

#### Journalism and advocacy

Reporters covering environmental justice stories need current and historical pollution data tied to specific communities. The monitor inventory endpoint identifies which neighborhoods have - and which lack - monitoring infrastructure, a key data point in coverage of monitoring gaps.

***

### 🔌 Automating EPA AQS Scraper

Connect this Actor to your existing stack without writing code:

- **Make (Integromat)** - schedule a weekly run and push results to Google Sheets or Airtable automatically.
- **Zapier** - trigger on Actor completion and forward new records to Slack, Notion, or a database.
- **Apify Scheduler** - run daily on a cron schedule to maintain a rolling air quality dataset.
- **Apify API** - call the Actor programmatically from Python, Node.js, or any HTTP client and retrieve results as JSON.
- **Webhooks** - send a POST notification to your server the moment each run completes.

***

### 🌟 Beyond business use cases

#### Academic research

Climate scientists and atmospheric chemists use AQS data to validate dispersion models, analyze long-term concentration trends, and calibrate low-cost sensor networks against federal reference monitors.

#### Citizen science and advocacy

Community air quality groups use monitor inventory data to identify monitoring deserts - areas with no nearby EPA stations - and build cases for new monitors in underserved neighborhoods.

#### Educational projects

Data journalism students and GIS courses use this Actor to build choropleth maps, time-series charts, and exposure analyses without navigating the raw EPA API or decoding FIPS schemas.

#### Open data and journalism tools

Open-data journalists and data aggregators use the Actor to keep local environmental dashboards current, pairing it with census data to show per-capita exposure by income bracket or demographic group.

***

### 🤖 Ask an AI assistant about this scraper

You can ask your AI assistant questions like:

- "What fields does the EPA AQS daily summary endpoint return?"
- "How do I get hourly ozone readings for a specific monitoring site?"
- "What is the difference between dailyDataByCounty and sampleDataBySite?"
- "Show me how to use the Apify API to run the EPA AQS scraper and retrieve results."
- "What FIPS code does Los Angeles County use?"

This Actor is designed for straightforward integration. The output schema is consistent and well-documented above.

***

### ❓ Frequently Asked Questions

#### ❓ Do I need an EPA account to use this Actor?

No. The Actor ships with shared demo credentials that work immediately. For production use or higher data volumes, register a free account at [aqs.epa.gov/data/api/signup](https://aqs.epa.gov/data/api/signup).

#### ❓ What is the maximum date range per query?

The EPA AQS API accepts a maximum of one calendar year per query. For multi-year datasets, run the Actor once per year and combine the outputs.

#### ❓ Why are some fields null in certain records?

Some fields are endpoint-specific. `time`, `datetimeLocal`, and `datetimeGmt` are only populated for hourly sample data. `openDate`, `closeDate`, `monitoringAgency`, and `monitorType` are only populated for the monitor inventory endpoint. `aqi`, `observationCount`, and `pollutantStandard` are only populated for daily summaries.

#### ❓ What pollutant codes are supported?

The Actor supports 11 parameter codes: PM2.5 FRM (88101), PM2.5 non-FRM (88502), PM10 (81102), CO (42101), SO2 (42401), NO2 (42602), O3 (44201), Lead (14129), Reactive NOx (42600), Wind (WIND), and Temperature (TEMP).

#### ❓ How do I find the FIPS code for my county?

FIPS codes are standardized federal identifiers. The state FIPS is the two-digit code (06 = California, 48 = Texas). County FIPS is three digits (037 = Los Angeles County). You can look them up at the U.S. Census Bureau or use the stateCode dropdown which lists all 51 jurisdictions.

#### ❓ How do I find a specific site number?

Use the `monitorsByState` endpoint first to get a list of all monitoring sites in your target state. The `siteNumber` field in those records can then be used as input for the `sampleDataBySite` endpoint.

#### ❓ What is the AQI field?

The Air Quality Index is the EPA's standardized 0-500 scale for communicating pollution levels to the public. It is calculated from the concentration and varies by pollutant. It is only available in the daily summary endpoint.

#### ❓ What does POC mean?

Parameter Occurrence Code distinguishes multiple monitors measuring the same pollutant at the same site. POC 1 is usually the primary monitor. Most use cases can filter to POC 1.

#### ❓ Can I get data for all counties in a state at once?

The EPA AQS API requires county-level filtering for daily summaries. To collect all counties in a state, run the Actor once per county or use the `monitorsByState` endpoint to first identify which counties have monitoring stations for your parameter.

#### ❓ How current is the data?

The EPA AQS database is updated continuously as state and local agencies submit data. Recent data (last 60-90 days) may be preliminary. Finalized data is typically available within 90 days of the measurement date.

#### ❓ Is the data free?

Yes. The EPA AQS is a public federal database. Access is free with registration. This Actor charges only for the compute and data transfer on Apify's platform.

#### ❓ What does CBSA mean?

Core Based Statistical Area - the U.S. Census Bureau's classification for metropolitan and micropolitan statistical areas. The `cbsaCode` and `cbsaName` fields identify the broader urban region a monitoring site belongs to.

***

### 🔌 Integrate with any app

Export your dataset and connect it to the tools you already use:

- **Google Sheets** - paste the JSON/CSV link into the IMPORTDATA formula
- **Power BI / Tableau** - connect via the Apify dataset REST endpoint
- **Python pandas** - `pd.read_json("https://api.apify.com/v2/datasets/{id}/items")`
- **R / tidyverse** - `jsonlite::fromJSON(url)` or use `httr`
- **PostgreSQL / MySQL** - load the CSV export with COPY or LOAD DATA
- **Zapier** - trigger on Actor finish, push rows to Google Sheets, Airtable, or Slack
- **Make (Integromat)** - schedule runs and route records to any connected app
- **Apify API** - `/v2/acts/parseforge~epa-aqs-air-quality-scraper/runs` with POST

***

### 🔗 Recommended Actors

| Actor | Description |
|---|---|
| [OurAirports Global Airport Database Scraper](https://apify.com/parseforge/ourairports-scraper) | Export 85,000+ airports, heliports, and airfields worldwide with ICAO, IATA, GPS coordinates, and service status |
| [FAA Aircraft Registry Scraper](https://apify.com/parseforge/faa-aircraft-registry-scraper) | Full FAA N-number aircraft registry with ownership, type, status, and airworthiness data |
| [FINRA BrokerCheck Scraper](https://apify.com/parseforge/finra-brokercheck-scraper) | Export FINRA-registered broker and firm records including disclosures, licenses, and employment history |

> 💡 **Pro Tip:** browse the complete [ParseForge collection](https://apify.com/parseforge) to find scrapers for government databases, financial data, and public records that pair well with environmental datasets.

Need help or found a bug? Open an issue on the [Apify Community Forum](https://community.apify.com/).

***

**Disclaimer:** This Actor retrieves publicly available data from the U.S. EPA Air Quality System API. All data is sourced directly from the EPA and is subject to the EPA's terms of use. ParseForge is not affiliated with the U.S. Environmental Protection Agency. Measurement values, especially recent data, may be preliminary and subject to revision by the EPA.

# Actor input Schema

## `maxItems` (type: `integer`):

Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000

## `endpoint` (type: `string`):

Which EPA AQS dataset to export.

## `parameter` (type: `string`):

EPA parameter code for the pollutant.

## `stateCode` (type: `string`):

Two-digit state FIPS code. Required for monitorsByState and dailyDataByCounty.

## `countyCode` (type: `string`):

Three-digit county FIPS code (required for dailyDataByCounty). Example: '037' for Los Angeles County, CA.

## `siteNumber` (type: `string`):

Four-digit monitor site number (required for sampleDataBySite).

## `startDate` (type: `string`):

Start date in YYYYMMDD format.

## `endDate` (type: `string`):

End date in YYYYMMDD format. Max one year per query.

## `email` (type: `string`):

Optional. Defaults to the shared demo account. For higher quotas, register a free account at the EPA AQS data service and supply your own email + access key.

## `accessKey` (type: `string`):

Optional. Defaults to the shared demo key. Personal access key issued by the EPA AQS data service when you registered.

## Actor input object example

```json
{
  "maxItems": 10,
  "endpoint": "dailyDataByCounty",
  "parameter": "88101",
  "stateCode": "06",
  "countyCode": "037",
  "siteNumber": "0080",
  "startDate": "20240101",
  "endDate": "20240131"
}
```

# Actor output Schema

## `results` (type: `string`):

Scraped EPA air quality records

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "maxItems": 10,
    "endpoint": "dailyDataByCounty",
    "parameter": "88101",
    "stateCode": "06",
    "countyCode": "037",
    "siteNumber": "0080",
    "startDate": "20240101",
    "endDate": "20240131"
};

// Run the Actor and wait for it to finish
const run = await client.actor("parseforge/epa-aqs-air-quality-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "maxItems": 10,
    "endpoint": "dailyDataByCounty",
    "parameter": "88101",
    "stateCode": "06",
    "countyCode": "037",
    "siteNumber": "0080",
    "startDate": "20240101",
    "endDate": "20240131",
}

# Run the Actor and wait for it to finish
run = client.actor("parseforge/epa-aqs-air-quality-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "maxItems": 10,
  "endpoint": "dailyDataByCounty",
  "parameter": "88101",
  "stateCode": "06",
  "countyCode": "037",
  "siteNumber": "0080",
  "startDate": "20240101",
  "endDate": "20240131"
}' |
apify call parseforge/epa-aqs-air-quality-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=parseforge/epa-aqs-air-quality-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "EPA Air Quality System (AQS) Scraper",
        "description": "Export U.S. ambient air-quality measurements from EPA's Air Quality System: daily summaries by county, hourly sample readings by monitor site, and active monitor inventory by state. Covers PM2.5, PM10, NO2, O3, CO, SO2, lead, VOCs and meteorological data from 10,000+ monitoring stations.",
        "version": "0.1",
        "x-build-id": "KbJgog3EG0CrcR5I5"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/parseforge~epa-aqs-air-quality-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-parseforge-epa-aqs-air-quality-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/parseforge~epa-aqs-air-quality-scraper/runs": {
            "post": {
                "operationId": "runs-sync-parseforge-epa-aqs-air-quality-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/parseforge~epa-aqs-air-quality-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-parseforge-epa-aqs-air-quality-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "maxItems": {
                        "title": "Max Items",
                        "minimum": 1,
                        "maximum": 1000000,
                        "type": "integer",
                        "description": "Free users: Limited to 10 items (preview). Paid users: Optional, max 1,000,000"
                    },
                    "endpoint": {
                        "title": "Dataset",
                        "enum": [
                            "dailyDataByCounty",
                            "sampleDataBySite",
                            "monitorsByState"
                        ],
                        "type": "string",
                        "description": "Which EPA AQS dataset to export."
                    },
                    "parameter": {
                        "title": "Pollutant Parameter",
                        "enum": [
                            "88101",
                            "88502",
                            "81102",
                            "42101",
                            "42401",
                            "42602",
                            "44201",
                            "14129",
                            "42600",
                            "WIND",
                            "TEMP"
                        ],
                        "type": "string",
                        "description": "EPA parameter code for the pollutant."
                    },
                    "stateCode": {
                        "title": "State FIPS Code",
                        "enum": [
                            "01",
                            "02",
                            "04",
                            "05",
                            "06",
                            "08",
                            "09",
                            "10",
                            "11",
                            "12",
                            "13",
                            "15",
                            "16",
                            "17",
                            "18",
                            "19",
                            "20",
                            "21",
                            "22",
                            "23",
                            "24",
                            "25",
                            "26",
                            "27",
                            "28",
                            "29",
                            "30",
                            "31",
                            "32",
                            "33",
                            "34",
                            "35",
                            "36",
                            "37",
                            "38",
                            "39",
                            "40",
                            "41",
                            "42",
                            "44",
                            "45",
                            "46",
                            "47",
                            "48",
                            "49",
                            "50",
                            "51",
                            "53",
                            "54",
                            "55",
                            "56"
                        ],
                        "type": "string",
                        "description": "Two-digit state FIPS code. Required for monitorsByState and dailyDataByCounty."
                    },
                    "countyCode": {
                        "title": "County FIPS Code",
                        "type": "string",
                        "description": "Three-digit county FIPS code (required for dailyDataByCounty). Example: '037' for Los Angeles County, CA."
                    },
                    "siteNumber": {
                        "title": "Site Number",
                        "type": "string",
                        "description": "Four-digit monitor site number (required for sampleDataBySite)."
                    },
                    "startDate": {
                        "title": "Start Date (YYYYMMDD)",
                        "type": "string",
                        "description": "Start date in YYYYMMDD format."
                    },
                    "endDate": {
                        "title": "End Date (YYYYMMDD)",
                        "type": "string",
                        "description": "End date in YYYYMMDD format. Max one year per query."
                    },
                    "email": {
                        "title": "Registered Email (optional)",
                        "type": "string",
                        "description": "Optional. Defaults to the shared demo account. For higher quotas, register a free account at the EPA AQS data service and supply your own email + access key."
                    },
                    "accessKey": {
                        "title": "Access Key (optional)",
                        "type": "string",
                        "description": "Optional. Defaults to the shared demo key. Personal access key issued by the EPA AQS data service when you registered."
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
