# Weather Forecast API: hourly + daily by city or lat/lon (`bosco_labs/weather-forecast`) Actor

Weather forecast for up to 50 places or coordinates, up to 10 days: hourly temperature, rain, wind, gusts, clouds and humidity plus a daily summary in local time. Source MET Norway (CC BY 4.0), cached per its terms. Unknown places are free.

- **URL**: https://apify.com/bosco_labs/weather-forecast.md
- **Developed by:** [Bosco Labs](https://apify.com/bosco_labs) (community)
- **Categories:** AI, Developer tools, Business
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.50 / 1,000 location forecasts

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## Weather Forecast API: hourly + daily by city or lat/lon

**Weather forecasts for place names or coordinates, up to 10 days ahead**: hourly temperature,
precipitation, wind speed, direction and gusts, cloud cover, humidity and pressure, plus a
daily summary in local time. The data come from MET Norway, the Norwegian national weather
service (the forecasts behind yr.no), which covers the whole world. Built for **AI agents**
planning travel, logistics, events, farming or energy work, and for people who need a clean
forecast table.

**Pricing (pay per event):** $0.0015 per location forecast. Unknown places and invalid
coordinates are returned too, free of charge.

### What you get

One row per location. Real output for `{"locations": ["Amsterdam"], "hours": 48}` (run
2026-11-05; `timeseries` shortened to 2 of its 12 steps):

```json
{
  "schema_version": "1",
  "input": "Amsterdam",
  "resolved": true,
  "status": "ok",
  "name": "Amsterdam, North Holland, NL",
  "country_code": "NL",
  "latitude": 52.374,
  "longitude": 4.8897,
  "elevation_m": 13,
  "timezone": "Europe/Amsterdam",
  "updated_at": "2026-11-05T19:17:13Z",
  "fetched_at": "2026-11-05T23:13:00+00:00",
  "hours": 48,
  "units": {"temperature": "celsius", "precipitation": "mm", "precipitation_probability": "%", "wind_speed": "m/s", "wind_gust": "m/s", "wind_direction": "degrees, direction the wind comes from (0 = north, 90 = east)", "cloud_cover": "%", "humidity": "%", "pressure": "hPa (at sea level)"},
  "timeseries": [
    {"time": "2026-11-06T00:00:00+01:00", "period_hours": 1, "temperature": 4.7, "temperature_min": null, "temperature_max": null, "precipitation": 0.0, "precipitation_probability": null, "wind_speed": 4.0, "wind_gust": null, "wind_direction": 83.7, "cloud_cover": 0.0, "humidity": 92.8, "pressure": 1026.3, "symbol_code": "clearsky_night"},
    {"time": "2026-11-06T01:00:00+01:00", "period_hours": 1, "temperature": 4.4, "temperature_min": null, "temperature_max": null, "precipitation": 0.0, "precipitation_probability": null, "wind_speed": 3.9, "wind_gust": null, "wind_direction": 78.0, "cloud_cover": 0.0, "humidity": 93.8, "pressure": 1026.2, "symbol_code": "clearsky_night"}
  ],
  "daily": [
    {"date": "2026-11-06", "hours_covered": 24, "temperature_min": 2.6, "temperature_max": 8.3, "precipitation": 0.0, "wind_speed_max": 4.4, "wind_gust_max": null, "symbol_code": "clearsky"},
    {"date": "2026-11-07", "hours_covered": 24, "temperature_min": 0.7, "temperature_max": 6.6, "precipitation": 0.3, "wind_speed_max": 3.0, "wind_gust_max": null, "symbol_code": "fog"}
  ],
  "warnings": [],
  "source_url": "https://api.met.no/weatherapi/locationforecast/2.0/complete?lat=52.374&lon=4.8897&altitude=13",
  "place_source_url": "https://www.geonames.org/2759794",
  "attribution": "Data from MET Norway (CC BY 4.0)",
  "attribution_details": "Forecast by MET Norway (api.met.no), CC BY 4.0, https://creativecommons.org/licenses/by/4.0/. Daily values and local times are derived by Bosco Labs from MET Norway's forecast; they are not the responsibility of MET Norway. Place name and coordinates from GeoNames (geonames.org), CC BY 4.0.",
  "retrieved_at": "2026-11-05T23:13:00+00:00"
}
```

#### Key fields

- **`timeseries`**: forecast steps in local time.
  - Instant values (temperature, wind, clouds, humidity, pressure) hold at `time`.
  - `precipitation`, `symbol_code` and the 6-hour `temperature_min`/`max` cover the
    `period_hours` that starts at `time`.
  - Steps are hourly for about the first 2.5 days, then every 6 hours.
  - With `summary: true` you get the next 12 hourly steps; with `false`, every step in `hours`.
- **`daily`**: one row per local calendar day. It holds min/max temperature, total
  precipitation, max wind and gust, and the most frequent weather symbol. `hours_covered` < 24
  means the day is only partly in the window (the first and last day).
- **`wind_gust` and `precipitation_probability`**: MET Norway gives these only inside its
  Nordic model area. Checked 2026-11-05: yes for Oslo, Bergen, Copenhagen, Tallinn and
  Hamburg; no for Amsterdam, Rotterdam, New York and Portland. Elsewhere they are `null`.
- **`symbol_code`**: MET Norway's weather symbols, e.g. `clearsky_day`, `partlycloudy_night`,
  `rain`, `heavysnowshowers_day`, `fog`. Icons and meanings:
  [github.com/metno/weathericons](https://github.com/metno/weathericons).
- **`updated_at`** / **`fetched_at`**:
  - `updated_at`: when MET's model data were updated. Hourly in the Nordic region, every 6
    hours elsewhere.
  - `fetched_at`: when this Actor got the forecast. It can be up to 3 hours before your run,
    because MET's terms require reusing a forecast until it may be fetched again. A newer
    forecast would not have been available anyway.

### Input

```json
{ "locations": ["Rotterdam", "Paris, FR", "Portland, Oregon", "52.3676,4.9041"], "hours": 48 }
```

| Field | Meaning |
|---|---|
| `locations` | Up to 50 place names or `lat,lon` pairs. Required |
| `hours` | Hours ahead from the current hour, 1-240. Default 48 |
| `timezone` | IANA zone for times and days, e.g. `Europe/Amsterdam`. Default: the place's own zone, UTC for coordinates |
| `summary` | `true` (default): daily summary + next 12 hours. `false`: daily summary + every step |

**Place names** are matched against a built-in list of about 34,000 towns and cities with
15,000+ people, plus all capitals (GeoNames). Matching ignores case and accents, and knows
common other-language names ("Den Haag", "München"). When a name is shared ("Portland"), the
most populous place is used and `warnings` lists the others. Add a country or region after a
comma to choose: "Portland, Maine", "Paris, US", "Delft, NL". For anything smaller (a farm, a
venue, a wind turbine) give coordinates.

**Coordinates** are `lat,lon` in decimal degrees, latitude first: `52.3676,4.9041`. They are
rounded to 4 decimals (about 10 m), as MET Norway's terms require.

### Use from an AI agent (MCP)

Agents can call this Actor as a tool through the
[Apify MCP server](https://github.com/apify/apify-mcp-server). Add this server URL to your MCP
client (Claude, Cursor, VS Code, ...):

```text
https://mcp.apify.com?tools=bosco_labs/weather-forecast
```

It loads this Actor as a tool, plus the tools that read its results (`get-actor-run`,
`get-dataset-items`). The hosted server signs you in with OAuth, or accepts your Apify token as
`Authorization: Bearer <APIFY_TOKEN>`.

Example prompt: *"Will it rain in Amsterdam tomorrow afternoon?"* The agent passes:

```json
{ "locations": ["Amsterdam"], "hours": 48, "summary": false }
```

and reads the hourly `precipitation` for tomorrow 12:00-18:00 local time.

Example prompt: *"Wind speed forecast for these 5 wind farm coordinates, next 48 hours."*

```json
{ "locations": ["53.4167,6.1667", "54.0167,6.5833", "52.8,4.4", "51.65,3.0", "53.2,7.2"], "hours": 48, "summary": false, "timezone": "Europe/Amsterdam" }
```

**Output for agents:**

- About 7 KB per location with `summary: true`. With `false`: 18 KB for 48 hours, 33 KB for
  240\.
- Stable `snake_case` fields. Numbers are numbers, `null` means unknown, and arrays are never
  null.
- Times carry their UTC offset.
- `warnings` say in plain words what to fix (an ambiguous name, an unknown place, UTC because
  no timezone was given).

Measured locally on 2026-11-05: 4 locations in 1.0 s (4 requests to MET Norway). Repeating
the run took 0.9 s with 0 requests, served from the cache.

**Cost:** $0.0015 per location forecast, billed to the Apify account the MCP server is signed
in with. Unresolved locations are free.

### FAQ

**Where does the data come from?**

- **Forecast:** MET Norway's Locationforecast 2.0 (api.met.no). Outside the Nordic region it is
  based on the ECMWF global model. In the Nordic region MET uses its own high-resolution model,
  post-processed with local observations.
- **Place names:** GeoNames.
- **Sources per row:** `source_url` is the exact MET request; `place_source_url` is the
  GeoNames record.

**How fresh is it?** MET Norway updates Nordic forecasts every hour and the rest of the world
every 6 hours. Their terms forbid asking for the same point again within 30 minutes (Nordic)
or 3 hours (elsewhere), and before the response's `Expires` time. So this Actor keeps each
forecast in a key-value store named `weather-forecast-cache` in your Apify account, and serves
it from there until it may be refreshed. `fetched_at` shows when it was fetched.

**What is not included?**

- Past weather or observations; only current forecasts.
- Weather warnings and alerts.
- Air quality, marine and aviation (above-ground) forecasts.
- Wind at hub height. `wind_speed` is at 10 m above ground; for turbines, scale it up yourself.
- Gusts and precipitation probability outside the Nordic region.
- Forecasts beyond about 9.5 days. MET's forecast ends there, even with `hours: 240`.

**Why is the daily precipitation off by a little at midnight?** After the first ~2.5 days,
steps are 6 hours long. A 6-hour period counts toward the local day it starts in, so in
timezones that are not a multiple of 6 hours from UTC some rain can land on the neighbouring
day.

**My town isn't found.** The built-in list holds places with 15,000+ people and capitals. Give
the coordinates instead (`"lat,lon"`). Unknown places are free.

**Limits?**

- 50 locations per run.
- MET Norway is a free public service without an SLA. If it does not answer, the row is marked
  `source_error` and not charged. If a recent cached forecast exists (under 12 hours old), it
  is served with a warning instead.

**Licence and attribution.**

- Forecast: "Data from MET Norway", CC BY 4.0. Daily summaries and local times are derived by
  Bosco Labs and are not MET Norway's responsibility.
- Place names: GeoNames, CC BY 4.0.

If you republish the data, keep the `attribution` field. This Actor is not made or endorsed by
MET Norway or Yr. See `LEGAL.md`.

# Actor input Schema

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

Places to forecast, one per line: a town or city name, optionally with a country or region after a comma ("Amsterdam", "Paris, FR", "Portland, Oregon"), or coordinates as "lat,lon" in decimal degrees, latitude first ("52.3676,4.9041"; rounded to 4 decimals). Place names come from a built-in list of towns of 15,000+ people and capitals; for anything else (a farm, a venue, a wind turbine) give coordinates. Up to 50; repeats are forecast once. One output row per location. Required.

## `hours` (type: `integer`):

How far ahead to forecast, counted from the current hour, e.g. 48 for today and tomorrow. Max 240 (10 days; MET Norway's forecast ends after about 9.5). Steps are hourly for the first ~2.5 days, then every 6 hours. Default (or empty) = 48.

## `timezone` (type: `string`):

IANA timezone for output times and daily summaries, e.g. "Europe/Amsterdam", "America/New_York", "UTC". Empty (default) = the place's own timezone for place names, UTC for coordinates.

## `summary` (type: `boolean`):

true (default) = a daily summary for every day in `hours` plus only the next 12 hourly steps (about 7 KB per location). false = the daily summary plus every forecast step in `hours` (about 18 KB per location for 48 hours, 33 KB for 240). The price is the same.

## Actor input object example

```json
{
  "locations": [
    "Amsterdam",
    "51.9225,4.4792"
  ],
  "hours": 48,
  "summary": true
}
```

# Actor output Schema

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

No description

# 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 = {
    "locations": [
        "Amsterdam",
        "51.9225,4.4792"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("bosco_labs/weather-forecast").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 = { "locations": [
        "Amsterdam",
        "51.9225,4.4792",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("bosco_labs/weather-forecast").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 '{
  "locations": [
    "Amsterdam",
    "51.9225,4.4792"
  ]
}' |
apify call bosco_labs/weather-forecast --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,bosco_labs/weather-forecast"
        }
    }
}
```

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/cqCdSeMhsoh8T3FNE/builds/h1XWOhbkAKgUnAG2x/openapi.json
