Weather API — Forecast, Historical & Air Quality (Open-Meteo) avatar

Weather API — Forecast, Historical & Air Quality (Open-Meteo)

Pricing

$0.30 / 1,000 locations

Go to Apify Store
Weather API — Forecast, Historical & Air Quality (Open-Meteo)

Weather API — Forecast, Historical & Air Quality (Open-Meteo)

Current conditions, hourly and 16-day forecast, air quality and historical weather back to 1940 for any city or coordinates. No key, one record per location. Unofficial Open-Meteo API.

Pricing

$0.30 / 1,000 locations

Rating

0.0

(0)

Developer

yestrue

yestrue

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

2 days ago

Last modified

Share

Weather for any place on Earth as one clean JSON record per location: current conditions, an hour-by-hour forecast, a daily forecast up to 16 days out, current air quality (European and US AQI, PM10, PM2.5, NO₂, SO₂, ozone, CO, UV) and, when you ask for it, historical weather for any date range back to 1940. Give it city names or coordinates, pick metric or imperial, and every number comes back with its unit and every weather code with a plain-English description. Built on Open-Meteo's public, key-less geocoding, forecast, archive and air-quality endpoints.

Try it in 1 minute:

  1. Press Start — the prefilled input gets the weather for Berlin and New York (by name) and for 52.52,13.41 (by coordinates).
  2. Seconds later the Output tab shows three records with current conditions, 168 hourly rows, 7 daily rows and air quality each.
  3. Download JSON, CSV or Excel, or add your own places, raise Forecast days to 16, switch Units to imperial, or set Historical from / to for a past date range.

Price: $0.30 per 1,000 locations (one location = one record with current, hourly, daily, air quality and history inside). Names the geocoder does not know, invalid inputs and requests Open-Meteo refuses are free.

Use it to:

  • Feed an AI agent or chatbot that answers "what's the weather in …" with real numbers instead of guesses.
  • Pull the 16-day forecast for a list of venues, depots, farms or construction sites every morning into a sheet or a dashboard.
  • Build historical weather datasets for analysis: a year of daily and hourly temperature, rain, snow and wind for each store or city.
  • Enrich events, orders or incidents with the weather at their place and time (coordinates in, conditions out).
  • Watch air quality and UV for the cities your users live in, without signing up for a weather vendor.

How it works

  1. Locations are parsed in every form: a place name (Berlin, Paris, Texas — the part after the comma picks among same-named places), a lat,lng pair (52.52,13.41) or, via the API, { lat, lng } / { name } objects. Duplicates are dropped; an input that is neither a name nor coordinates gets a free INVALID_INPUT record.
  2. Names are resolved with Open-Meteo's geocoder (geocoding-api.open-meteo.com/v1/search) into coordinates plus the location block (name, country, region, time zone, population). No match is a free NOT_FOUND.
  3. Forecast comes from api.open-meteo.com/v1/forecast with 15 current variables, 10 hourly variables and 14 daily variables for 1-16 days in the location's own time zone. Air quality (air-quality-api.open-meteo.com) and, with a date range, the historical archive (archive-api.open-meteo.com, ERA5 reanalysis back to 1940) are fetched at the same time — 2 to 4 requests per location.
  4. Open-Meteo's arrays-per-variable answers are transposed into rows of friendly fields (temperature, feelsLike, windSpeed …), each WMO weather code gets a description, and the units of every field go into one units object on the record.

Requests go directly to Open-Meteo (no proxy, unless a connection drops); its per-IP rate limit (HTTP 429) is waited out and retried on the same route. Open-Meteo publishes no weather warnings, so alerts is always an empty list.

Input

FieldWhat it does
locationsPlaces, one per line: a name (Berlin, Paris, Texas) or lat,lng (52.52,13.41). Objects { lat, lng } / { name } via the API.
forecastDaysDays of daily and hourly forecast, 1-16 (default 7).
includeHourlyAdd the hour-by-hour forecast (default on).
unitsmetric (°C, km/h, mm; snow in cm) or imperial (°F, mph, inch).
includeAirQualityAdd current air quality (default on; one extra request).
historicalFrom, historicalToYYYY-MM-DD dates; adds historical { daily[], hourly[] } from the archive. At most 366 days per location, back to 1940-01-01; one date alone means that day.
hourlyLimitCuts the forecast's hourly list after this many hours (default 168 = 7 days, max 384).
maxConcurrencyLocations fetched in parallel (default 4).
proxyConfigurationUsed only to retry after a network error; the first try is direct.

Output

One record per location:

FieldWhat it is
location{ name, country, countryCode, admin1, timezone, population } from the geocoder; for a coordinate input only timezone is filled
lat, lng, elevation, timezone, utcOffsetSecondsThe point the weather is for, the model grid cell's elevation (m), and the local time zone every time in the record is in
units{ system, temperature, humidity, feelsLike, precipitation, snowfall, windSpeed, windDirection, pressureMsl, … } — the unit of every numeric field
current{ time, temperature, humidity, feelsLike, isDay, precipitation, rain, showers, snowfall, weatherCode, description, cloudCover, pressureMsl, surfacePressure, windSpeed, windDirection, windGusts }
hourly[]{ time, temperature, humidity, feelsLike, precipitationProbability, precipitation, weatherCode, description, cloudCover, windSpeed, windDirection, uvIndex } from midnight today
daily[]{ date, weatherCode, description, temperatureMax, temperatureMin, feelsLikeMax, feelsLikeMin, sunrise, sunset, uvIndexMax, precipitationSum, rainSum, snowfallSum, precipitationProbabilityMax, windSpeedMax, windGustsMax }
airQuality{ time, europeanAqi, usAqi, pm10, pm25, carbonMonoxide, nitrogenDioxide, sulphurDioxide, ozone, uvIndex, units } for the current hour, or null when off
historical{ from, to, daily[], hourly[] } for the dates you asked for (no precipitation probability or UV in the archive), or null
alerts[], warnings[]alerts is always [] (Open-Meteo has no warnings); warnings notes a failed air-quality request or a qualifier that matched no candidate
input, status, error, scrapedAtWhat you gave, OK / NOT_FOUND / INVALID_INPUT / FAILED, the reason, and when

