# OpenAQ Air Quality Data Search (`ryanclinton/openaq-air-quality`) Actor

OpenAQ Air Quality Data Search is an Apify actor that retrieves real-time and historical air pollution measurements from the OpenAQ platform -- the world's largest open-source database of air quality data.

- **URL**: https://apify.com/ryanclinton/openaq-air-quality.md
- **Developed by:** [Ryan Clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Stats:** 15 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 4.00 out of 5 stars

## Pricing

from $1.00 / 1,000 measurement fetcheds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — 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

## OpenAQ Air Quality Data Search

OpenAQ Air Quality Data Search is an Apify actor that retrieves real-time and historical air pollution measurements from the OpenAQ platform -- the world's largest open-source database of air quality data. It connects to the OpenAQ v3 API to pull structured readings from thousands of government-run monitoring stations across 100+ countries, covering six key pollutants: PM2.5, PM10, ozone (O3), nitrogen dioxide (NO2), sulfur dioxide (SO2), and carbon monoxide (CO).

Each record includes the concentration value, measurement units, station metadata, GPS coordinates, UTC and local timestamps, and the original data provider. Two modes are supported -- latest readings for real-time snapshots and historical date-range queries for time-series analysis. Whether you need to track urban pollution, compare air quality across countries, build research datasets, or automate pollution alerts, this actor provides a clean pipeline from the global OpenAQ network to a structured Apify dataset. A free OpenAQ API key is all you need.

***

### Why use OpenAQ Air Quality Data Search?

- **No coding required** -- Skip API pagination, sensor mapping, and data normalization. Configure your search in the console and get clean results.
- **Managed cloud infrastructure** -- Run on Apify without provisioning servers. Schedule recurring runs for continuous monitoring.
- **Instant export and integration** -- Push results to Google Sheets, Slack, S3, webhooks, or Zapier using built-in connectors.
- **Free data source** -- The OpenAQ API key costs nothing. Daily collection runs under $1 per month on Apify's free tier.
- **Consistent, flat output** -- Every record follows the same 17-field schema regardless of country or network.
- **Programmatic access** -- Trigger runs via the Apify REST API or official Python and JavaScript clients.

***

### Key features

- **Six pollutant parameters** -- Query PM2.5, PM10, ozone, NO2, SO2, or CO concentrations from a single interface with standardized output fields.
- **100+ country coverage** -- Access real-time pollution data from government monitoring stations worldwide using ISO 3166-1 alpha-2 country codes.
- **Geographic proximity search** -- Find stations near any latitude/longitude coordinate within a configurable radius up to 25 km for localized assessments.
- **City-level filtering** -- Narrow results to a specific city with intelligent partial matching on station names and locality fields.
- **Two operating modes** -- Retrieve the latest available readings for a real-time snapshot, or specify a date range for historical time-series data.
- **Structured, normalized output** -- Each record includes 17 fields: station name, city, country, GPS coordinates, pollutant type, value, unit, UTC/local timestamps, monitor type, and data source.
- **Configurable result limits** -- Control output volume from 1 to 1,000 records per run to fit your use case and budget.
- **Dry-run mode** -- Run without an API key to preview the output schema and sample data before configuring production queries.
- **Summary logging** -- Each run logs value range (min/max/average), countries covered, and unique station count for quick validation.
- **Lightweight execution** -- Runs on 256 MB memory in 10--30 seconds with no browser rendering or heavy computation.

***

### How to use

#### Apify Console

1. **Get a free API key.** Visit [explore.openaq.org](https://explore.openaq.org), create a free account, and copy your API key from account settings.
2. **Open the actor.** Navigate to the [OpenAQ Air Quality Data Search](https://apify.com/ryanclinton/openaq-air-quality) page on the Apify Store and click "Start".
3. **Enter your API key.** Paste it into the "OpenAQ API Key" field. The field is encrypted and marked as secret.
4. **Set your filters.** Choose a country code, optionally enter a city name, select a pollutant, and configure any date range or coordinate filters.
5. **Run and export.** Click "Start" and wait for results in the Dataset tab. Download as JSON, CSV, or Excel, or use integrations for automated delivery.

#### API (Python)

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("XXDvwdapkYoEC8dyx").call(run_input={
    "apiKey": "YOUR_OPENAQ_KEY",
    "country": "US",
    "city": "Los Angeles",
    "parameter": "pm25",
    "maxResults": 50,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['locationName']}: {item['value']} {item['unit']}")
```

#### API (JavaScript)

```javascript
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_APIFY_TOKEN" });
const run = await client.actor("XXDvwdapkYoEC8dyx").call({
    apiKey: "YOUR_OPENAQ_KEY",
    country: "GB",
    city: "London",
    parameter: "no2",
    maxResults: 50,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => console.log(`${item.locationName}: ${item.value} ${item.unit}`));
```

***

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `apiKey` | String | Yes | -- | Your free OpenAQ API key from [explore.openaq.org](https://explore.openaq.org). Without it, the actor runs in dry-run mode. |
| `country` | String | No | `US` | ISO 3166-1 alpha-2 country code (e.g., `US`, `GB`, `IN`, `CN`, `DE`). Leave empty for worldwide. |
| `city` | String | No | -- | Filter stations by city or locality name. Uses partial matching on station names and locality fields. |
| `parameter` | Select | No | `pm25` | Pollutant to measure: `pm25`, `pm10`, `o3`, `no2`, `so2`, or `co`. |
| `dateFrom` | String | No | -- | Start date in `YYYY-MM-DD` format for historical data. Omit for latest readings. |
| `dateTo` | String | No | -- | End date in `YYYY-MM-DD` format for historical data. Omit for latest readings. |
| `latitude` | Number | No | -- | Latitude for proximity search. Use with `longitude` and optionally `radius`. |
| `longitude` | Number | No | -- | Longitude for proximity search. Use with `latitude` and optionally `radius`. |
| `radius` | Integer | No | `25000` | Search radius in meters from coordinates. Range: 1--25,000 (25 km). |
| `maxResults` | Integer | No | `100` | Maximum measurement records to return. Range: 1--1,000. |

#### Input JSON example

```json
{
    "apiKey": "YOUR_OPENAQ_KEY",
    "country": "IN",
    "city": "Delhi",
    "parameter": "pm25",
    "dateFrom": "2025-12-01",
    "dateTo": "2025-12-31",
    "maxResults": 200
}
```

#### Tips

- **PM2.5 has the best global coverage.** Other parameters like SO2 or CO may have fewer reporting stations in some regions.
- **Coordinate search is ideal for hyperlocal analysis** -- pair latitude/longitude with a small radius to find the nearest stations to a school, hospital, or factory.
- **Omit date fields for real-time data.** The actor fetches the latest available reading from each station when no date range is specified.

***

### Output

Each run produces a dataset of air quality measurement records with 17 fields per record.

#### Output JSON example

```json
[
    {
        "locationId": 2178,
        "locationName": "Del Norte",
        "city": "Albuquerque",
        "country": "United States",
        "countryCode": "US",
        "latitude": 35.1353,
        "longitude": -106.5847,
        "parameter": "pm25",
        "parameterDisplayName": "PM2.5",
        "value": 8.3,
        "unit": "ug/m3",
        "dateUtc": "2025-01-15T12:00:00Z",
        "dateLocal": "2025-01-15T05:00:00-07:00",
        "isMonitor": true,
        "isMobile": false,
        "sourceName": "AirNow",
        "extractedAt": "2025-01-15T14:30:00.000Z"
    },
    {
        "locationId": 8714,
        "locationName": "Anand Vihar",
        "city": "Delhi",
        "country": "India",
        "countryCode": "IN",
        "latitude": 28.6508,
        "longitude": 77.3152,
        "parameter": "pm25",
        "parameterDisplayName": "PM2.5",
        "value": 156.4,
        "unit": "ug/m3",
        "dateUtc": "2025-01-15T10:30:00Z",
        "dateLocal": "2025-01-15T16:00:00+05:30",
        "isMonitor": true,
        "isMobile": false,
        "sourceName": "CPCB",
        "extractedAt": "2025-01-15T14:30:00.000Z"
    }
]
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `locationId` | Integer | OpenAQ station identifier |
| `locationName` | String | Monitoring station name |
| `city` | String | City or locality of the station |
| `country` | String | Full country name |
| `countryCode` | String | ISO alpha-2 country code |
| `latitude` | Number | Station latitude |
| `longitude` | Number | Station longitude |
| `parameter` | String | Pollutant code (`pm25`, `no2`, `o3`, etc.) |
| `parameterDisplayName` | String | Display name (`PM2.5`, `NO2`, etc.) |
| `value` | Number | Measured concentration |
| `unit` | String | Unit (typically `ug/m3` or `ppm`) |
| `dateUtc` | String | Measurement timestamp in UTC |
| `dateLocal` | String | Measurement timestamp in local timezone |
| `isMonitor` | Boolean | Reference-grade monitor flag |
| `isMobile` | Boolean | Mobile station flag |
| `sourceName` | String | Data provider (AirNow, DEFRA, CPCB, etc.) |
| `extractedAt` | String | Actor extraction timestamp |

***

### Use cases

- **Urban pollution monitoring** -- Track PM2.5 and NO2 across major cities to identify pollution hotspots and assess trends.
- **Health impact research** -- Build historical datasets for epidemiological studies linking pollution to respiratory outcomes.
- **Regulatory compliance** -- Monitor whether pollutant concentrations in industrial zones stay within WHO or national thresholds.
- **Environmental journalism** -- Gather data-driven evidence on pollution sources, seasonal patterns, and cross-border events.
- **Real estate analysis** -- Compare air quality across neighborhoods for property buyers and renters.
- **Smart city dashboards** -- Feed live readings into municipal dashboards and public-facing community displays.
- **Wildfire smoke tracking** -- Monitor PM2.5 spikes during wildfire season to assess smoke dispersion and health impact.
- **Academic research** -- Collect structured time-series data for climate science, atmospheric modeling, and ML projects.
- **Supply chain risk** -- Evaluate air quality at manufacturing sites and logistics hubs impacting worker health.
- **Community alerts** -- Automate notifications when local pollution exceeds safe thresholds via scheduled runs and webhooks.

***

### API and integration

#### Python

```python
from apify_client import ApifyClient
client = ApifyClient("YOUR_APIFY_TOKEN")
run = client.actor("XXDvwdapkYoEC8dyx").call(run_input={
    "apiKey": "YOUR_OPENAQ_KEY",
    "country": "DE",
    "parameter": "o3",
    "maxResults": 100,
})
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(f"{item['locationName']} ({item['countryCode']}): {item['value']} {item['unit']}")
```

#### JavaScript

```javascript
import { ApifyClient } from "apify-client";
const client = new ApifyClient({ token: "YOUR_APIFY_TOKEN" });
const run = await client.actor("XXDvwdapkYoEC8dyx").call({
    apiKey: "YOUR_OPENAQ_KEY",
    country: "IN",
    city: "Mumbai",
    parameter: "pm10",
    maxResults: 100,
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(`Retrieved ${items.length} measurements`);
```

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/XXDvwdapkYoEC8dyx/runs?token=YOUR_APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "apiKey": "YOUR_OPENAQ_KEY",
    "country": "US",
    "city": "Chicago",
    "parameter": "pm25",
    "maxResults": 50
  }'
```

#### Integrations

- **Google Sheets** -- Export air quality data to spreadsheets for visualization and sharing.
- **Slack / Email** -- Send alerts when pollutant levels exceed health thresholds.
- **Amazon S3 / Google Cloud Storage** -- Archive historical measurements for long-term analysis.
- **Webhooks** -- Push new readings to your own API endpoint for real-time processing.
- **Zapier / Make** -- Connect air quality data to thousands of apps without code.

***

### How it works

The actor follows a multi-stage pipeline to retrieve and normalize air quality data from the OpenAQ v3 API.

1. **Input validation** -- Maps the selected pollutant to an OpenAQ parameter ID (e.g., `pm25` to ID `2`, `no2` to ID `7`).
2. **Location discovery** -- Queries `/locations` with country code, parameter ID, and optional coordinate/radius filters.
3. **City filtering** -- Client-side partial matching on station names and locality fields.
4. **Latest mode** -- Without date range, fetches the most recent reading via `/locations/{id}/latest`.
5. **Historical mode** -- With `dateFrom`/`dateTo`, fetches sensor measurements via `/sensors/{id}/measurements`.
6. **Normalization** -- Transforms responses into a flat 17-field schema consistent across all networks.
7. **Output** -- Pushes records to the Apify dataset and logs a summary (value range, countries, station count).

```
  Input Parameters
        |
        v
  [ Validate & Map Pollutant to ID ]
        |
        v
  [ GET /locations (country, coords, parameter_id) ]
        |
        v
  [ City Filter (partial match) ]
        |
   +----+----+
   |         |
   v         v
 No Date   Date Range
 Range     Specified
   |         |
   v         v
 GET        GET
 /locations /sensors/{id}/
 /{id}/     measurements
 latest       |
   |         |
   +----+----+
        |
        v
  [ Normalize to 17 output fields ]
        |
        v
  Apify Dataset + Summary Log
```

***

### Performance and cost

| Scenario | Stations | Results | Memory | Duration | Est. Cost |
|----------|----------|---------|--------|----------|-----------|
| Single city, latest PM2.5 | 5--15 | 10--15 | 256 MB | ~10 sec | ~$0.001 |
| Country-wide US, latest NO2 | 50--200 | 100 | 256 MB | ~15 sec | ~$0.002 |
| City + date range, 1 month | 10--30 | 200 | 256 MB | ~20 sec | ~$0.003 |
| Worldwide PM2.5, max results | 500+ | 1,000 | 256 MB | ~30 sec | ~$0.005 |
| Daily scheduled run (30 days) | varies | 100/day | 256 MB | ~15 sec/run | ~$0.06/mo |

The OpenAQ API key is completely free with no usage fees. All costs above are Apify platform compute credits only.

***

### Limitations

- **API key required** -- A free OpenAQ API key is mandatory for fetching real data. Without it, the actor runs in dry-run mode with sample output only.
- **Maximum 1,000 results per run** -- The actor caps output at 1,000 measurement records. For larger datasets, run multiple queries with different filters.
- **Radius limit of 25 km** -- Geographic proximity search is capped at 25,000 meters from the specified coordinates.
- **Data freshness varies** -- Most government monitoring networks report with a 1--6 hour delay. The `dateUtc` field shows the actual measurement time.
- **City filtering is client-side** -- City name matching uses partial string comparison on station names and locality fields, which may miss stations with unconventional naming.
- **Six pollutants only** -- The actor supports PM2.5, PM10, O3, NO2, SO2, and CO. Other parameters available in OpenAQ (e.g., BC, NH3) are not currently mapped.
- **Station coverage varies by region** -- Developed countries typically have denser monitoring networks. Rural and developing regions may have sparse or no coverage for certain pollutants.

***

### Responsible use

- **Verify critical decisions against primary sources.** For regulatory compliance or public health advisories, cross-check data against the original government monitoring network (e.g., EPA AirNow, DEFRA, CPCB). The `sourceName` field identifies the original provider.
- **Respect OpenAQ terms of service.** OpenAQ provides data under open licenses for public benefit. Do not use the data in ways that misrepresent pollution levels or mislead the public.
- **Attribute data sources appropriately.** When publishing or sharing air quality data collected through this actor, credit both OpenAQ and the original monitoring network.
- **Use scheduled runs responsibly.** While the API is free, avoid unnecessary high-frequency polling. Hourly or daily collection is sufficient for most monitoring use cases.
- **Contextualize measurements properly.** Raw pollutant concentrations require context -- always reference WHO guidelines or national air quality standards when interpreting values.

***

### FAQ

**Do I need to pay for an OpenAQ API key?**

No. The OpenAQ API key is completely free. Visit [explore.openaq.org](https://explore.openaq.org), create an account, and generate your key at no cost. OpenAQ is a nonprofit organization providing universally accessible air quality data.

**What countries are covered?**

OpenAQ aggregates data from government networks in 100+ countries, including the US (EPA/AirNow), UK (DEFRA), India (CPCB), China (MEE), Germany (UBA), France, Australia, Brazil, and more.

**How current is the data?**

Without date filters, the actor fetches the latest reading from each station. Most networks report with a 1--6 hour delay. The `dateUtc` field shows the exact measurement time.

**What is dry-run mode?**

Running without an API key outputs sample data and instructions for obtaining a free key. This lets you preview the output schema before production use.

**What is the difference between PM2.5 and PM10?**

PM2.5 measures fine particles 2.5 micrometers or smaller that penetrate deep into lungs and bloodstream -- the most health-critical pollutant. PM10 covers coarser particles up to 10 micrometers, including dust and pollen. Both are measured in micrograms per cubic meter.

**Can I get historical data?**

Yes. Set `dateFrom` and `dateTo` in `YYYY-MM-DD` format. The actor switches to the sensor-level measurements endpoint for date-range queries.

**How do I search near a specific address?**

Convert your address to coordinates using a geocoding service or the Nominatim Geocoder actor, then provide latitude, longitude, and radius.

**Why are some stations missing?**

Station availability depends on the network's reporting status. Some stations go offline for maintenance, and not all stations measure every pollutant. Try broadening your radius or switching to PM2.5, which has the widest coverage.

**Can I schedule recurring collection?**

Yes. Use Apify's scheduling feature to run the actor hourly, daily, or at any custom interval. Results accumulate in your dataset, building a comprehensive pollution time-series.

**What units are the measurements in?**

Most pollutants are reported in micrograms per cubic meter (ug/m3). Carbon monoxide may use parts per million (ppm). The `unit` field in each record specifies the exact unit.

**How do I compare readings against health guidelines?**

The WHO annual PM2.5 guideline is 5 ug/m3, and the 24-hour guideline is 15 ug/m3. The US EPA AQI uses different breakpoints. Cross-reference the `value` and `parameter` fields with the appropriate standard for your region.

**Can I use the Apify API?**

Yes. Use actor ID `XXDvwdapkYoEC8dyx` or slug `ryanclinton/openaq-air-quality` with the REST API, Python client, or JS client.

***

### Related actors

| Actor | Description |
|-------|-------------|
| [NOAA Weather Alert Monitor](https://apify.com/ryanclinton/noaa-weather-alerts) | Combine severe weather alerts with air quality data for comprehensive environmental monitoring. |
| [GDACS Disaster Alerts](https://apify.com/ryanclinton/gdacs-disaster-alerts) | Track natural disasters like wildfires and volcanic eruptions that directly impact air quality levels. |
| [Weather Forecast Search](https://apify.com/ryanclinton/weather-forecast-search) | Pair air pollution data with weather forecasts for environmental and health impact analysis. |
| [Nominatim Geocoder](https://apify.com/ryanclinton/nominatim-geocoder) | Convert street addresses to latitude/longitude coordinates for precise location-based station searches. |
| [UK Flood Warnings](https://apify.com/ryanclinton/uk-flood-warnings) | Monitor UK flood warnings alongside air quality data for multi-hazard environmental dashboards. |
| [World Bank Development Indicators](https://apify.com/ryanclinton/world-bank-indicators) | Correlate air pollution levels with economic development indicators for cross-country research. |

# Actor input Schema

## `apiKey` (type: `string`):

Your OpenAQ API key. Get a free key at https://explore.openaq.org (sign up, then find your API key in account settings).

## `country` (type: `string`):

ISO 3166-1 alpha-2 country code (e.g. US, GB, IN, CN, DE). Leave empty for worldwide.

## `city` (type: `string`):

Filter locations by locality/city name (partial match on location name).

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

Air quality parameter to measure.

## `dateFrom` (type: `string`):

Start date for measurements in YYYY-MM-DD format. Used when fetching historical sensor data.

## `dateTo` (type: `string`):

End date for measurements in YYYY-MM-DD format. Used when fetching historical sensor data.

## `latitude` (type: `number`):

Latitude for location-based search (use with longitude and radius).

## `longitude` (type: `number`):

Longitude for location-based search (use with latitude and radius).

## `radius` (type: `integer`):

Search radius in meters from coordinates. Max 25000 (25km). Default 25000.

## `maxResults` (type: `integer`):

Maximum number of results to return. Default 100, max 1000.

## Actor input object example

```json
{
  "country": "US",
  "parameter": "pm25",
  "radius": 25000,
  "maxResults": 100
}
```

# Actor output Schema

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

No description

# 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 = {
    "country": "US"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/openaq-air-quality").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 = { "country": "US" }

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

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

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

```

## CLI example

```bash
echo '{
  "country": "US"
}' |
apify call ryanclinton/openaq-air-quality --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,ryanclinton/openaq-air-quality"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/XXDvwdapkYoEC8dyx/builds/dxQ99uoqLYLWRUbk4/openapi.json
