# Weather Forecast Search (`ryanclinton/weather-forecast-search`) Actor

Get current weather conditions and multi-day forecasts for any location worldwide using the free Open-Meteo API. Search by city name (auto-geocoded) or direct latitude/longitude coordinates.

- **URL**: https://apify.com/ryanclinton/weather-forecast-search.md
- **Developed by:** [Ryan Clinton](https://apify.com/ryanclinton) (community)
- **Categories:** AI, Developer tools
- **Stats:** 27 total users, 4 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: 5.00 out of 5 stars

## Pricing

from $1.00 / 1,000 forecast fetcheds

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/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

## Weather Forecast & Operational Intelligence

![Weather Forecast & Operations Monitor — risk scores, alerts, recommendations, and portfolio monitoring](https://apifyforge.com/readme-assets/ryanclinton-weather-forecast-search/hero.png)

Monitor weather-driven operational risk across one site or an entire portfolio. Track changes run-to-run, rank locations, detect threshold crossings, surface the sites that need attention, and follow a feed of what changed — all powered by deterministic weather intelligence. Underneath it is a full forecast (current conditions, multi-day, hourly), but the output is built for **decisions**: a 0-100 risk score, recommended actions, exceptions, escalations, and site health. No API key required for the default data source.

Weather Forecast Search is an Apify actor that turns a place name or a pair of coordinates into a complete weather picture *plus the decisions that come with it*. By default it draws from the **MET Norway** weather API (the Norwegian Meteorological Institute), which is free and licensed for commercial use. Type a city like "London" or "Tokyo" and the actor resolves it to coordinates through OpenStreetMap, fetches the forecast, and returns temperature, feels-like, humidity, wind, precipitation, UV index, cloud cover, sunrise/sunset, threshold-based weather alerts, a deterministic risk score, operational-impact tags (travel-delay, frost, heat-stress, ideal-conditions…), forecast trend, and per-day confidence — ready for dashboards, automations, agents, or alerting pipelines.

Monitoring a fleet of sites? Pass a `locations` list and the actor returns one forecast record per location **plus a ranking summary** — best location, highest-risk location, and a portfolio risk-band breakdown — turning it into a weather operations center, not just a forecast API. Add a `watchlistName` to track what got worse since the last run, or `watchFor` thresholds to catch the day a limit is crossed. Have your own Open-Meteo commercial API key? Drop it in for full native fidelity — your subscription, your bill.

***

![Risk score per site, monitor a portfolio, track what changed, deterministic with no AI](https://apifyforge.com/readme-assets/ryanclinton-weather-forecast-search/feature-callouts.png)

### Why use Weather Forecast Search?

- **No API key needed to start** — the default MET Norway data source is free and commercially licensed (CC BY 4.0 / NLOD 2.0). Run it immediately, no signup.
- **Worldwide coverage** — any city name or any latitude/longitude on the planet, from capital cities to remote farms, airports, and offshore sites.
- **Weather alerts built in** — every run computes deterministic advisories for severe weather, extreme heat/cold, high wind, heavy precipitation, and high UV, so downstream automations can branch on conditions without parsing raw numbers.
- **Agent- and automation-ready** — a one-line `summary` string plus stable enum fields (`recordType`, `alerts[].severity`) drop straight into Dify, Zapier, Make, n8n, Slack rules, and AI agent tool calls.
- **Bring your own provider** — supply an Open-Meteo commercial key for full native fidelity and up to 16 forecast days; otherwise the free MET Norway source covers ~10 days.
- **Lightweight and cheap** — a run completes in seconds with minimal memory and one or two HTTP calls.

***

### Key features

- **Current conditions** — temperature, feels-like (apparent) temperature, humidity, precipitation, weather description, wind speed, wind direction, wind gusts (where available), cloud cover, and a day/night indicator.
- **Daily forecast** — high/low temperatures, feels-like range, sunrise, sunset, max UV index, precipitation totals, max wind speed and gusts, and dominant wind direction per day.
- **Weather intelligence layer** — a deterministic 0-100 `riskScore` and `riskLevel` (severe/high/moderate/low/minimal) on current and every day, plus `weatherImpacts[]` tags (travel-delay-risk, frost-risk, heat-stress-risk, high-uv-exposure, outdoor-event-risk, ideal-conditions…) and a top-level `overallRisk` you can branch on at a glance.
- **Recommended actions** — a `recommendations[]` array of deterministic action enums (avoid-outdoor-events, delay-high-wind-operations, uv-protection-recommended, frost-protection-recommended, conditions-favourable…).
- **Forecast outlook and stability** — a run-level `forecastOutlook` (0-100 + rating: is the week good or bad?) and a `stability` rating (stable/variable/volatile from day-to-day swings).
- **Prioritization layer** — `topRisks` decomposes each score into its biggest drivers (so you know *why*), `recovery` tells you the first day an elevated-risk forecast eases, and the multi-location `summary` surfaces an `exceptions` list (only the sites that need attention) plus a `comparison` explaining why the best site won.
- **Multi-location ranking + portfolio** — pass a `locations` list and get a `summary` record that ranks sites best-first, names the `bestLocation` and `highestRiskLocation`, and counts how many fall in each risk band. Monitor depots, stores, sites, or farms as one portfolio.
- **Persistent site intelligence** — set a `watchlistName` and the actor keeps a rolling history per location: each record gains a `change` block (deteriorating / improving / stable vs the prior run) *and* a `siteHealth` block (multi-run `trend`, `riskAverage`, `daysInHighRisk`). The multi-location `summary` adds an operations `feed` — a changelog of risk increases and threshold crossings across your sites. Answers "what has been happening?", not just "what's next?"
- **Threshold watch** — pass `watchFor` thresholds (e.g. temperature above 30, wind above 50) and the actor reports the first day each is crossed in `watchEvents`.
- **Industry lens (opt-in)** — set `industryMode` to `travel`, `agriculture`, `construction`, `events`, `drone`, or `logistics` for a deterministic sector assessment (flight-delay risk, frost/spraying/irrigation, crane risk, outdoor suitability, drone flight conditions, delivery disruption).
- **Trend and confidence** — a `trend` block (warming/cooling, wetter/drier across the window) and a lead-time `confidence` per day.
- **Best-time windows** — when hourly data is on, the actor surfaces favourable daytime windows (dry, light wind, comfortable) for outdoor work, events, and photography.
- **Multi-location batch mode** — pass a `locations` list and get one forecast record per place in a single run.
- **Optional hourly breakdown** — temperature, humidity, precipitation, weather code, wind speed, and wind direction for each hour.
- **Deterministic weather alerts** — threshold-based advisories and warnings for thunderstorms, extreme heat/cold, freezing, high/strong wind, heavy precipitation, snow, and high/very-high/extreme UV.
- **One-line summary** — a plain-English `summary` an LLM, agent, or dashboard can quote verbatim.
- **City geocoding or direct coordinates** — resolve any place name via OpenStreetMap Nominatim, or pass exact latitude (-90 to 90) and longitude (-180 to 180).
- **Celsius or Fahrenheit**, plus a configurable IANA timezone (or `auto`, derived from the location).
- **Stable, versioned output** — every record carries a `schemaVersion` and a `recordType` discriminator for clean downstream filtering.

All intelligence is **deterministic** — computed from documented thresholds, no AI and no fabrication. The same forecast always produces the same scores and tags.

***

### How to use Weather Forecast Search

#### Using the Apify Console

1. Open the [Weather Forecast Search actor](https://apify.com/ryanclinton/weather-forecast-search) on the Apify Store.
2. Click **Try for free** to open it in Apify Console.
3. Enter a **Location** (a city such as "London", "Tokyo", or "San Francisco") or provide **Latitude** and **Longitude** directly.
4. Set the number of **Forecast Days** (1 to 16; default 7).
5. Optionally enable **Include Hourly Forecast**.
6. Choose your **Temperature Unit** (Celsius or Fahrenheit) and a **Timezone** (or leave `auto`).
7. (Optional) Under **Advanced**, paste an **Open-Meteo API key** to use your own commercial subscription.
8. Click **Start**, then read or download the result from the **Dataset** tab as JSON, CSV, or Excel.

#### Using the Apify API

```bash
curl -X POST "https://api.apify.com/v2/acts/TpfQHy4R1EZT3ZqOp/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "location": "Tokyo",
    "forecastDays": 5,
    "includeHourly": true,
    "temperatureUnit": "celsius",
    "timezone": "auto"
  }'
```

#### Using the Apify CLI

```bash
apify call ryanclinton/weather-forecast-search -i '{
  "location": "Berlin",
  "forecastDays": 3,
  "temperatureUnit": "celsius"
}'
```

***

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `location` | String | No\* | `"New York"` | City name to search for. Geocoded to coordinates via OpenStreetMap. Ignored if `locations` is set or if latitude/longitude are provided. |
| `locations` | String\[] | No\* | — | Batch mode: a list of city names (up to 25). Returns one forecast record per location. Overrides `location` when set. |
| `latitude` | Number | No\* | — | Direct latitude (-90 to 90). Overrides location when both lat and lon are set. |
| `longitude` | Number | No\* | — | Direct longitude (-180 to 180). Overrides location when both lat and lon are set. |
| `forecastDays` | Integer | No | `7` | Number of forecast days (1 to 16). MET Norway provides ~10 days; an Open-Meteo key reaches 16. |
| `includeHourly` | Boolean | No | `false` | Include an hourly weather breakdown. |
| `temperatureUnit` | String | No | `"celsius"` | `"celsius"` or `"fahrenheit"`. |
| `timezone` | String | No | `"auto"` | IANA timezone (e.g. `"America/New_York"`). `"auto"` derives it from the location's coordinates. |
| `industryMode` | String | No | `"none"` | Optional sector lens: `travel`, `agriculture`, `construction`, `events`, `drone`, or `logistics`. Adds an `industry` assessment block. |
| `watchFor` | Object | No | — | Threshold watch. Keys: `temperatureAbove`, `temperatureBelow`, `windSpeedAbove`, `precipitationAbove`, `uvIndexAbove`. Reports the first day each is crossed in `watchEvents`. |
| `watchlistName` | String | No | — | Turns on cross-run change detection. Each location record gains a `change` block vs the prior run on this watchlist. |
| `openMeteoApiKey` | String (secret) | No | — | Your own Open-Meteo commercial API key. When set, forecasts come from Open-Meteo at full native fidelity. When blank, the free MET Norway source is used. |

\*You must provide either `location` or both `latitude` and `longitude`.

#### Input example

```json
{
  "location": "Paris",
  "forecastDays": 10,
  "includeHourly": true,
  "temperatureUnit": "celsius",
  "timezone": "Europe/Paris"
}
```

#### Batch input example (multiple locations)

```json
{
  "locations": ["London", "Paris", "Berlin", "Madrid"],
  "forecastDays": 5,
  "temperatureUnit": "celsius"
}
```

#### Industry-lens example (agriculture)

```json
{
  "location": "Fresno",
  "forecastDays": 7,
  "industryMode": "agriculture"
}
```

#### Operations-monitoring example (fleet of sites, with change detection)

```json
{
  "locations": ["Liverpool", "Manchester", "London", "Leeds"],
  "forecastDays": 3,
  "watchlistName": "uk-depots",
  "watchFor": { "windSpeedAbove": 50, "temperatureBelow": 0 }
}
```

A multi-location run also emits one `recordType: "summary"` record:

```json
{
  "recordType": "summary",
  "actionRequired": true,
  "criticalSites": 1,
  "topOperationalRisk": "wind",
  "locationCount": 4,
  "bestLocation": "London",
  "highestRiskLocation": "Liverpool",
  "portfolioSummary": { "severe": 0, "high": 1, "moderate": 1, "low": 1, "minimal": 1 },
  "exceptions": [
    { "location": "Liverpool", "severity": "high", "reason": "wind-risk" }
  ],
  "comparison": {
    "winner": "London",
    "reasons": ["best operational score (88 vs portfolio average 66)", "lowest risk band (minimal)"]
  },
  "escalations": [
    { "location": "Liverpool", "reason": "entered-high-risk-band" }
  ],
  "feed": [
    { "type": "risk-increase", "location": "Liverpool", "delta": 18 },
    { "type": "threshold-crossed", "location": "Leeds", "threshold": "wind-above" }
  ],
  "watchlistHealth": { "status": "deteriorating", "riskDelta": 18 },
  "portfolioMovement": { "critical": 1, "deteriorating": 2, "improving": 1, "stable": 1, "safe": 2 },
  "rankings": [
    { "rank": 1, "location": "London", "operationalScore": 88, "overallRisk": "minimal", "riskScore": 8, "topRisk": null },
    { "rank": 4, "location": "Liverpool", "operationalScore": 34, "overallRisk": "high", "riskScore": 58, "topRisk": "wind" }
  ]
}
```

***

### Output

![Sample output — location, overall risk, operational score, risk trend, top risk, recommendation](https://apifyforge.com/readme-assets/ryanclinton-weather-forecast-search/output-table.png)

The actor outputs a single structured JSON record per run to the default dataset.

#### Output example

```json
{
  "schemaVersion": "2.0",
  "recordType": "forecast",
  "location": {
    "name": "London",
    "country": "United Kingdom",
    "latitude": 51.5074,
    "longitude": -0.1278,
    "elevation": null,
    "timezone": "Europe/London"
  },
  "overallRisk": "low",
  "forecastOutlook": { "score": 82, "rating": "excellent" },
  "stability": { "score": 75, "rating": "stable" },
  "recommendations": ["uv-protection-recommended"],
  "trend": { "temperature": "warming", "precipitation": "stable" },
  "current": {
    "temperature": 14.2,
    "feelsLike": 12.8,
    "humidity": 72,
    "precipitation": 0,
    "weatherCode": 2,
    "weatherDescription": "Partly cloudy",
    "windSpeed": 15.3,
    "windDirection": 230,
    "windGusts": null,
    "cloudCover": 45,
    "isDay": true,
    "riskScore": 0,
    "riskLevel": "minimal",
    "weatherImpacts": ["ideal-conditions"]
  },
  "daily": [
    {
      "date": "2026-06-04",
      "weatherCode": 3,
      "weatherDescription": "Overcast",
      "tempMax": 16.4,
      "tempMin": 9.1,
      "feelsLikeMax": 14.8,
      "feelsLikeMin": 6.7,
      "sunrise": "2026-06-04T04:42",
      "sunset": "2026-06-04T21:11",
      "uvIndexMax": 4.3,
      "precipitationSum": 1.2,
      "rainSum": 1.2,
      "windSpeedMax": 22.6,
      "windGustsMax": null,
      "windDirection": 215,
      "riskScore": 8,
      "riskLevel": "minimal",
      "weatherImpacts": ["ideal-conditions"],
      "confidence": 96
    }
  ],
  "alerts": [
    { "type": "high-uv", "severity": "advisory", "message": "High UV on 2026-06-06: index 7.", "day": "2026-06-06" }
  ],
  "summary": "London, United Kingdom — currently 14.2°C, Partly cloudy. Next 7 days: 9.1°C to 24.5°C. 1 weather alert.",
  "dataSource": "MET Norway",
  "attribution": "Weather data: MET Norway (api.met.no), licensed CC BY 4.0 / NLOD 2.0. Geocoding: © OpenStreetMap contributors (ODbL).",
  "extractedAt": "2026-06-04T13:39:46.903Z"
}
```

#### Output fields

| Field | Type | Description |
|-------|------|-------------|
| `schemaVersion` | String | Output contract version. Branch on this to detect shape changes. |
| `recordType` | String | `forecast` for results, `notice` or `error` for diagnostics. |
| `summary` | String | One-line plain-English summary of conditions, range, and alert count. |
| `overallRisk` | String | Worst risk level across current + daily: `severe`/`high`/`moderate`/`low`/`minimal`. The at-a-glance status. |
| `forecastOutlook` | Object | `{ score: 0-100, rating: excellent/good/fair/poor }` — is the window good or bad? |
| `stability` | Object | `{ score: 0-100, rating: stable/variable/volatile }` from day-to-day temperature, wind, and precipitation swings. |
| `recommendations` | Array | Deterministic recommended-action enums (e.g. `avoid-outdoor-events`, `uv-protection-recommended`, `conditions-favourable`). |
| `industry` | Object | Present only when `industryMode` is set. Sector assessment with a `mode` discriminator (travel/agriculture/construction/events/drone/logistics). |
| `watchEvents` | Array | Present only when `watchFor` is set. First forecast day each threshold is crossed: `{ type, threshold, day, value }`. |
| `change` | Object | Present only when `watchlistName` is set. Cross-run change vs the prior run: `{ status, changeType, riskDelta, previousRiskScore, previousSeenAt }`. |
| `siteHealth` | Object | Present only when `watchlistName` is set. Longitudinal: `{ runsTracked, riskAverage, daysInHighRisk, trend }`. |
| `recovery` | Object | Present only when `overallRisk` is high/severe: `{ expectedDay, riskAfterRecovery }`. |
| `timeline` | Array | Present only when hourly is on: daytime `good`/`fair`/`poor` segments `{ day, from, to, status }`. |
| `current.topRisks` / `daily[].topRisks` | Array | The biggest drivers of each risk score: `[{ type, contribution, reason }]`. |
| `riskTrajectory` | Array | Day-by-day risk series `[{ day, riskScore }]`. |
| `riskTrend` | String | Risk direction over the window: `rapidly-deteriorating` / `deteriorating` / `stable` / `improving` / `rapidly-improving`. |
| `trend` | Object | `temperature` (warming/cooling/stable) and `precipitation` (increasing/decreasing/stable) over the window. Null if too few days. |
| **Summary record** (`recordType: "summary"`, multi-location only) | — | `actionRequired`, `criticalSites`, `topOperationalRisk`, `bestLocation`, `highestRiskLocation`, `portfolioSummary`, `rankings[]`, `exceptions[]`, `comparison`, and — on watchlist runs — `escalations[]` (band transitions), `feed[]` (operations changelog), `watchlistHealth`, `portfolioMovement`. |
| `bestWindows[]` | Array | Favourable daytime windows (dry, light wind, comfortable), present only when `includeHourly` is true. Each has `day`, `start`, `end`, `reason`. |
| `alerts[]` | Array | Deterministic threshold advisories. Each has `type`, `severity` (`warning`/`advisory`), `message`, and `day`. |
| `location` | Object | Resolved location: name, country, latitude, longitude, elevation, timezone. |
| `current.*` | Object | Current conditions plus `riskScore` (0-100), `riskLevel`, and `weatherImpacts[]`. |
| `daily[]` | Array | Per-day forecast plus `riskScore`, `riskLevel`, `weatherImpacts[]`, and `confidence` (lead-time, 0-100). |
| `hourly[]` | Array | Per-hour forecast (optional, when `includeHourly` is true). |
| `dataSource` | String | Upstream provider: `MET Norway` or `Open-Meteo (commercial)`. |
| `attribution` | String | Required data-provider attribution (CC BY 4.0 / ODbL). |
| `extractedAt` | String | ISO 8601 timestamp of when the data was collected. |
| `failureType` | String | Present only on `notice`/`error` records: `no-data`, `invalid-input`, `upstream-unreachable`, or `unknown`. |

#### Weather alerts

The actor scans the forecast and emits deterministic alerts using documented meteorological thresholds — no AI, no fabrication:

| Alert type | Severity | Fires when |
|------------|----------|------------|
| `thunderstorm` | warning | Current or forecast thunderstorm conditions |
| `extreme-heat` / `heat` | warning / advisory | Daily high ≥ 35°C / ≥ 30°C (95°F / 86°F) |
| `extreme-cold` / `freezing` | warning / advisory | Daily low ≤ -10°C / ≤ 0°C (14°F / 32°F) |
| `high-wind` / `strong-wind` | warning / advisory | Max wind ≥ 75 / ≥ 50 km/h |
| `heavy-precipitation` / `precipitation` | warning / advisory | Daily precipitation ≥ 50 / ≥ 20 mm |
| `extreme-uv` / `very-high-uv` / `high-uv` | warning / advisory | Max UV index ≥ 11 / ≥ 8 / ≥ 6 |
| `snow` | advisory | Snow in the daily forecast |

***

### Weather intelligence

![Intelligence stack — location to geocoding, forecast, risk scoring, impacts, alerts, monitoring, operations output](https://apifyforge.com/readme-assets/ryanclinton-weather-forecast-search/intelligence-layers.png)

Beyond raw numbers, every record carries a deterministic decision layer so your automation does not have to interpret the forecast itself.

- **`riskScore` (0-100) and `riskLevel`** — a composite of wind, precipitation, temperature extremes, UV, and severe-weather codes, on `current` and every `daily` entry. Bands: `severe` ≥ 70, `high` ≥ 50, `moderate` ≥ 30, `low` ≥ 12, else `minimal`.
- **`overallRisk`** — the worst `riskLevel` across the whole forecast: one field to branch on for "is this location a problem?"
- **`weatherImpacts[]`** — stable enum tags describing what the weather *means*: `travel-delay-risk`, `outdoor-event-risk`, `frost-risk`, `heat-stress-risk`, `extreme-heat-risk`, `high-wind-risk`, `heavy-rain-risk`, `snow-risk`, `thunderstorm-risk`, `high-uv-exposure`, or `ideal-conditions`.
- **`topRisks`** — the score's biggest drivers, each with a plain-English reason, e.g. `[{ "type": "wind", "contribution": 40, "reason": "forecast winds up to 72 km/h" }]`. Answers "why is this risky?"
- **`recovery`** — when `overallRisk` is high or severe, the first forecast day risk eases to low/minimal and the level then. Answers "when does it improve?"
- **`riskTrajectory` + `riskTrend`** — the day-by-day risk score as a series, plus a direction (`rapidly-deteriorating` … `rapidly-improving`). See risk *evolve*, not just a snapshot.
- **`timeline`** — when hourly is on, the day split into `good`/`fair`/`poor` segments for scheduling operations.
- **`escalations`** (watchlist summary) — band-level state transitions across the portfolio (`entered-high-risk-band` / `left-high-risk-band`). Operations think in transitions, not values.
- **`recommendations[]`** — recommended-action enums derived from those impacts: `avoid-outdoor-events`, `delay-high-wind-operations`, `prepare-for-wet-conditions`, `allow-extra-travel-time`, `frost-protection-recommended`, `heat-precautions-recommended`, `uv-protection-recommended`, `monitor-severe-weather`, or `conditions-favourable`.
- **`forecastOutlook`** — a run-level 0-100 score + rating answering "is the next few days good or bad?" — this *is* the operational score (100 = perfect operating conditions, 0 = impossible). The dashboard headline metric.
- **`stability`** — 0-100 + `stable`/`variable`/`volatile` from how much temperature, wind, and precipitation swing day to day. Operations teams care about predictability.
- **`industry`** (opt-in via `industryMode`) — a sector assessment from the same engine. `travel`: `flightDelayRisk` + `drivingConditions`. `agriculture`: `frostRisk` + `heatStressRisk` + `sprayingConditions` + `irrigationNeed`. `construction`: `workability` + `concretePourRisk` + `craneRisk`. `events`: `outdoorSuitability` + `weatherRisk`.
- **`trend`** — whether temperature is `warming`/`cooling` and precipitation `increasing`/`decreasing` across the window.
- **`confidence`** — a per-day lead-time confidence (near-term days score higher than long-range; a documented heuristic, not an ensemble spread).
- **`bestWindows[]`** — when hourly is on, the favourable daytime windows for outdoor activity.

All of it is computed from documented thresholds — deterministic, reproducible, and free of AI.

***

### Data sources and attribution

This actor uses openly licensed data. When you republish or display the output, keep the attribution string the actor provides.

- **Weather (default):** [MET Norway](https://api.met.no/) — the Norwegian Meteorological Institute, licensed under NLOD 2.0 and CC BY 4.0. Commercial use is permitted with credit to "MET Norway".
- **Weather (optional):** [Open-Meteo](https://open-meteo.com/) commercial API, used only when you supply your own API key. Billed to your Open-Meteo subscription.
- **Geocoding:** [OpenStreetMap](https://www.openstreetmap.org/) Nominatim, © OpenStreetMap contributors, licensed under the ODbL.

***

### Use in Dify

Weather Forecast Search returns decisions, not just raw numbers — a top-level `overallRisk` enum, a `recordType` discriminator, and an `alerts[]` array whose entries carry a stable `severity` (`warning` / `advisory`) and `type`. Dify's if/else branching nodes route on equality matches, so a weather-monitoring agent plugs in cleanly: pull the forecast, branch on `overallRisk`, and act. Competitors pointed at the same source return raw numbers; this returns the risk call your downstream node branches on.

- **Actor ID:** `TpfQHy4R1EZT3ZqOp`

Sample input for a scheduled multi-location watch:

```json
{
  "locations": ["Miami", "Houston", "New Orleans"],
  "forecastDays": 3,
  "temperatureUnit": "celsius"
}
```

Branching example (Dify if/else node):

- **If** `recordType` equals `error` → notify the operator that the forecast run failed (read `failureType`).
- **Else if** `overallRisk` equals `severe` or `high` → send a severe-weather alert to Slack with the `summary` and any `alerts[].message`.
- **Else if** `overallRisk` equals `moderate` → log a heads-up for review.
- **Else** → store the `summary` and continue.

The `summary`, `weatherImpacts[]`, and `alerts[].message` values are usable verbatim — no LLM rewriting needed.

***

### Use cases

- **Daily weather briefings** — schedule a morning run and push the `summary` and any alerts to Slack, email, or a dashboard.
- **Severe-weather monitoring** — branch automations on `alerts[].severity` to notify teams about heat, cold, wind, or storms.
- **Travel planning** — check destination conditions 1–16 days ahead before booking or packing.
- **Agriculture and field operations** — track temperature extremes, precipitation totals, UV, and wind for planting, irrigation, and harvest decisions.
- **Event and construction planning** — watch the forecast leading up to outdoor work and flag weather risk early.
- **Energy and demand forecasting** — feed temperature forecasts into heating/cooling demand models.
- **AI agents and pipelines** — give an agent a single tool that turns a place name into structured weather plus a quotable summary.

***

### API and integrations

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run_input = {
    "location": "New York",
    "forecastDays": 7,
    "temperatureUnit": "fahrenheit",
    "timezone": "America/New_York",
}

run = client.actor("TpfQHy4R1EZT3ZqOp").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["summary"])
    for day in item.get("daily", []):
        print(f"  {day['date']}: {day['tempMin']} - {day['tempMax']}, {day['weatherDescription']}")
```

#### JavaScript

```javascript
import { ApifyClient } from "apify-client";

const client = new ApifyClient({ token: "YOUR_API_TOKEN" });

const run = await client.actor("TpfQHy4R1EZT3ZqOp").call({
  location: "Sydney",
  forecastDays: 5,
  includeHourly: true,
  temperatureUnit: "celsius",
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const item of items) {
  console.log(item.summary);
  for (const alert of item.alerts ?? []) console.log(`  [${alert.severity}] ${alert.message}`);
}
```

#### cURL

```bash
## Start a run
curl -X POST "https://api.apify.com/v2/acts/TpfQHy4R1EZT3ZqOp/runs?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"location": "Berlin", "forecastDays": 3}'

## Fetch the result (replace DATASET_ID from the run response)
curl "https://api.apify.com/v2/datasets/DATASET_ID/items?token=YOUR_API_TOKEN"
```

#### Integrations

Works with all native Apify integrations: **Google Sheets**, **Slack**, **Zapier**, **Make (Integromat)**, **n8n**, and **webhooks/REST API**. Schedule recurring runs to build weather-monitoring pipelines on autopilot.

***

### How it works

1. **Input validation** — the actor checks for a city name or latitude/longitude. At least one is required.
2. **Geocoding (if needed)** — a city name is resolved to coordinates via OpenStreetMap Nominatim; the timezone is derived from those coordinates (or taken from your `timezone` input).
3. **Forecast fetch** — with no API key, the actor calls MET Norway (`api.met.no`); with an Open-Meteo key, it calls `customer-api.open-meteo.com`. Both calls retry transient network errors with exponential backoff.
4. **Normalisation** — the provider response is mapped to a single, consistent output shape (units converted, weather codes resolved, daily values aggregated, sunrise/sunset computed).
5. **Alerts and summary** — deterministic threshold alerts and a one-line summary are computed from the forecast.
6. **Output** — the structured record is written to the Apify dataset with attribution.

```
Input --> Geocoding (OpenStreetMap, if city name) --> Coordinates + timezone
              |
              v
       MET Norway (default) or Open-Meteo (your key) --> Normalise --> Alerts + Summary --> Dataset
```

***

### Performance and cost

| Metric | Value |
|--------|-------|
| Average run time | 3 to 8 seconds |
| Memory | 256 MB default |
| External API cost | Free (MET Norway), or billed to your own Open-Meteo subscription |
| Max forecast range | ~10 days (MET Norway) / 16 days (Open-Meteo key) |

***

### What this actor does NOT do

Honest scope so you know what you are getting:

- **Not real-time severe-weather warnings.** The `alerts` are computed from forecast thresholds, not official government warnings. For life-safety alerts, use your national meteorological agency.
- **Not historical weather.** It returns current conditions and forecasts only, not past observations.
- **Up to 25 locations per run.** Pass a `locations` list to monitor a portfolio in one run; for larger fleets, split across multiple runs (via API or scheduled tasks).
- **Wind gusts and UV can be null on the free source.** MET Norway does not provide wind gusts for every location, and clear-sky UV is populated mainly for the near-term days. On the free source, feels-like temperature is computed (Bureau of Meteorology apparent-temperature formula) rather than supplied. For complete native fields, use an Open-Meteo commercial key.
- **Geocoding returns the top match.** Ambiguous names (e.g. "Springfield") may resolve to an unintended place — pass coordinates directly for precision.
- **Change detection needs at least two runs.** The first run on a new `watchlistName` marks every location `change.status: "new"`; deltas appear from the second run onward. Schedule the actor for it to be useful.

***

### Responsible use

- **Keep the attribution.** When you republish or display this data, credit MET Norway and OpenStreetMap as the actor's `attribution` field states (a licence requirement).
- **Do not rely on it alone for safety-critical decisions.** Supplement with official warnings for severe weather, evacuations, and emergencies.
- **Rate-limit your runs.** Once per hour or a few times per day is plenty for most monitoring; avoid excessive polling.

***

### FAQ

**Does this actor require an API key?**
No. The default MET Norway data source is free and needs no key. You can optionally supply your own Open-Meteo commercial key for full native fidelity and up to 16 days.

**Where does the weather data come from?**
By default, MET Norway (the Norwegian Meteorological Institute), which is free and licensed for commercial use. If you supply an Open-Meteo commercial key, data comes from Open-Meteo instead.

**How many forecast days can I get?**
Up to ~10 days on the free MET Norway source, or up to 16 days with your own Open-Meteo key.

**What are the weather alerts?**
Deterministic advisories computed from documented thresholds (severe weather, extreme heat/cold, high wind, heavy precipitation, high UV). They are signals for automation, not official government warnings.

**Why is `windGusts` or `uvIndexMax` sometimes null?**
MET Norway does not provide wind gusts for every location, and clear-sky UV is mainly available for the near-term days. Use an Open-Meteo key for fuller native coverage.

**Can I get weather for exact coordinates?**
Yes. Provide `latitude` and `longitude` and the actor skips geocoding.

**Celsius or Fahrenheit?**
Both. Set `temperatureUnit` to `"celsius"` or `"fahrenheit"`; all temperatures use your choice.

**Can I set a custom timezone?**
Yes. Pass any IANA timezone (e.g. `"Asia/Tokyo"`), or use `"auto"` to derive it from the location.

**Is this good for AI agents and automations?**
Yes. The `summary` string, `recordType`, and `alerts[].severity` are designed for tool calls and if/else routing in Dify, Zapier, Make, and n8n.

***

### Related actors

| Actor | Description |
|-------|-------------|
| [Nominatim Geocoder](https://apify.com/ryanclinton/nominatim-geocoder) | Convert place names to coordinates, or reverse-geocode, using OpenStreetMap data. |
| [NOAA Weather Alert Monitor](https://apify.com/ryanclinton/noaa-weather-alerts) | Monitor official severe-weather alerts and warnings for United States locations. |
| [Sunrise Sunset Search](https://apify.com/ryanclinton/sunrise-sunset-search) | Detailed sunrise, sunset, and twilight phase data for any location worldwide. |
| [OpenStreetMap POI Search](https://apify.com/ryanclinton/osm-poi-search) | Search points of interest, businesses, and landmarks with geographic filtering. |

# Actor input Schema

## `location` (type: `string`):

City name to search for (will be geocoded to coordinates). Ignored if 'locations' is set, or if latitude/longitude are provided.

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

Optional. A list of city names to fetch in one run — the actor returns one forecast record per location. Overrides the single 'location' field when set. Up to 25 locations per run.

## `latitude` (type: `number`):

Direct latitude coordinate. Overrides location if both latitude and longitude are provided.

## `longitude` (type: `number`):

Direct longitude coordinate. Overrides location if both latitude and longitude are provided.

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

Number of forecast days (1-16).

## `includeHourly` (type: `boolean`):

Include hourly weather breakdown in the output.

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

Temperature unit for the forecast.

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

Timezone for the forecast (e.g., 'America/New\_York', 'Europe/London'). Use 'auto' to detect it from the location's coordinates.

## `industryMode` (type: `string`):

Optional. Adds a deterministic 'industry' assessment for your sector: travel (flight delay + driving conditions), agriculture (frost, spraying, irrigation), construction (workability, crane risk, concrete pour), events (outdoor suitability + weather risk), drone (flight conditions from wind/gusts/precip), or logistics (delivery disruption risk). Default 'none'.

## `watchFor` (type: `object`):

Optional. Report the first forecast day each threshold is crossed (in your chosen units). Keys: temperatureAbove, temperatureBelow, windSpeedAbove (km/h), precipitationAbove (mm), uvIndexAbove. Example: {"temperatureAbove": 30, "windSpeedAbove": 50}.

## `watchlistName` (type: `string`):

Optional. Set a stable name to turn on persistent monitoring — the actor keeps a rolling per-location history. Each record gains a 'change' block (vs the prior run) and a 'siteHealth' block (multi-run trend, risk average, days in high risk), and the multi-location summary gains an operations 'feed'. The first run marks everything 'new'; trends sharpen as runs accumulate.

## `openMeteoApiKey` (type: `string`):

Optional. Provide your own Open-Meteo commercial API key to fetch forecasts from customer-api.open-meteo.com at full native fidelity (billed to your Open-Meteo subscription). Leave blank to use the free, commercially-licensed MET Norway data source.

## Actor input object example

```json
{
  "location": "New York",
  "forecastDays": 7,
  "includeHourly": false,
  "temperatureUnit": "celsius",
  "timezone": "auto",
  "industryMode": "none"
}
```

# 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 = {
    "location": "New York"
};

// Run the Actor and wait for it to finish
const run = await client.actor("ryanclinton/weather-forecast-search").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 = { "location": "New York" }

# Run the Actor and wait for it to finish
run = client.actor("ryanclinton/weather-forecast-search").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "location": "New York"
}' |
apify call ryanclinton/weather-forecast-search --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=ryanclinton/weather-forecast-search",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/TpfQHy4R1EZT3ZqOp/builds/eZCFjYhSh1ytGOHZl/openapi.json
