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.

Air quality APIs tested from the browser, checked October 2026
APIFree tierKeyBrowser CORSThrough cors.dev
Open-Meteo Air Quality10,000 calls a day, non-commercialNoneYes, any originNot needed
Sensor.CommunityFree open dataNoneYes, any originNot needed
WAQI (aqicn.org)Free, no paid appstoken in the URLYes, any originNot needed
AirNow (US EPA)Free, hourly limit per keyAPI_KEY in the URLYes, any originNot needed
IQAir AirVisual10,000 calls a month, 500 a daykey in the URLYes, any originNot needed
OpenWeather Air Pollution1,000,000 calls a monthappid in the URLYes, any originNot needed
PurpleAir1,000,000 points at signupX-API-Key header or api_keyYes, any originNot needed
Google Air Quality API10,000 requests a monthkey in the URL, POSTYes, echoes the originNot needed, free tier is GET only
OpenAQ v360 a minute, 2,000 an hourX-API-Key header onlyNo, preflight answers 401cors.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³.

Current AQI for London from Open-Meteo, no key
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,3 returned 77 readings from citizen-run sensors within 3 km of central Berlin, all from the last 5 minutes. P1 is PM10 and P2 is 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.dat is 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. The demo token returned the Shanghai station for London and for coordinates, and a bad token answered HTTP 200 with {"status":"error","data":"Invalid key"}, so check status. 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.aqi uses OpenWeather's own 1 to 5 scale, components holds 8 pollutants in µg/m³, /air_pollution/forecast gives 4 days hourly and /air_pollution/history goes 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:

  1. Sign up

    Create an account at cors.dev/signup with Google.

  2. Create a Connection

    Add your exact page origin and the target host api.openaq.org.

  3. Send both headers

    Put the Connection's publishable key in X-Cors-Key and your OpenAQ key in X-API-Key.

Latest OpenAQ readings through cors.dev Pro
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-Key header or the api_key query parameter, and the preflight allows X-API-Key with Access-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:lookup is a POST with a JSON body and the key in the key query parameter. Its preflight answered 200, echoing our origin and allowing Content-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 429 when 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 GET and HEAD at 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.