Open-Meteo Weather Scraper — Forecast, History, Air Quality avatar

Open-Meteo Weather Scraper — Forecast, History, Air Quality

Pricing

from $0.35 / 1,000 result items

Go to Apify Store
Open-Meteo Weather Scraper — Forecast, History, Air Quality

Open-Meteo Weather Scraper — Forecast, History, Air Quality

Weather data for AI agents without an API key: current, hourly/16-day daily forecast, ERA5 history since 1940, air quality (AQI, PM2.5, pollen), marine waves, CMIP6 climate projections, ensemble spread, river discharge — for any city or coordinates. 200+ variables, model selection, units, timezone.

Pricing

from $0.35 / 1,000 result items

Rating

0.0

(0)

Developer

Samat Makatov

Samat Makatov

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

1

Monthly active users

10 days ago

Last modified

Share

Weather data for agents, dashboards and models without an API key, browser or proxy. One actor covers the whole Open-Meteo family: current conditions, hourly and 16-day daily forecasts (24 selectable models), ERA5 history back to 1940, air quality (European/US AQI, PM2.5, NO₂, pollen), marine waves and currents, CMIP6 climate projections to 2050, ensemble spread and river discharge — for any city name or lat,lon. 200+ variables, your units and timezone, one row per timestamp or a compact series per location.

Use cases

  • Agro & irrigation planning — history with et0_fao_evapotranspiration, precipitation_sum, shortwave_radiation_sum per field for the season; daily with soil_moisture_0_to_10cm_mean and growing_degree_days_base_0_limit_50 for the next two weeks.
  • Logistics / delivery risk — hourly precipitation_probability, wind_gusts_10m, visibility, snowfall for depots and routes; ensemble spread to know how certain the forecast is.
  • Retail demand & staffing — 16-day temperature_2m_max, weather_code per store city; historical weather to explain last year's sales.
  • Health & ESG reporting — airQuality (PM2.5, ozone, us_aqi) and uv_index_max for office locations; climate projections for 2030–2050 site assessments.
  • Energy — shortwave_radiation, direct_normal_irradiance, wind_speed_100m (history) for solar/wind yield estimates.
  • Marine & tourism — marine wave height/period and sea_surface_temperature for ports, beaches and offshore work windows; flood river discharge for riverside assets.

Input

