# Dark Sky Replacement (`nexgendata/dark-sky-replacement`) Actor

Drop-in replacement for the killed Dark Sky API. Wraps Open-Meteo's free weather data and reshapes it to match Dark Sky's exact JSON schema. Zero auth, zero cost for the data itself.

- **URL**: https://apify.com/nexgendata/dark-sky-replacement.md
- **Developed by:** [Stephan Corbeil](https://apify.com/nexgendata) (community)
- **Categories:** Developer tools, Automation, Business
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

$2.00 / 1,000 weather forecast per coordinates

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 a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Dark Sky API Replacement — The Drop-In Weather Wrapper Your Legacy Code Has Been Waiting For

> **Your Dark Sky integration broke on March 31, 2023. This actor makes it work again — same JSON shape, same field names, no rewrite required.**

On March 31, 2023, Apple flipped the switch and the Dark Sky API — the one that powered half the weather apps, commute notifiers, agritech dashboards, irrigation controllers, and smart-home routines on the internet — simply stopped answering. No grace period, no drop-in successor, no "use this URL instead" migration guide. Apple rolled Dark Sky's tech into [WeatherKit](https://developer.apple.com/weatherkit/), a paid, Apple-ID-gated iOS/macOS SDK that is **useless** to anyone running a Python cron job, a Home Assistant blueprint, a Node.js Slack bot, an n8n workflow, a Rails backend, a Flutter app on non-Apple platforms, or basically any non-Xcode codebase on the planet.

Thousands of indie apps, academic research pipelines, and production integrations were left with two options: ship a full rewrite against OpenWeatherMap / Tomorrow.io / Visual Crossing (each with a *different* response shape, a *different* auth model, and a *different* paid tier wall), or let the feature die.

**This actor is the third option.** It wraps the excellent, genuinely-free, academically-backed [Open-Meteo](https://open-meteo.com/) API and reshapes the response to match Dark Sky's **exact** JSON schema — `currently`, `hourly.data[]`, `daily.data[]`, `icon`, `summary`, `temperature`, `apparentTemperature`, `dewPoint`, `humidity`, `pressure`, `windSpeed`, `windBearing`, `cloudCover`, `uvIndex`, `visibility`, all of it. Point your existing Dark Sky client at this actor's dataset instead of `api.darksky.net` and most integrations keep working with zero code changes beyond the base URL.

Zero auth. No API keys. No monthly minimum. You pay `$0.002` per forecast event via Apify's pay-per-event billing; the underlying weather data itself is free.

---

### Why Open-Meteo Is the Right Backend

Open-Meteo is a German-run, academically-supported weather API that aggregates data from the national forecasting services (DWD, NOAA/NWS, Météo-France, ECMWF, JMA, CMC, MeteoSwiss, etc.) and serves it through a clean, CORS-friendly HTTP endpoint. Relevant points:

- **Free for non-commercial use out of the box, no API key.** Commercial tiers exist but most small-to-mid workloads fit under the free ceiling.
- **High-resolution global coverage.** Runs the same numerical models the national services run — the data quality is excellent.
- **Variables match Dark Sky's field set almost 1:1.** Temperature, apparent temperature, dew point, relative humidity, surface pressure, wind (speed + bearing), cloud cover, UV index, visibility, precipitation amount, precipitation probability, weather code — every one of these has a direct Dark Sky counterpart.
- **Unit systems are selectable on the request.** Fahrenheit/mph/inches (Dark Sky US default), Celsius/m-s/mm (SI), Celsius/km-h/mm (CA), Celsius/mph/mm (UK2) — all handled server-side, so your reshaped Dark Sky `flags.units` value stays honest.
- **Reasonable terms.** Open-source, documented methodology, no predatory enterprise funnel.

Open-Meteo is what Dark Sky would look like if it were reborn in 2023 as a public-good project instead of being absorbed into an Apple platform SDK. This actor's only job is to paper over the shape difference so your existing code doesn't care.

---

### Side-by-Side Schema Mapping

Here's how every Dark Sky field maps back to Open-Meteo — and where we had to fill gaps or soften the promise.

| Dark Sky field | Open-Meteo field | Notes |
|---|---|---|
| `latitude` | `latitude` | Identical. |
| `longitude` | `longitude` | Identical. |
| `timezone` | `timezone` | Identical (IANA tz name, e.g. `America/Los_Angeles`). |
| `offset` | `utc_offset_seconds / 3600` | Converted to hours to match Dark Sky. |
| `currently.time` | `current.time` | ISO-8601 converted to Unix epoch seconds. |
| `currently.summary` | derived from `weather_code` | We map WMO codes to Dark Sky-style short text ("Partly Cloudy", "Light Rain", etc.). |
| `currently.icon` | derived from `weather_code` + `is_day` | WMO code → Dark Sky icon slug (`clear-day`, `partly-cloudy-night`, `rain`, `snow`, `sleet`, `fog`, `cloudy`, `thunderstorm`). |
| `currently.temperature` | `temperature_2m` | Units follow the selected preset. |
| `currently.apparentTemperature` | `apparent_temperature` | Direct. |
| `currently.dewPoint` | `dew_point_2m` | Direct. |
| `currently.humidity` | `relative_humidity_2m / 100` | Open-Meteo returns 0–100, Dark Sky returned 0.0–1.0. We scale. |
| `currently.pressure` | `surface_pressure` | hPa. |
| `currently.windSpeed` | `wind_speed_10m` | Units follow preset. |
| `currently.windBearing` | `wind_direction_10m` | Degrees, 0–359. |
| `currently.cloudCover` | `cloud_cover / 100` | Scaled 0.0–1.0 to match Dark Sky. |
| `currently.uvIndex` | `uv_index` | Direct. |
| `currently.visibility` | `visibility` | Meters in SI units, miles in US preset. |
| `currently.precipIntensity` | `precipitation` | Units follow preset. |
| `currently.precipProbability` | `precipitation_probability / 100` | Scaled to 0.0–1.0. |
| `hourly.data[]` | `hourly.*` arrays | Zipped index-by-index into Dark Sky's "array of objects" shape. |
| `daily.data[]` | `daily.*` arrays | Same — includes `sunriseTime` / `sunsetTime` converted to epoch. |
| `alerts[]` | *(no equivalent)* | Open-Meteo does not publish unified severe-weather alerts. We return `[]` when requested and add a `flags.alerts_note` explainer. See Limitations. |
| `flags.units` | — | Echoed from your input. |
| `flags.sources` | — | Set to `["open-meteo"]`. |

Fields like `nearestStormDistance`, `ozone`, and `moonPhase` that Dark Sky exposed but Open-Meteo doesn't mirror by default are simply omitted rather than returned as fake zeros. If your code `.get()`s them with a default, nothing changes.

---

### Drop-In Migration Example

**Before (Dark Sky, dead since March 2023):**

````

GET https://api.darksky.net/forecast/YOUR\_API\_KEY/37.7749,-122.4194?units=us

````

**After (this actor, synchronous mode):**

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/nexgendata~dark-sky-replacement/run-sync-get-dataset-items?token=YOUR_APIFY_TOKEN" \
  -H 'Content-Type: application/json' \
  -d '{
    "coordinates": ["37.7749,-122.4194"],
    "units": "us",
    "days": 7
  }'
````

The response body is a JSON **array** of one forecast object, where that object has the exact same `latitude / longitude / timezone / currently / hourly.data / daily.data` shape Dark Sky used to return. If your code did:

```python
forecast = requests.get(darksky_url).json()
temp = forecast["currently"]["temperature"]
for hour in forecast["hourly"]["data"]:
    ...
```

…change it to:

```python
forecasts = requests.post(apify_url, json={"coordinates": ["37.7749,-122.4194"]}).json()
forecast = forecasts[0]
temp = forecast["currently"]["temperature"]
for hour in forecast["hourly"]["data"]:
    ...
```

That's the entire migration in most codebases. Extract-one-line-swap-one-line.

***

### Python Example with ApifyClient

For production use — especially bulk lookups across many cities — use the official Apify client:

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_APIFY_TOKEN")

run = client.actor("nexgendata/dark-sky-replacement").call(run_input={
    "coordinates": [
        "37.7749,-122.4194",   ## San Francisco
        "40.7128,-74.0060",    ## New York
        "51.5074,-0.1278",     ## London
        "35.6762,139.6503",    ## Tokyo
    ],
    "units": "us",
    "include_hourly": True,
    "include_daily": True,
    "include_alerts": False,
    "days": 7,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["timezone"], "->", item["currently"]["temperature"], "°F")
    print("  tomorrow high:", item["daily"]["data"][1]["temperatureHigh"])
```

One forecast event fires per coordinate, so the run above costs `4 × $0.002 = $0.008`.

***

### 5 Real Use Cases

#### 1. Resurrecting a Legacy Dark Sky Python / Node Service

You have a production cron job written in 2019 that pulls the Dark Sky forecast, posts tomorrow's high to Slack at 8am, and has been broken for over two years. Swap the base URL to this actor, leave every other line alone, and it works again. Takes fifteen minutes, not a sprint.

#### 2. Home Assistant / Smart-Home Automations

Dozens of community Home Assistant blueprints and Node-RED flows hard-coded the Dark Sky JSON shape — irrigation controllers, EV charging schedules, window-blind automations. This actor gives them a backend again without rewriting every blueprint to match OpenWeatherMap's wildly-different shape.

#### 3. Indie Weather App with Paying Users

You ship a small iOS/Android/web weather app, you built it against Dark Sky five years ago, and you absolutely do not want to re-architect around Apple's WeatherKit (which is iOS-only, Apple-ID-gated, and legally sketchy to proxy to non-Apple platforms). Point your backend at this actor instead.

#### 4. Agritech / Irrigation Scheduling

Farmers running Dark Sky-based evapotranspiration models for irrigation timing were hit hard when it went dark. Open-Meteo delivers the same `temperature_2m` + `dew_point_2m` + `wind_speed_10m` + `precipitation` set that ET formulas need, in the Dark Sky field names the existing calculation modules expect.

#### 5. Academic / Climate-Research Pipelines

Research codebases that processed thousands of lat/lng points against Dark Sky's hourly API for historical retrospectives. Open-Meteo exposes both forecast and (separately) reanalysis endpoints; this actor fronts the forecast side today, and you can plug the same reshape logic into a historical variant when needed.

***

### Dark Sky vs This Actor vs The Paid Alternatives

| Capability | Dark Sky (2016–2023) | **This actor (Open-Meteo)** | OpenWeatherMap One Call | Tomorrow.io | Apple WeatherKit |
|---|---|---|---|---|---|
| Status in 2026 | **Dead since March 2023** | Active | Active | Active | Active |
| JSON shape | Dark Sky proprietary | **Dark Sky-compatible** | OWM proprietary | Tomorrow.io proprietary | Apple proprietary |
| Auth required | API key | **No auth (via Apify token)** | API key | API key | Apple ID + JWT + team key |
| Free tier | 1,000 calls/day | **Pay-per-event, no cap** | 1,000 calls/day | 500 calls/day | 500k calls/month (rate-limited) |
| Price per 1,000 forecasts | ~$0 (free tier) then $0.0001 | **~$2 via PPE** | ~$18 on paid tier | ~$10 on paid tier | Free within Apple quota, else $0.50–$2.50 |
| Works from non-Apple platforms | Yes | **Yes** | Yes | Yes | **No — Apple ecosystem only** |
| Severe weather alerts | Yes | Stub (empty array + note) | Yes | Yes | Yes |
| Global coverage | Yes | **Yes** | Yes | Yes | Yes |
| Academic / open methodology | No | **Yes (Open-Meteo is open-source)** | No | No | No |
| Rate limit headaches | Yes | **None — Apify handles retries** | Yes | Yes | Yes |

For severe-weather alerting you still want NWS / Meteoalarm / BOM directly. For everything else — current conditions, hourly, daily forecast — this is the simplest and cheapest way to get back to a working Dark Sky-shaped response today.

***

### Why Run This on NexGenData / Apify?

- **Zero infra.** No HTTP client retry loop, no WMO-code mapping table, no epoch conversion, no unit scaling. Paste coordinates, click Run.
- **Batch-friendly.** Up to thousands of `lat,lng` strings per run — one PPE event per coordinate.
- **Pay-per-event pricing.** No monthly seat. A 7-day forecast for one city is $0.002. A 500-city workload is $1.00.
- **Clean data contract.** Stable Dark Sky-shaped JSON, graceful nulls for missing fields, ISO-8601 → epoch conversion done for you.
- **Integrations.** Pipe output to Google Sheets, Slack, Zapier, Make, n8n, or your own webhook via standard Apify integrations.
- **Survives backend changes.** If Open-Meteo changes its shape or we add a secondary provider, the actor's output contract stays Dark Sky-shaped.

***

### Related Actors in the NexGenData Suite

- **[heroku-cost-calculator](https://apify.com/nexgendata?fpr=2ayu9b)** — Estimate your Heroku bill and compare migration costs to Railway, Render, Fly.io, Cloudflare Workers, and DigitalOcean.
- **[tranco-rank-lookup](https://apify.com/nexgendata?fpr=2ayu9b)** — Free Alexa Rank alternative using academic Tranco data.
- **[company-data-aggregator](https://apify.com/nexgendata?fpr=2ayu9b)** — Bulk company profile from WHOIS, DNS, GitHub, SSL, tech stack. Great for enriching location-based customer data.
- **[iex-replacement](https://apify.com/nexgendata?fpr=2ayu9b)** — Same "killed API, rebuilt cheap" playbook for IEX Cloud's discontinued financial endpoints.

***

### FAQ

**Q: Is the output really identical to Dark Sky's response?**
Field names and shape: yes, intentionally. The top-level keys (`latitude`, `longitude`, `timezone`, `offset`, `currently`, `hourly.data[]`, `daily.data[]`, `flags`) and their inner keys match Dark Sky's schema. A few fields Dark Sky exposed (e.g. `ozone`, `nearestStormDistance`, `moonPhase`) are simply omitted because Open-Meteo doesn't publish them — if your code `.get()`s those with defaults, you won't notice. Numeric values are returned in the same unit system Dark Sky used for the requested preset.

**Q: Why didn't Apple just keep Dark Sky running?**
Apple bought Dark Sky in 2020, integrated the tech into iOS weather and then into WeatherKit, and killed the public API because (a) running a free public weather endpoint has a real infrastructure cost, and (b) WeatherKit monetizes the same tech via Apple Developer Program seats. Commercially rational, developer-hostile — which is why the public had to build its own replacement.

**Q: Is Open-Meteo going to disappear too?**
Open-Meteo is open-source (see their GitHub) and the server software itself can be self-hosted against freely-available weather model outputs from DWD, NOAA, ECMWF, etc. Even if the hosted endpoint went away tomorrow, anyone could spin up a compatible instance. That's a meaningfully different risk profile from "Apple's SDK team decides to deprecate it."

**Q: What about severe-weather alerts?**
Open-Meteo doesn't publish a unified alerts feed. When you enable `include_alerts`, this actor returns an empty `alerts: []` array plus a `flags.alerts_note` explainer — enough to keep existing Dark Sky clients that iterate the array from crashing, without pretending to deliver data we don't have. For production alerting, subscribe directly to the National Weather Service (CAP feed), Meteoalarm (Europe), BOM (Australia), or Environment Canada's feeds.

**Q: Does this work for historical weather (dates in the past)?**
Not at the moment. Open-Meteo has a separate `/archive` endpoint backed by the ERA5 reanalysis dataset. If there's demand we'll publish a `dark-sky-historical-replacement` sibling actor wired to that endpoint with the same reshape logic.

**Q: Is the data accurate enough for production?**
Yes, with a caveat. Open-Meteo serves the **same operational model outputs** the national weather services serve — it's not a second-class panel estimate. Forecast accuracy is comparable to Dark Sky in its prime. Current-conditions "temperature" is model-interpolated rather than read from the nearest physical station (Dark Sky did the same thing), so in extreme microclimates you may see 1–2°F drift versus a specific airport METAR. For irrigation, routing, commute notifications, home-automation triggers, and general consumer weather apps, it's excellent.

**Q: Can I use this commercially?**
Open-Meteo is free for non-commercial use and offers paid tiers for commercial deployments. Small-to-mid commercial workloads generally fit under the hosted free ceiling, but if you're making thousands of calls per minute you should review Open-Meteo's terms and consider their commercial plan or self-hosting. The Apify-side billing (`$0.002/forecast`) is independent of Open-Meteo's terms.

**Q: What's the rate limit?**
There's no hard rate limit inside this actor — Open-Meteo's public endpoint is generous, and Apify handles the concurrency. For runs of 10,000+ coordinates, split into multiple actor runs rather than one giant batch to keep run-duration manageable.

***

#### Built by NexGenData — more "killed API, reborn cheaper" actors at [apify.com/nexgendata](https://apify.com/nexgendata?fpr=2ayu9b)

# Actor input Schema

## `coordinates` (type: `array`):

List of 'lat,lng' strings to fetch a forecast for. Example: \["37.7749,-122.4194", "40.7128,-74.0060"]. Each entry triggers one forecast call and one PPE charge.

## `units` (type: `string`):

Dark Sky-compatible unit system. 'us' (Fahrenheit, mph, inches — Dark Sky default), 'si' (Celsius, m/s, mm), 'ca' (Celsius, km/h, mm), 'uk2' (Celsius, mph, mm).

## `include_hourly` (type: `boolean`):

Include an hourly forecast block (matches Dark Sky's `hourly.data[]`). Disable for lighter payloads.

## `include_daily` (type: `boolean`):

Include a daily forecast block (matches Dark Sky's `daily.data[]`).

## `include_alerts` (type: `boolean`):

Include an `alerts` array in the response. Open-Meteo does not provide unified alert feeds; this returns an empty array plus a `flags.alerts_note` explainer. Enable only if your client expects the key to exist.

## `days` (type: `integer`):

Number of days of forecast data (1-16). Dark Sky returned 7 days; Open-Meteo supports up to 16.

## Actor input object example

```json
{
  "coordinates": [
    "37.7749,-122.4194"
  ],
  "units": "us",
  "include_hourly": true,
  "include_daily": true,
  "include_alerts": false,
  "days": 7
}
```

# 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 = {
    "coordinates": [
        "37.7749,-122.4194"
    ],
    "units": "us",
    "include_hourly": true,
    "include_daily": true,
    "include_alerts": false,
    "days": 7
};

// Run the Actor and wait for it to finish
const run = await client.actor("nexgendata/dark-sky-replacement").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 = {
    "coordinates": ["37.7749,-122.4194"],
    "units": "us",
    "include_hourly": True,
    "include_daily": True,
    "include_alerts": False,
    "days": 7,
}

# Run the Actor and wait for it to finish
run = client.actor("nexgendata/dark-sky-replacement").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 '{
  "coordinates": [
    "37.7749,-122.4194"
  ],
  "units": "us",
  "include_hourly": true,
  "include_daily": true,
  "include_alerts": false,
  "days": 7
}' |
apify call nexgendata/dark-sky-replacement --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=nexgendata/dark-sky-replacement",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Dark Sky Replacement",
        "description": "Drop-in replacement for the killed Dark Sky API. Wraps Open-Meteo's free weather data and reshapes it to match Dark Sky's exact JSON schema. Zero auth, zero cost for the data itself.",
        "version": "0.0",
        "x-build-id": "yifvekj1L8FIeqYBa"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/nexgendata~dark-sky-replacement/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-nexgendata-dark-sky-replacement",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/nexgendata~dark-sky-replacement/runs": {
            "post": {
                "operationId": "runs-sync-nexgendata-dark-sky-replacement",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/nexgendata~dark-sky-replacement/run-sync": {
            "post": {
                "operationId": "run-sync-nexgendata-dark-sky-replacement",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "coordinates"
                ],
                "properties": {
                    "coordinates": {
                        "title": "Coordinates",
                        "type": "array",
                        "description": "List of 'lat,lng' strings to fetch a forecast for. Example: [\"37.7749,-122.4194\", \"40.7128,-74.0060\"]. Each entry triggers one forecast call and one PPE charge.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "units": {
                        "title": "Unit System",
                        "enum": [
                            "us",
                            "si",
                            "ca",
                            "uk2"
                        ],
                        "type": "string",
                        "description": "Dark Sky-compatible unit system. 'us' (Fahrenheit, mph, inches — Dark Sky default), 'si' (Celsius, m/s, mm), 'ca' (Celsius, km/h, mm), 'uk2' (Celsius, mph, mm).",
                        "default": "us"
                    },
                    "include_hourly": {
                        "title": "Include Hourly Forecast",
                        "type": "boolean",
                        "description": "Include an hourly forecast block (matches Dark Sky's `hourly.data[]`). Disable for lighter payloads.",
                        "default": true
                    },
                    "include_daily": {
                        "title": "Include Daily Forecast",
                        "type": "boolean",
                        "description": "Include a daily forecast block (matches Dark Sky's `daily.data[]`).",
                        "default": true
                    },
                    "include_alerts": {
                        "title": "Include Alerts Array",
                        "type": "boolean",
                        "description": "Include an `alerts` array in the response. Open-Meteo does not provide unified alert feeds; this returns an empty array plus a `flags.alerts_note` explainer. Enable only if your client expects the key to exist.",
                        "default": false
                    },
                    "days": {
                        "title": "Forecast Days",
                        "minimum": 1,
                        "maximum": 16,
                        "type": "integer",
                        "description": "Number of days of forecast data (1-16). Dark Sky returned 7 days; Open-Meteo supports up to 16.",
                        "default": 7
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
