GuidesAIR QUALITY APIS
Free air quality API for JavaScript
For a free air quality API you can call from browser JavaScript, start with Open-Meteo: no key, Access-Control-Allow-Origin: *, and current European and US AQI plus a 5-day hourly forecast, free for non-commercial use up to 10,000 calls a day. Eight of the 9 APIs we tested on 28 October 2026 work with fetch() directly, including WAQI, AirNow, IQAir and OpenWeather with a key in the URL. OpenAQ v3 is the exception: it takes its key only in an X-API-Key header and answers the browser's preflight with 401, so call it from a server or through cors.dev Pro, $5 a month for 500,000 requests with a 7-day trial of 1,000 requests and no card.
Which air quality API works from the browser
Each API was called on 28 October 2026 with Origin: https://example.com, as a browser sends it, then through https://proxy.cors.dev/. Eight of the 9 send CORS headers that let fetch() read the response on any site; only OpenAQ v3 is blocked.
| API | Free tier | Key | Browser CORS | Through cors.dev |
|---|---|---|---|---|
| Open-Meteo Air Quality | 10,000 calls a day, non-commercial | None | Yes, any origin | Not needed |
| Sensor.Community | Free open data | None | Yes, any origin | Not needed |
| WAQI (aqicn.org) | Free, no paid apps | token in the URL | Yes, any origin | Not needed |
| AirNow (US EPA) | Free, hourly limit per key | API_KEY in the URL | Yes, any origin | Not needed |
| IQAir AirVisual | 10,000 calls a month, 500 a day | key in the URL | Yes, any origin | Not needed |
| OpenWeather Air Pollution | 1,000,000 calls a month | appid in the URL | Yes, any origin | Not needed |
| PurpleAir | 1,000,000 points at signup | X-API-Key header or api_key | Yes, any origin | Not needed |
| Google Air Quality API | 10,000 requests a month | key in the URL, POST | Yes, echoes the origin | Not needed, free tier is GET only |
| OpenAQ v3 | 60 a minute, 2,000 an hour | X-API-Key header only | No, preflight answers 401 | cors.dev Pro forwards X-API-Key |
Open-Meteo and Sensor.Community need no key
The Open-Meteo Air Quality API (air-quality-api.open-meteo.com/v1/air-quality) takes no key and sends Access-Control-Allow-Origin: *. It returns european_aqi, us_aqi, pm2_5, pm10, ozone and more as current values or hourly series, 5 days ahead by default and up to 7. For London at 22:00 on 28 October 2026 it returned a European AQI of 52, a US AQI of 36 and PM2.5 of 9.5 µg/m³.
const params = new URLSearchParams({
latitude: '51.5074',
longitude: '-0.1278',
current: 'european_aqi,us_aqi,pm2_5,pm10,nitrogen_dioxide,ozone',
timezone: 'auto',
});
// Open-Meteo sends Access-Control-Allow-Origin: *, so no proxy and no key
const response = await fetch(`https://air-quality-api.open-meteo.com/v1/air-quality?${params}`);
if (!response.ok) throw new Error(`Open-Meteo answered ${response.status}`);
const { current, current_units: units } = await response.json();
console.log(`European AQI ${current.european_aqi}, US AQI ${current.us_aqi} at ${current.time}`);
console.log(`PM2.5 ${current.pm2_5} ${units.pm2_5}, PM10 ${current.pm10} ${units.pm10}`);The values come from Copernicus CAMS models at 11 km over Europe and 45 km elsewhere, not from monitoring stations, and the free API is non-commercial with CC BY 4.0 credit. The free weather API guide covers Open-Meteo's forecast API.
Two more sources need no key and send Access-Control-Allow-Origin: *:
- Sensor.Community:
data.sensor.community/airrohr/v1/filter/area=52.52,13.405,3returned 77 readings from citizen-run sensors within 3 km of central Berlin, all from the last 5 minutes.P1is PM10 andP2is PM2.5, both sent as strings, and the data is under the Database Contents License v1. - AirNow file products:
files.airnowtech.org/airnow/today/reportingarea.datis a 1.8 MB pipe-delimited file of current AQI and forecasts for US reporting areas, updated at :10, :25 and :40 past each hour.
WAQI, AirNow, IQAir and OpenWeather with a key in the URL
These four take a free key in the query string and send Access-Control-Allow-Origin: *, even on error responses:
- WAQI (aqicn.org):
api.waqi.info/feed/{city}/?token=allows 1,000 requests a minute with bursts of up to 60 under the WAQI terms of service, though its token page says 1,000 a second. Thedemotoken returned the Shanghai station for London and for coordinates, and a bad token answered HTTP200with{"status":"error","data":"Invalid key"}, so checkstatus. Paid apps may not use the data, and WAQI and the source agency must be credited. - AirNow (US EPA): The key goes in
API_KEY, and data covers the United States, Canada and Mexico from more than 2,500 monitoring stations, with an hourly limit per web service and key. Use the services added on 17 June 2026, such as/aq/observation/current/ziplatlong/; six older ones, including/aq/observation/zipCode/current/, were set to retire on 30 September 2026. - IQAir AirVisual: The free Community plan allows 5 calls a minute, 500 a day and 10,000 a month, with city-level US and China AQI and current weather. Pollutant concentrations start on the paid Startup plan.
- OpenWeather Air Pollution: The free plan allows 60 calls a minute and 1,000,000 a month.
main.aqiuses OpenWeather's own 1 to 5 scale,componentsholds 8 pollutants in µg/m³,/air_pollution/forecastgives 4 days hourly and/air_pollution/historygoes back to 27 November 2020.
Each key sits in the URL, so any visitor can copy it from DevTools and spend your quota.
OpenAQ v3 through cors.dev Pro
OpenAQ v3 (api.openaq.org/v3) gives free keys with 60 requests a minute and 2,000 an hour, but it accepts the key only in the X-API-Key header; api_key in the query string answered 401. A custom header makes the browser send an OPTIONS preflight first, and OpenAQ answered it with 401 and no Access-Control-Allow-Origin, so the browser blocks the call before the GET leaves. The old v1 and v2 endpoints answer 410 Gone.
The free cors.dev proxy answered a request carrying X-API-Key with 400 and X-Cors-Error: header_not_allowed. cors.dev Pro forwards the header for $5 a month and 500,000 requests, with a 7-day trial of 1,000 requests and no card:
- Sign up
Create an account at cors.dev/signup with Google.
- Create a Connection
Add your exact page origin and the target host
api.openaq.org. - Send both headers
Put the Connection's publishable key in
X-Cors-Keyand your OpenAQ key inX-API-Key.
const PROXY = 'https://proxy.cors.dev/';
const OPENAQ = 'https://api.openaq.org/v3/locations/';
// X-Cors-Key is your publishable Connection key; X-API-Key stays visible in DevTools
const headers = { 'X-Cors-Key': 'YOUR_CONNECTION_KEY', 'X-API-Key': 'YOUR_OPENAQ_KEY' };
async function openAq(path) {
const response = await fetch(PROXY + OPENAQ + path, { headers });
const proxyError = response.headers.get('X-Cors-Error');
if (proxyError) throw new Error(`cors.dev: ${proxyError}`);
if (!response.ok) throw new Error(`OpenAQ answered ${response.status}`);
return (await response.json()).results;
}
const locationId = 2178;
const [[location], latest] = await Promise.all([openAq(locationId), openAq(`${locationId}/latest`)]);
// Latest readings carry only a sensor id, so we label them from the location's sensors
const parameters = new Map(location.sensors.map((sensor) => [sensor.id, sensor.parameter]));
for (const reading of latest) {
const parameter = parameters.get(reading.sensorsId);
console.log(`${parameter?.displayName}: ${reading.value} ${parameter?.units} at ${reading.datetime.utc}`);
}To find stations near a point, query /v3/locations?coordinates=lat,lng&radius= with a radius of up to 25,000 meters. OpenAQ asks you to treat the key like a password, and it stays visible in DevTools, so cors.dev Pro fits internal dashboards and prototypes; a public site should call OpenAQ from a backend.
PurpleAir and the Google Air Quality API
Both work from any origin:
- PurpleAir: The key goes in the
X-API-Keyheader or theapi_keyquery parameter, and the preflight allowsX-API-KeywithAccess-Control-Allow-Origin: *. Access is points-based: new accounts get 1,000,000 points, extra points cost from $10 at 100,000 points per dollar, and sensor owners query their own sensors for free. - Google Air Quality API:
currentConditions:lookupis aPOSTwith a JSON body and the key in thekeyquery parameter. Its preflight answered200, echoing our origin and allowingContent-Type. Billing must be enabled, the first 10,000 requests a month are free and the next cost $5.00 per 1,000 up to 100,000; restrict the key to your site's HTTP referrers.
The free cors.dev tier refuses X-API-Key with 400 and answers a POST with 405 method_not_allowed, so call both APIs directly.
Limits to plan for
- Open-Meteo: 600 calls a minute, 5,000 an hour, 10,000 a day and 300,000 a month, non-commercial only.
- OpenAQ: 60 requests a minute and 2,000 an hour per key, with
429when you go over. - IQAir Community: 5 calls a minute, 500 a day and 10,000 a month.
- OpenWeather free plan: 60 calls a minute and 1,000,000 a month.
- AirNow: An hourly limit per web service and key; observations update once an hour, so cache them.
- cors.dev: Free needs no signup and allows
GETandHEADat about 600 requests a minute per IP. cors.dev Pro allows 3,000 requests a minute per account and 100 in flight, and both tiers cap responses at 6 MiB with a 30-second upstream deadline.
Good questions.
Is there a free air quality API without an API key?
Yes. Open-Meteo returns current European and US AQI plus pollutant forecasts with no key, Sensor.Community serves citizen sensor readings, and AirNow publishes reportingarea.dat for US reporting areas. All three send Access-Control-Allow-Origin: *, so fetch() works from any page.
Why does the OpenAQ API give a CORS error in the browser?
OpenAQ v3 takes its key only in the X-API-Key header, so the browser first sends an OPTIONS preflight without the key. OpenAQ answers that preflight with 401 and no Access-Control-Allow-Origin, and the browser never sends the real request. Call OpenAQ from your server, or through cors.dev Pro, which forwards X-API-Key.
Can I use the WAQI demo token in my app?
No. The demo token returned the Shanghai station whatever city or coordinates we asked for. Request your own free token from aqicn.org, and check the status field, because a bad token still answers HTTP 200.
Which free air quality API has a forecast?
Open-Meteo returns 5 days of hourly forecasts by default and up to 7, with no key. OpenWeather's free plan includes a 4-day hourly forecast at /air_pollution/forecast, and AirNow's /aq/forecast/current/ returns the forecasts issued by US reporting agencies.
Is the Google Air Quality API free?
Partly. The first 10,000 requests a month are free, but billing must be enabled on the Google Cloud project, and further requests cost $5.00 per 1,000 up to 100,000. It sends CORS headers, so a POST with the key in the URL works from the browser once you restrict the key to your site.