Example

{
"input": "Berlin",
"location": { "name": "Berlin", "country": "Germany", "countryCode": "DE", "admin1": "State of Berlin", "timezone": "Europe/Berlin", "population": 3426354 },
"lat": 52.52437,
"lng": 13.41053,
"elevation": 38,
"timezone": "Europe/Berlin",
"utcOffsetSeconds": 7200,
"units": { "system": "metric", "temperature": "°C", "humidity": "%", "feelsLike": "°C", "precipitation": "mm", "rain": "mm", "showers": "mm", "snowfall": "cm", "cloudCover": "%", "pressureMsl": "hPa", "surfacePressure": "hPa", "windSpeed": "km/h", "windDirection": "°", "windGusts": "km/h", "precipitationProbability": "%", "temperatureMax": "°C", "temperatureMin": "°C", "feelsLikeMax": "°C", "feelsLikeMin": "°C", "precipitationSum": "mm", "rainSum": "mm", "snowfallSum": "cm", "precipitationProbabilityMax": "%", "windSpeedMax": "km/h", "windGustsMax": "km/h" },
"current": { "time": "2026-10-19T20:15", "temperature": 8.7, "humidity": 62, "feelsLike": 5.8, "isDay": false, "precipitation": 0, "rain": 0, "showers": 0, "snowfall": 0, "weatherCode": 0, "description": "Clear sky", "cloudCover": 0, "pressureMsl": 1029.7, "surfacePressure": 1025, "windSpeed": 7.8, "windDirection": 68, "windGusts": 18 },
"hourly": [
{ "time": "2026-10-19T00:00", "temperature": 11.6, "humidity": 80, "feelsLike": 9.4, "precipitationProbability": 0, "precipitation": 0, "weatherCode": 3, "description": "Overcast", "cloudCover": 100, "windSpeed": 12.2, "windDirection": 66, "uvIndex": 0 }
],
"daily": [
{ "date": "2026-10-19", "weatherCode": 3, "description": "Overcast", "temperatureMax": 11.8, "temperatureMin": 5.3, "feelsLikeMax": 9.4, "feelsLikeMin": 2.5, "sunrise": "2026-10-19T07:38", "sunset": "2026-10-19T18:02", "uvIndexMax": 2.65, "precipitationSum": 0, "rainSum": 0, "snowfallSum": 0, "precipitationProbabilityMax": 0, "windSpeedMax": 12.9, "windGustsMax": 31.3 },
{ "date": "2026-10-20", "weatherCode": 80, "description": "Slight rain showers", "temperatureMax": 10.8, "temperatureMin": 5.1, "feelsLikeMax": 8.3, "feelsLikeMin": 2.2, "sunrise": "2026-10-20T07:40", "sunset": "2026-10-20T18:00", "uvIndexMax": 2.15, "precipitationSum": 0.6, "rainSum": 0.6, "snowfallSum": 0, "precipitationProbabilityMax": 14, "windSpeedMax": 13.1, "windGustsMax": 31 }
],
"airQuality": { "time": "2026-10-19T20:00", "europeanAqi": 27, "usAqi": 28, "pm10": 7.4, "pm25": 6, "carbonMonoxide": 198, "nitrogenDioxide": 15.5, "sulphurDioxide": 3.3, "ozone": 46, "uvIndex": 0, "units": { "europeanAqi": "EAQI", "usAqi": "USAQI", "pm10": "μg/m³", "pm25": "μg/m³", "carbonMonoxide": "μg/m³", "nitrogenDioxide": "μg/m³", "sulphurDioxide": "μg/m³", "ozone": "μg/m³" } },
"historical": null,
"alerts": [],
"warnings": [],
"status": "OK",
"error": null,
"scrapedAt": "2026-10-19T18:30:00.000Z"
}

FAQ

Is this an official API? No, it's an unofficial API built on public pages/endpoints — Open-Meteo's free, key-less weather, geocoding, archive and air-quality APIs (open-meteo.com, CC BY 4.0 data). This Actor only shapes their answers into stable JSON records; the forecasts themselves come from the national weather services Open-Meteo combines (DWD, NOAA, Météo-France, ECMWF and others).

Why does alerts stay empty? Open-Meteo has no weather-warnings endpoint, so there is nothing to put there. The field is kept so your code can rely on the record's shape; if you need official warnings, take them from your national weather service.

How far back and how far ahead? Forecasts cover 1-16 days (hourly and daily). The historical archive goes back to 1940-01-01 and runs about five days behind today; a run reads at most 366 days per location, so a longer period is several runs.

Why is a place NOT_FOUND, or the wrong one? The geocoder knows cities, towns, villages and many postcodes by their English and local names, but not street addresses or landmarks. Qualify ambiguous names (Paris, Texas, Paris, US) or give coordinates — lat,lng always works. A qualifier that matches nothing takes the first candidate and says so in warnings.

What times and units are these? Every time is local to the location (timezone, utcOffsetSeconds) without an offset suffix, straight from Open-Meteo. Numbers are in the units you chose; the record lists the unit of every field, so a parser never has to guess.

Like it? A short review on the Store page helps other people find this Actor. Something missing or broken? Tell us on the Issues tab — we read every one.