FieldTypeDefaultNotes
locationsstring[]—Almaty, Berlin, DE, Paris, France, 40.71,-74.01. Coordinates: one Open-Meteo call each; a place name one more for the geocoder (remembered for 30 days). Listed twice = fetched once.
modeselectdailycurrent, daily, hourly, history, historyHourly, airQuality, airQualityCurrent, marine, marineHourly, climate, ensemble, flood.
daysint7Days ahead (or back for history). Caps: daily/hourly/marine/ensemble 16, airQuality 7, flood 210.
pastDaysint—Forecast modes: prepend 0–92 days of recent data.
startDate, endDatedate—Explicit period (YYYY-MM-DD). History: 1940-01-01 → 2 days ago. Climate: 1950–2050.
variablesstring[]mode defaultsOpen-Meteo variable names for the mode (dictionaries below). Case, spaces, _ and - do not matter; a name the mode lacks is skipped and named in the status and SUMMARY.warnings (with the mode that has it, or a "did you mean"); no valid name = the run stops before any request.
modelsstring[]best matchForecast/ensemble/climate model ids (below). Several forecast models → one column per model. Unknown ids are skipped and named; none valid = the run stops (a typo never becomes another model).
includeEnsembleMembersboolfalseEnsemble: add <var>_values arrays.
unitsselectmetricmetric (°C, km/h, mm) or imperial (°F, mph, inch).
temperatureUnit / windSpeedUnit / precipitationUnitselect—`celsius
timezonestringautoIANA name or auto (local time per location).
geocodeLanguagestringenLanguage for place matching / labels.
geocodeCountrystring—ISO-2 country filter for all place-name lookups.
cellSelectionselectlandland, sea, nearest grid cell (coasts).
airQualityDomainselectautocams_europe (11 km) or cams_global (40 km).
layoutselectrowsrows (one row per timestamp) or compact (one row per location with arrays — 1 billed item).
maxItemsint20000Hard cap on rows (each row is billed). Date ranges are cut to the days that still fit — the cut is named in the status.
fieldsstring[]allKeep only these columns, in this order. location and date/time are always kept. Unknown names are skipped and named; none valid = the run stops before any request.

Reference

mode, units, temperatureUnit, windSpeedUnit, precipitationUnit, cellSelection, airQualityDomain and layout are lists: Apify refuses any other value before the run starts and shows the allowed values (listed in the table above and below). variables, models and fields are free text and are checked by the actor.

Modes → endpoint, granularity, range

modeendpointrowsrange
currentforecast1 per locationnow (15-min update)
dailyforecast1 per day≤16 ahead, ≤92 back
hourlyforecast1 per hour≤16 ahead, ≤92 back
historyarchive (ERA5/ERA5-Land, 9–25 km)1 per day1940 → T-2 days
historyHourlyarchive1 per hour1940 → T-2 days
airQualityair-quality (CAMS)1 per hour≤7 ahead, ≤92 back
airQualityCurrentair-quality1 per locationnow
marinemarine1 per day≤16 ahead
marineHourlymarine1 per hour≤16 ahead
climateclimate (CMIP6 HighResMIP)1 per day1950–2050
ensembleensemble1 per day (+min/max/mean/spread over 30–50 members)≤16 ahead
floodflood (GloFAS)1 per day≤210 ahead

Variables by mode

current: temperature_2m relative_humidity_2m apparent_temperature is_day precipitation rain showers snowfall weather_code cloud_cover pressure_msl surface_pressure wind_speed_10m wind_direction_10m wind_gusts_10m

daily (forecast): weather_code temperature_2m_max/min/mean apparent_temperature_max/min/mean sunrise sunset daylight_duration sunshine_duration uv_index_max uv_index_clear_sky_max rain_sum showers_sum snowfall_sum precipitation_sum precipitation_hours precipitation_probability_max/min/mean wind_speed_10m_max/min/mean wind_gusts_10m_max/min/mean wind_direction_10m_dominant shortwave_radiation_sum et0_fao_evapotranspiration relative_humidity_2m_max/min/mean dew_point_2m_max/min/mean cloud_cover_max/min/mean pressure_msl_max/min/mean surface_pressure_max/min/mean visibility_max/min/mean cape_max/min/mean vapour_pressure_deficit_max leaf_wetness_probability_mean soil_moisture_0_to_10cm_mean growing_degree_days_base_0_limit_50

hourly (forecast): temperature_2m relative_humidity_2m dew_point_2m apparent_temperature precipitation_probability precipitation rain showers snowfall snow_depth weather_code pressure_msl surface_pressure cloud_cover cloud_cover_low/mid/high visibility evapotranspiration et0_fao_evapotranspiration vapour_pressure_deficit wind_speed_10m/80m/120m/180m wind_direction_10m/80m/120m/180m wind_gusts_10m temperature_80m/120m/180m soil_temperature_0cm/6cm/18cm/54cm soil_moisture_0_to_1cm/1_to_3cm/3_to_9cm/9_to_27cm/27_to_81cm uv_index uv_index_clear_sky is_day sunshine_duration wet_bulb_temperature_2m total_column_integrated_water_vapour cape lifted_index convective_inhibition freezing_level_height boundary_layer_height shortwave_radiation direct_radiation diffuse_radiation direct_normal_irradiance global_tilted_irradiance terrestrial_radiation

history (daily archive): weather_code temperature_2m_max/min/mean apparent_temperature_max/min/mean sunrise sunset daylight_duration sunshine_duration precipitation_sum rain_sum snowfall_sum precipitation_hours wind_speed_10m_max wind_gusts_10m_max wind_direction_10m_dominant shortwave_radiation_sum et0_fao_evapotranspiration

historyHourly: temperature_2m relative_humidity_2m dew_point_2m apparent_temperature precipitation rain snowfall snow_depth weather_code pressure_msl surface_pressure cloud_cover cloud_cover_low/mid/high et0_fao_evapotranspiration vapour_pressure_deficit wind_speed_10m/100m wind_direction_10m/100m wind_gusts_10m soil_temperature_0_to_7cm/7_to_28cm/28_to_100cm/100_to_255cm soil_moisture_0_to_7cm/7_to_28cm/28_to_100cm/100_to_255cm is_day sunshine_duration shortwave_radiation direct_radiation diffuse_radiation direct_normal_irradiance global_tilted_irradiance terrestrial_radiation boundary_layer_height wet_bulb_temperature_2m total_column_integrated_water_vapour cape

airQuality (hourly) / airQualityCurrent: pm10 pm2_5 carbon_monoxide carbon_dioxide* nitrogen_dioxide sulphur_dioxide ozone aerosol_optical_depth dust uv_index uv_index_clear_sky ammonia methane* alder_pollen birch_pollen grass_pollen mugwort_pollen olive_pollen ragweed_pollen (pollen: Europe only) european_aqi european_aqi_pm2_5/pm10/nitrogen_dioxide/ozone/sulphur_dioxide us_aqi us_aqi_pm2_5/pm10/nitrogen_dioxide/ozone/sulphur_dioxide/carbon_monoxide (*hourly only)

marine (daily): wave_height_max wave_direction_dominant wave_period_max wind_wave_height_max wind_wave_direction_dominant wind_wave_period_max wind_wave_peak_period_max swell_wave_height_max swell_wave_direction_dominant swell_wave_period_max swell_wave_peak_period_max marineHourly: wave_height wave_direction wave_period wind_wave_height/direction/period/peak_period swell_wave_height/direction/period/peak_period ocean_current_velocity ocean_current_direction sea_surface_temperature sea_level_height_msl

climate (daily): temperature_2m_mean/max/min wind_speed_10m_mean/max cloud_cover_mean shortwave_radiation_sum relative_humidity_2m_mean/max/min dew_point_2m_mean/min/max precipitation_sum rain_sum snowfall_sum pressure_msl_mean soil_moisture_0_to_10cm_mean et0_fao_evapotranspiration_sum

ensemble (daily): temperature_2m_max/min/mean precipitation_sum rain_sum snowfall_sum wind_speed_10m_max wind_gusts_10m_max shortwave_radiation_sum weather_code — each also emitted as _min, _max, _mean, _spread, _members.

flood (daily): river_discharge river_discharge_mean/median/max/min/p25/p75

Models

modeids
forecast (current, daily, hourly)best_match · ecmwf_ifs025 · ecmwf_aifs025 · gfs_seamless · gfs_global · gfs_hrrr · icon_seamless · icon_global · icon_eu · icon_d2 · gem_seamless · gem_global · meteofrance_seamless · meteofrance_arpege_world · jma_seamless · jma_msm · metno_seamless · knmi_seamless · dmi_seamless · ukmo_seamless · cma_grapes_global · bom_access_global · kma_seamless · italia_meteo_arpae_icon_2i
ensembleicon_seamless (default) · icon_global · icon_eu · icon_d2 · gfs_seamless · gfs025 · gfs05 · ecmwf_ifs025 · ecmwf_aifs025 · gem_global · bom_access_global_ensemble · ukmo_global_ensemble_20km · ukmo_uk_ensemble_2km · meteoswiss_icon_ch1 · meteoswiss_icon_ch2
climateEC_Earth3P_HR (default) · CMCC_CM2_VHR4 · FGOALS_f3_H · HiRAM_SIT_HR · MRI_AGCM3_2_S · MPI_ESM1_2_XR · NICAM16_8S

WMO weather codes (weather_code → weather)

0 Clear sky · 1 Mainly clear · 2 Partly cloudy · 3 Overcast · 45 Fog · 48 Rime fog · 51/53/55 Drizzle light/moderate/dense · 56/57 Freezing drizzle · 61/63/65 Rain slight/moderate/heavy · 66/67 Freezing rain · 71/73/75 Snowfall slight/moderate/heavy · 77 Snow grains · 80/81/82 Rain showers slight/moderate/violent · 85/86 Snow showers · 95 Thunderstorm · 96/99 Thunderstorm with hail

Examples

Two-week outlook for store cities (default variables)

{ "locations": ["Almaty", "Astana", "Shymkent"], "mode": "daily", "days": 14, "geocodeCountry": "KZ" }

Season history for agronomy (per field, daily)

{
"locations": ["54.87,69.15", "53.28,69.39"],
"mode": "history",
"startDate": "2026-04-01",
"endDate": "2026-08-31",
"variables": ["temperature_2m_mean", "precipitation_sum", "et0_fao_evapotranspiration", "shortwave_radiation_sum", "wind_speed_10m_max"]
}

Delivery-risk hours for the next 2 days

{ "locations": ["Berlin, DE", "Hamburg, DE"], "mode": "hourly", "days": 2, "variables": ["temperature_2m", "precipitation_probability", "precipitation", "snowfall", "wind_gusts_10m", "visibility", "weather_code"] }

Air quality now for office locations

{ "locations": ["Almaty", "Tashkent", "Bishkek"], "mode": "airQualityCurrent" }

Forecast certainty: ensemble spread + two models side by side

{ "locations": ["Almaty"], "mode": "ensemble", "days": 7, "models": ["ecmwf_ifs025"] }
{ "locations": ["Almaty"], "mode": "daily", "days": 7, "models": ["ecmwf_ifs025", "gfs_seamless", "icon_seamless"], "variables": ["temperature_2m_max", "precipitation_sum"] }

Climate projection for a site (July 2040)

{ "locations": ["Almaty"], "mode": "climate", "startDate": "2040-07-01", "endDate": "2040-07-31", "models": ["MRI_AGCM3_2_S"] }

Output

Daily row (default variables):

{
"input": "Almaty",
"location": "Almaty, Almaty, Kazakhstan",
"lat": 43.26889,
"lon": 76.95067,
"elevation": 794,
"country": "Kazakhstan",
"countryCode": "KZ",
"timezone": "Asia/Almaty",
"utcOffsetSeconds": 18000,
"mode": "daily",
"date": "2026-09-13",
"weather_code": 2,
"temperature_2m_max": 30,
"temperature_2m_min": 19.9,
"precipitation_sum": 0,
"precipitation_probability_max": 0,
"wind_speed_10m_max": 8.2,
"wind_gusts_10m_max": 25.2,
"uv_index_max": 5.95,
"sunrise": "2026-09-13T05:29",
"sunset": "2026-09-13T18:06",
"weather": "Partly cloudy",
"tempMax": 30,
"tempMin": 19.9,
"precipitation": 0,
"windMax": 8.2,
"units": { "temperature_2m_max": "°C", "precipitation_sum": "mm", "wind_speed_10m_max": "km/h" },
"sourceUrl": "https://api.open-meteo.com/v1/forecast?latitude=43.25&longitude=76.91&daily=…",
"fetchedAt": "2026-09-12T23:51:57.792Z"
}
FieldDescription
input, locationWhat you passed and the resolved place (name, admin1, country).
lat, lon, elevationGrid-cell coordinates/elevation used by the model.
country, countryCode, timezone, utcOffsetSecondsFrom the geocoder / API.
mode, date or timeGranularity; time is local time unless timezone is set.
<variable>Every requested variable under its Open-Meteo name (multi-model: <variable>_<model>; ensemble: _min/_max/_mean/_spread/_members).
weatherText for weather_code.
temp, feelsLike, humidity, tempMax, tempMin, precipitation, windMax, uvIndexMax, precipProbability(Max), windSpeed, windDir, cloudCover, pressure, weatherCodeLegacy aliases kept for v0.1 users.
unitsUnit per variable, as reported by the API.
sourceUrl, fetchedAtExact API call and timestamp.

layout: "compact" rows have granularity, series (parallel arrays incl. time) and units. With fields, rows keep only the listed columns in your order (location, date/time always first unless you list them).

Failed locations (not geocodable, API error) are not rows and are not charged. The run's status message names them, and the SUMMARY key-value record holds the details: { mode, locations, rows, variables, models, range, errors[{location, error}], errorCount, notFetched, maxItemsReached, rowsOverMaxItems, rateLimit, estimatedWeightedCalls, warnings, delivered, stoppedBy, status }. warnings lists everything the actor changed or skipped (unknown variables, clamped dates, range cuts, a place matched in another language). The run fails only when no location returned data.

Dataset views: Weather (overview), Air quality, Marine, Ensemble spread, River discharge.

Use it from code / agents

curl -X POST "https://api.apify.com/v2/acts/yadroo~open-meteo-weather/run-sync-get-dataset-items?token=$APIFY_TOKEN" \
-H 'Content-Type: application/json' -d '{"locations":["Almaty"],"mode":"current"}'
import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('yadroo/open-meteo-weather').call({ locations: ['Berlin, DE'], mode: 'hourly', days: 2, layout: 'compact' });
const { items } = await client.dataset(run.defaultDatasetId).listItems();
from apify_client import ApifyClient
client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("yadroo/open-meteo-weather").call(run_input={"locations": ["54.87,69.15"], "mode": "history", "startDate": "2026-04-01", "endDate": "2026-08-31", "variables": ["precipitation_sum", "et0_fao_evapotranspiration"]})
items = client.dataset(run["defaultDatasetId"]).list_items().items

MCP: connect https://mcp.apify.com and call the yadroo/open-meteo-weather tool with the same JSON.

Pricing

Pay per event: $0.001 per run start + $0.0005 per row. A 16-day daily forecast for 10 cities = 160 rows ≈ $0.081; 5 months of daily history for 20 fields ≈ 3 000 rows ≈ $1.50; hourly 16-day runs are cheaper with layout: "compact" (1 row per location).

Store discounts: Bronze −10 %, Silver −20 %, Gold and above −30 % on the row price; the start event is the same on every plan; platform usage is included. A run never charges more than your maximum cost per run: it stops with "Stopped at your spending limit: N rows delivered", and every row it saved is in the dataset.

Limits & FAQ

  • Freshness. Forecasts update hourly (current every 15 min); ERA5 history lags ~2 days (the actor clamps endDate); air quality hourly.
  • Resolution. Best-match forecast 1–11 km depending on region; history 9–25 km; climate 20–50 km. lat/lon in the output are the grid cell actually used.
  • Place not found? Use City, CC, geocodeCountry, or coordinates. Ambiguous names resolve to the most populous match. The geocoder matches a name only in the requested geocodeLanguage: a name in another script ("Москва", "Київ") is also tried in that script's languages (Cyrillic: ru, then uk), and the status says which one matched. Short CJK names (2 characters) match only exact entries — use Latin spelling or coordinates.
  • Rate limits. Open-Meteo's free API allows about 600 calls per minute, 5 000 per hour and 10 000 per day per IP address, and counts a request with more than 10 variables or more than 2 weeks of data as several calls (a year of data with up to 10 variables ≈ 26 calls). Apify runs share IP addresses, so that budget is not all yours. The actor paces its own calls under the per-minute limit and waits out a per-minute refusal (up to twice); when Open-Meteo says the hourly or daily limit is used up, it stops at once with a clear status — rows saved so far stay, and the locations not fetched are listed in SUMMARY.notFetched (run them again later). A place name costs one geocoder call the first time and is then remembered for 30 days (store open-meteo-weather-geocache in your account); coordinates cost none. Inputs that need more than 5 000 weighted calls get a warning before the first request.
  • Long ranges. Date ranges are read in pieces (up to 1 year per request for hourly modes, 5 years for daily) and each piece is saved before the next is read. maxItems is applied before reading: hourly history with maxItems: 1000 asks only for the first 42 days, and the cut is named in the status. One compact row holds up to ~600 000 values (an item must stay under 9 MB); a longer compact range is cut the same way. Rows are saved at roughly 100–200 per second (measured on hourly history), so one 15-minute run holds about 100 000 rows — split bigger jobs by date range or location.
  • Run timeout. Near the run's timeout the actor stops starting requests and ends SUCCEEDED with "Stopped before the run timeout: N rows saved"; raise the timeout or split the job.
  • Ensemble size. ICON 40 members, GFS 31, ECMWF 51 — _members tells you how many were present.
  • Licence. Data by Open-Meteo.com under CC BY 4.0 — attribute "Weather data by Open-Meteo.com" when you publish it. Open-Meteo's free API, which this actor calls, is meant for non-commercial use.
  • Roadmap. 15-minutely forecast, solar-panel tilt/azimuth inputs, elevation override, previous-runs comparison.

Made by Yadroo · Sibling actors: osm-geocode · public-holidays · world-bank-indicators · ip-intel