# Open-Meteo Scraper · Weather Forecasts, History & Locations (`reapx/open-meteo-scraper`) Actor

Scrape weather forecasts, historical climate archives, and geocoding location data from the Open-Meteo API. Fast HTTP scraper charging per returned location report.

- **URL**: https://apify.com/reapx/open-meteo-scraper.md
- **Developed by:** [Tarek Etman](https://apify.com/reapx) (community)
- **Categories:** Travel, Automation, Other
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.30 / 1,000 weather location returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#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

![reapX — public sources in, addressable records out](https://reapx.dev/reapx.gif)

## Open-Meteo Scraper · Weather Forecasts, History & Locations

The **Open-Meteo weather API forecast and historical scraper** extracts global 7-day weather forecasts, historical climate archives, and geocoding location metadata from Open-Meteo's open endpoints (`api.open-meteo.com` and `geocoding-api.open-meteo.com`). It collects current weather metrics, daily temperature highs and lows, precipitation sums, WMO weather codes, wind speeds, elevations, and IANA timezone data for any municipality or set of coordinates worldwide without requiring API keys or account registration.

> Maintained by **reapX**. Every row cites the Apify run that produced it — nothing is
> inferred, modelled or filled in, and a field absent from the source is absent from the row.
> The extracted archive for this source is browsable at
> [reapx.dev/data/open-meteo-scraper/](https://reapx.dev/data/open-meteo-scraper/) and mirrored as an open dataset on
> [Hugging Face](https://huggingface.co/datasets/reapxdev/open-meteo-scraper) and
> [Kaggle](https://www.kaggle.com/datasets/reapxdev/open-meteo-scraper). Questions: reapxdev@proton.me

Maintained by reapX. Public source citation guarantee: data fetched directly from official Open-Meteo endpoints.

***

### Features & Highlights

- ⚡ **Zero Authentication & Open Access**: Reads public Open-Meteo APIs directly without API key limits or login barriers.
- 🌍 **Global Geocoding Integration**: Automatically resolves city names, postal codes, and regional queries to exact WGS84 coordinates.
- 🔮 **7-Day Weather Forecasts**: Extract current temperatures, relative humidity, wind speed, WMO weather codes, and 7-day daily forecasts.
- 📜 **Historical Climate Archives**: Access historical weather data back to 1940 for climate trend analysis, backtesting, and environmental research.
- 📏 **Customizable Units**: Choose temperature units (°C or °F), wind speed units (km/h, m/s, mph, knots), and precipitation units (mm or inches).
- 🏷️ **Entity Page Ready**: Emits clean `slug` keys (`london-united-kingdom`, `paris-france`) ensuring addressable location entity pages.

***

### ⬇️ Input

Configure your extraction run using the input schema properties below. Every parameter includes default values so you can run the scraper immediately out-of-the-box.

#### Input Parameters Table

| Parameter | Type | Default / Prefill | Description |
| --- | --- | --- | --- |
| `mode` | String (select) | `"forecast"` | Operation mode: `forecast` (7-day projection), `archive` (historical data), or `geocoding_only` (location metadata). |
| `locations` | Array of Strings | `["London", "Paris", "Berlin", "Tokyo", "New York"]` | List of city names, postal codes, or location queries to search and fetch weather data for. |
| `countryCode` | String | `""` | Optional two-letter ISO 3166-1 country filter (e.g., `GB`, `FR`, `US`). |
| `forecastDays` | Integer | `7` | Number of daily forecast days to retrieve (1 to 16 days). |
| `startDate` | String (date) | `"2024-01-01"` | Start date for historical archive queries in `YYYY-MM-DD` format. |
| `endDate` | String (date) | `"2024-01-07"` | End date for historical archive queries in `YYYY-MM-DD` format. |
| `temperatureUnit` | String (select) | `"celsius"` | Temperature unit: `celsius` (°C) or `fahrenheit` (°F). |
| `windSpeedUnit` | String (select) | `"kmh"` | Wind speed unit: `kmh`, `ms`, `mph`, or `kn`. |
| `precipitationUnit` | String (select) | `"mm"` | Precipitation unit: `mm` or `inch`. |
| `maxLocations` | Integer | `50` | Maximum number of location weather reports to return in a single run. |

***

#### Example Input Configurations

##### Example 1: European Capital Cities Forecast (Celsius & KM/H)

```json
{
  "mode": "forecast",
  "locations": [
    "London",
    "Paris",
    "Berlin",
    "Rome",
    "Madrid"
  ],
  "forecastDays": 7,
  "temperatureUnit": "celsius",
  "windSpeedUnit": "kmh",
  "precipitationUnit": "mm",
  "maxLocations": 50
}
```

##### Example 2: US Metropolitan Areas (Fahrenheit & Miles/Hour)

```json
{
  "mode": "forecast",
  "locations": [
    "New York",
    "Los Angeles",
    "Chicago",
    "Houston",
    "Miami"
  ],
  "countryCode": "US",
  "forecastDays": 7,
  "temperatureUnit": "fahrenheit",
  "windSpeedUnit": "mph",
  "precipitationUnit": "inch",
  "maxLocations": 50
}
```

##### Example 3: Historical Winter Weather Archive (January 2024)

```json
{
  "mode": "archive",
  "locations": [
    "Zermatt",
    "Chamonix",
    "Innsbruck",
    "St. Moritz"
  ],
  "startDate": "2024-01-01",
  "endDate": "2024-01-14",
  "temperatureUnit": "celsius",
  "windSpeedUnit": "kmh",
  "precipitationUnit": "mm",
  "maxLocations": 50
}
```

##### Example 4: City Geocoding & Coordinates Lookup

```json
{
  "mode": "geocoding_only",
  "locations": [
    "Tokyo",
    "Sydney",
    "Cairo",
    "Buenos Aires",
    "Reykjavik"
  ],
  "maxLocations": 50
}
```

***

### ⬆️ Output

All scraped records are stored in the run's default dataset. Each row represents a single geographic location with its metadata and associated weather measurements.

#### Dataset Schema Fields

| Field Name | Type | Description | Example Value |
| --- | --- | --- | --- |
| `slug` | String | Unique addressable location identifier combining city name and country. | `"london-united-kingdom"` |
| `location` | String | Canonical city or municipality name. | `"London"` |
| `country` | String | Full country name. | `"United Kingdom"` |
| `countryCode` | String | Two-letter ISO 3166-1 alpha-2 country code. | `"GB"` |
| `admin1` | String | State, region, or primary administrative subdivision. | `"England"` |
| `latitude` | Number | Decimal latitude coordinate (WGS84). | `51.50853` |
| `longitude` | Number | Decimal longitude coordinate (WGS84). | `-0.12574` |
| `elevation` | Number | Elevation above sea level in meters. | `25.0` |
| `timezone` | String | IANA timezone database identifier. | `"Europe/London"` |
| `timezoneAbbreviation` | String | Local timezone abbreviation or UTC offset. | `"GMT+1"` |
| `population` | Integer | Population estimate for the location. | `8961989` |
| `mode` | String | Scraper execution mode (`forecast`, `archive`, `geocoding_only`). | `"forecast"` |
| `currentTemperature` | Number | Latest surface air temperature at 2m height. | `19.5` |
| `currentHumidity` | Number | Latest relative humidity percentage at 2m height. | `65` |
| `currentWeatherCode` | Integer | WMO weather interpretation condition code. | `1` |
| `currentWindSpeed` | Number | Latest surface wind speed at 10m height. | `12.4` |
| `dailyForecast` | Array | Daily time-series containing date, tempMax, tempMin, precipitationSum, weatherCode. | `[{"date":"2026-08-03","tempMax":22.5,...}]` |
| `scrapedAt` | String | ISO 8601 UTC timestamp of data retrieval. | `"2026-08-03T20:18:00Z"` |

***

#### Sample Output Record

```json
{
  "slug": "london-united-kingdom",
  "location": "London",
  "country": "United Kingdom",
  "countryCode": "GB",
  "admin1": "England",
  "latitude": 51.50853,
  "longitude": -0.12574,
  "elevation": 25.0,
  "timezone": "Europe/London",
  "timezoneAbbreviation": "GMT+1",
  "population": 8961989,
  "mode": "forecast",
  "scrapedAt": "2026-08-03T20:18:00Z",
  "currentTemperature": 19.5,
  "currentHumidity": 65,
  "currentWeatherCode": 1,
  "currentWindSpeed": 12.4,
  "dailyForecast": [
    {
      "date": "2026-08-03",
      "tempMax": 22.5,
      "tempMin": 14.1,
      "precipitationSum": 0.0,
      "weatherCode": 1,
      "windSpeedMax": 15.2
    },
    {
      "date": "2026-08-04",
      "tempMax": 21.0,
      "tempMin": 13.8,
      "precipitationSum": 1.2,
      "weatherCode": 61,
      "windSpeedMax": 18.4
    }
  ]
}
```

***

### How it works

1. **Location Resolution**: The actor receives input target location names (or defaults to top global cities). Each location string is sent to Open-Meteo's Geocoding Search API (`geocoding-api.open-meteo.com/v1/search`) to retrieve exact geographic coordinates (latitude, longitude), elevation, country code, administrative region, and timezone information.
2. **Weather Data Extraction**: Using resolved coordinates, the actor connects directly to Open-Meteo's Forecast API (`api.open-meteo.com/v1/forecast`) or Historical Archive API (`archive-api.open-meteo.com/v1/archive`) over plain HTTP.
3. **Identifier Normalization**: For each location, a clean addressable `slug` key is generated (e.g. `london-united-kingdom`). Latitude and longitude coordinates are emitted strictly as numerical measurements.
4. **Streaming Push**: Location reports are pushed directly to Apify's default dataset in real-time as they are processed.

***

### WMO Weather Interpretation Codes

Open-Meteo uses World Meteorological Organization (WMO) weather interpretation codes:

- **0**: Clear sky
- **1, 2, 3**: Mainly clear, partly cloudy, and overcast
- **45, 48**: Fog and depositing rime fog
- **51, 53, 55**: Drizzle (light, moderate, dense intensity)
- **61, 63, 65**: Rain (slight, moderate, heavy intensity)
- **71, 73, 75**: Snow fall (slight, moderate, heavy intensity)
- **80, 81, 82**: Rain showers (slight, moderate, violent)
- **95, 96, 99**: Thunderstorm (slight, moderate, with heavy hail)

***

### ❓ FAQ

#### Does this scraper require an API key?

No. Open-Meteo provides free, open-access endpoints for non-commercial and open data applications. The scraper communicates directly over standard HTTP without authentication tokens.

#### Can I retrieve historical weather data from previous years?

Yes. By setting `mode` to `"archive"` and supplying `startDate` and `endDate` parameters (in `YYYY-MM-DD` format), you can extract historical weather observations back to 1940.

#### How does pay-per-event pricing work for this actor?

You are charged a flat rate per location weather report successfully written to your dataset. If an API request fails, returns zero matches, or is blocked, no charge is levied.

#### What happens if I search for a city that exists in multiple countries?

You can supply the `countryCode` filter (e.g., `GB`, `US`, `CA`) to restrict search results to a specific nation. If omitted, Open-Meteo returns the most populous matching city worldwide.

***

### 💬 Your feedback

We continuously improve Open-Meteo Scraper based on user feedback. If you encounter issues, require additional weather variables (such as UV index, soil moisture, or hourly resolution), or want custom integration support, please contact us at **reapxdev@proton.me**.

***

*Unofficial - not affiliated with Open-Meteo. Collects public data only. reapx. Contact reapxdev@proton.me.*

### 🧪 Example input

A real, runnable configuration — this is an actual input this Actor has run with.

```json
{
  "mode": "forecast",
  "locations": [
    "London",
    "Manchester",
    "Birmingham",
    "Edinburgh",
    "Glasgow"
  ],
  "countryCode": "GB",
  "forecastDays": 7,
  "temperatureUnit": "celsius",
  "windSpeedUnit": "kmh",
  "precipitationUnit": "mm",
  "maxLocations": 50
}
```

### 📄 Sample output

One real row from a real run of this Actor, unedited.

```json
{
  "slug": "london-united-kingdom",
  "location": "London",
  "country": "United Kingdom",
  "countryCode": "GB",
  "admin1": "England",
  "latitude": 51.50853,
  "longitude": -0.12574,
  "elevation": 25.0,
  "timezone": "Europe/London",
  "timezoneAbbreviation": "GMT+1",
  "population": 8961989,
  "mode": "forecast",
  "scrapedAt": "2026-08-03T18:18:54.515615+00:00",
  "currentTemperature": 28.6,
  "currentHumidity": 33,
  "currentWeatherCode": 0,
  "currentWindSpeed": 15.8,
  "dailyForecast": [
    {
      "date": "2026-08-03",
      "tempMax": 30.8,
      "tempMin": 18.5,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 16.2
    },
    {
      "date": "2026-08-04",
      "tempMax": 28.6,
      "tempMin": 20.7,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 22.7
    },
    {
      "date": "2026-08-05",
      "tempMax": 23.8,
      "tempMin": 19.0,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 23.4
    },
    {
      "date": "2026-08-06",
      "tempMax": 20.5,
      "tempMin": 14.7,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 17.6
    },
    {
      "date": "2026-08-07",
      "tempMax": 21.7,
      "tempMin": 15.3,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 15.8
    },
    {
      "date": "2026-08-08",
      "tempMax": 23.1,
      "tempMin": 15.5,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 17.6
    },
    {
      "date": "2026-08-09",
      "tempMax": 24.1,
      "tempMin": 15.9,
      "precipitationSum": 0.0,
      "weatherCode": 3,
      "windSpeedMax": 17.6
    }
  ]
}
```

### ⚠️ Run outcomes and error handling

This Actor reports what happened in the run's **status message**, and it always keeps whatever it collected. These are the outcomes you can get and what each one means.

| Outcome | What it means |
|---|---|
| **Success** | Rows were returned and you were charged `weather-location-returned` at $0.002 per row. |
| **No matches** | The source returned nothing for your filters. **Nothing is charged.** Widen the date window or drop a filter. |
| **Partial - source refused** | The source rate-limited or refused some requests. The affected items are skipped and named in the log, and **everything already collected is still pushed**. A block never discards a run's work. |
| **Rejected filter** | The source itself rejected the filter combination. The run fails fast with the source's own reason and **nothing is charged.** |

#### What is guaranteed either way

- **Every row is pushed as it is built**, not buffered to the end of the run. Anything that buffers output loses everything to a timeout, a block or a migration; this does not.
- **A field absent from the source is absent from the row.** Nothing is inferred, modelled or filled in to make a row look complete.

# Actor input Schema

## `mode` (type: `string`):

Select whether to fetch 7-day weather <b>forecasts</b>, historical weather <b>archives</b>, or location <b>geocoding</b> data from Open-Meteo API. <code>forecast</code> retrieves current weather conditions and daily metrics.<br><br>Leaving this setting at default uses forecast mode. Choosing archive mode requires setting start and end dates.

## `locations` (type: `array`):

List of city names, postal codes, or location queries to search and fetch weather data for. <b>Example:</b> <code>\["London", "Paris", "Tokyo"]</code>.<br><br>Leaving this field empty defaults to major global cities. Each location is resolved using the Open-Meteo Geocoding API before fetching weather measurements.

## `countryCode` (type: `string`):

Filter location search results by two-letter ISO 3166-1 country code (e.g. <code>GB</code> for United Kingdom, <code>FR</code> for France, <code>US</code> for United States).<br><br>Leave empty to search globally without country restriction. Pattern requires exactly two uppercase letters.

## `forecastDays` (type: `integer`):

Number of daily forecast days to retrieve when mode is set to forecast (1 to 16 days). The higher the number, the larger the payload returned for each location.<br><br>Defaults to 7 days of daily weather projections. Must be an integer between 1 and 16.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## `startDate` (type: `string`):

Start date for historical weather archive queries in ISO format (<code>YYYY-MM-DD</code>). Used when mode is set to archive.<br><br>Leave empty to use 14 days prior to current date. The earlier the date, the more historical weather records are fetched.

## `endDate` (type: `string`):

End date for historical weather archive queries in ISO format (<code>YYYY-MM-DD</code>). Used when mode is set to archive.<br><br>Leave empty to use 7 days prior to current date. End date must be on or after the specified start date.

## `temperatureUnit` (type: `string`):

Unit of measurement for temperature values across all location reports. Choose between <code>celsius</code> (°C) or <code>fahrenheit</code> (°F).<br><br>Defaults to celsius metric standards. Affects min, max, and current temperature outputs.

## `windSpeedUnit` (type: `string`):

Unit of measurement for wind speed values across all location reports. Options include <code>kmh</code> (km/h), <code>ms</code> (m/s), <code>mph</code> (miles/hr), or <code>kn</code> (knots).<br><br>Defaults to kmh metric speed standards.

## `precipitationUnit` (type: `string`):

Unit of measurement for precipitation values (rain, snowfall). Choose between <code>mm</code> (millimeters) or <code>inch</code> (inches).<br><br>Defaults to millimeters metric standards. Affects daily precipitation totals.

## `maxLocations` (type: `integer`):

Upper capacity limit on total unique location weather reports produced in a single execution. The higher the number, the longer the run takes and the more events are charged.<br><br>Defaults to 50 locations. Set a lower limit to test queries quickly.<br><br>The higher the number, the longer the run takes and the more you are charged, because you pay per row returned.

## Actor input object example

```json
{
  "mode": "forecast",
  "locations": [
    "London",
    "Paris",
    "Berlin",
    "Tokyo",
    "New York"
  ],
  "forecastDays": 7,
  "startDate": "2024-01-01",
  "endDate": "2024-01-07",
  "temperatureUnit": "celsius",
  "windSpeedUnit": "kmh",
  "precipitationUnit": "mm",
  "maxLocations": 50
}
```

# Actor output Schema

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

Every weather location report found by this run, one row per location, in the default dataset.

# 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 = {
    "mode": "forecast",
    "locations": [
        "London",
        "Paris",
        "Berlin",
        "Tokyo",
        "New York"
    ],
    "countryCode": "",
    "forecastDays": 7,
    "startDate": "2024-01-01",
    "endDate": "2024-01-07",
    "temperatureUnit": "celsius",
    "windSpeedUnit": "kmh",
    "precipitationUnit": "mm",
    "maxLocations": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("reapx/open-meteo-scraper").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 = {
    "mode": "forecast",
    "locations": [
        "London",
        "Paris",
        "Berlin",
        "Tokyo",
        "New York",
    ],
    "countryCode": "",
    "forecastDays": 7,
    "startDate": "2024-01-01",
    "endDate": "2024-01-07",
    "temperatureUnit": "celsius",
    "windSpeedUnit": "kmh",
    "precipitationUnit": "mm",
    "maxLocations": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("reapx/open-meteo-scraper").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 '{
  "mode": "forecast",
  "locations": [
    "London",
    "Paris",
    "Berlin",
    "Tokyo",
    "New York"
  ],
  "countryCode": "",
  "forecastDays": 7,
  "startDate": "2024-01-01",
  "endDate": "2024-01-07",
  "temperatureUnit": "celsius",
  "windSpeedUnit": "kmh",
  "precipitationUnit": "mm",
  "maxLocations": 50
}' |
apify call reapx/open-meteo-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reapx/open-meteo-scraper"
        }
    }
}

```

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/xTqzJD1WeFKMwo3r9/builds/JzlVZeQwjYnrq50gM/openapi.json
