# Weather & Environmental Data by Location (`luochengfengqi/weather-environment-by-location`) Actor

Returns current conditions, daily weather, air quality and nearby earthquakes for place names or coordinates, joining Open-Meteo forecast and air-quality data with the USGS earthquake catalog on one location and date axis.

- **URL**: https://apify.com/luochengfengqi/weather-environment-by-location.md
- **Developed by:** [luochengfengqi](https://apify.com/luochengfengqi) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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 & Environmental Data by Location

Returns current conditions, daily weather, air quality and nearby earthquakes for a list of place names or coordinates, joined on a single location and date axis. Weather and air quality come from the Open-Meteo forecast and air-quality APIs; earthquake data comes from the USGS earthquake catalog. A monitoring job that needs "weather, air and seismic activity for these 40 sites, every morning, in one table" would otherwise maintain a geocoder, two Open-Meteo clients, a USGS client, an hourly-to-daily air-quality aggregation and a timezone-aware earthquake join. This Actor performs those steps against the native HTTP JSON APIs, without a headless browser.

Each location produces three kinds of records in one dataset: one `CURRENT_CONDITIONS` record, one `DAILY_WEATHER` record per day in the requested window (carrying the day's air-quality aggregates and earthquake counts), and one `EARTHQUAKE` record per returned USGS event with its distance from the location. A per-location `SUMMARY` record in the default Key-Value Store reports how every source behaved for every location.

### Table of Contents

- [Extraction Pipeline](#extraction-pipeline)
- [Input Formats](#input-formats)
- [Input Parameters](#input-parameters)
- [Output Schema](#output-schema)
- [Record Types](#record-types)
- [Key-Value Store Summary](#key-value-store-summary)
- [Error and Empty-Result Handling](#error-and-empty-result-handling)
- [Usage Examples](#usage-examples)
- [Pricing](#pricing)
- [Limitations and Notes](#limitations-and-notes)
- [Sources, Licenses and Commercial Use](#sources-licenses-and-commercial-use)

### Extraction Pipeline

| Step | Source or operation | Detail |
|---|---|---|
| 1 | Open-Meteo Geocoding API (`geocoding-api.open-meteo.com/v1/search`) | Resolves a place name to the top result's coordinates, country, region, timezone and population. Skipped for coordinate inputs. |
| 2 | Open-Meteo Forecast API (`api.open-meteo.com/v1/forecast`) | Current conditions plus daily aggregates for the past-days and forecast-days window, in the location's own timezone. |
| 3 | Open-Meteo Air Quality API (`air-quality-api.open-meteo.com/v1/air-quality`) | Hourly PM2.5, PM10, US AQI, European AQI, ozone and nitrogen dioxide, aggregated locally into daily mean and maximum values. |
| 4 | USGS Earthquake Catalog (`earthquake.usgs.gov/fdsnws/event/1/query`) | Events within the configured radius and magnitude floor over the same date window, strongest first. |
| 5 | Local join | Earthquake times are converted into the location's timezone; each daily record gains the count and strongest magnitude of returned events on that date, and each event gains its haversine distance from the location. |
| 6 | Output | Dataset records plus a `SUMMARY` record in the default Key-Value Store. |

When a run has an Open-Meteo key available, from the caller's input or from the operator's Actor configuration, all three Open-Meteo steps use the commercial `customer-` endpoints with that key. See the licensing section for the key priority rules.

Weather codes are WMO codes. The Actor maps them to text in `weatherCondition` and `currentWeatherCondition` (for example `3` becomes `Overcast`, `61` becomes `Slight rain`, `95` becomes `Thunderstorm`) while keeping the numeric code in `weatherCode`.

### Input Formats

| Format | Example | Resolution |
|---|---|---|
| Place name | `Shanghai` | Top geocoding result |
| Place with region or country | `Berlin, Germany`, `San Francisco` | Top geocoding result; adding a region or country disambiguates same-name places |
| Decimal coordinates | `31.23,121.47` | Used directly, no geocoding; name, country and region fields are null |
| Labeled coordinates | `lat:31.23,lon:121.47` | Used directly, same as above |

Place-name resolution always takes the first geocoding result. The resolved name, country and coordinates are stored on every record, so an ambiguous name is visible in the output and can be replaced with coordinates.

#### Example Input JSON

```json
{
  "locations": ["Shanghai", "San Francisco", "35.68,139.69"],
  "forecastDays": 7,
  "pastDays": 2,
  "includeAirQuality": true,
  "includeEarthquakes": true,
  "earthquakeRadiusKm": 300,
  "minEarthquakeMagnitude": 2.5,
  "maxEarthquakeEvents": 20
}
```

### Input Parameters

| Parameter | Type | Default | Required | Description |
|---|---|---|---|---|
| `locations` | array of string | `["Shanghai", "Berlin", "San Francisco"]` | No | Place names or coordinates, one entry per location. See Input Formats. |
| `forecastDays` | integer | `7` | No | Forecast days per location including today, 1 to 16. |
| `pastDays` | integer | `2` | No | Past days before today to include, 0 to 30, from the same model run. |
| `includeAirQuality` | boolean | `true` | No | Aggregate hourly air-quality data into daily mean and maximum fields. |
| `includeEarthquakes` | boolean | `true` | No | Search the USGS catalog around each location and emit earthquake records. |
| `earthquakeRadiusKm` | integer | `300` | No | USGS search radius in kilometers, 10 to 2000. |
| `minEarthquakeMagnitude` | number | `2.5` | No | Minimum magnitude for returned USGS events, 0 to 10. |
| `maxEarthquakeEvents` | integer | `20` | No | Maximum USGS events per location, 0 to 200, strongest first. Daily counts are computed over the returned events. |
| `openMeteoApiKey` | string (secret) | empty | No | Open-Meteo subscription key. When supplied, your key is used on the commercial customer endpoints. When empty, the operator's configured key is used instead. |

### Output Schema

The sample below is a real daily record from a verification run for San Francisco (dates are the location's local dates at run time).

```json
{
  "status": "OK",
  "recordType": "DAILY_WEATHER",
  "locationInput": "San Francisco",
  "locationName": "San Francisco",
  "country": "United States",
  "admin1": "California",
  "population": 827526,
  "geocodingMatch": "TOP_RESULT",
  "latitude": 37.77493,
  "longitude": -122.41942,
  "elevationMeters": 18,
  "timezone": "America/Los_Angeles",
  "recordDate": "2026-10-20",
  "dayOffset": -2,
  "weatherCode": 3,
  "weatherCondition": "Overcast",
  "temperatureMaxC": 20.4,
  "temperatureMinC": 10.2,
  "temperatureMeanC": 15,
  "apparentTemperatureMaxC": 18.8,
  "precipitationSumMm": 0,
  "rainSumMm": 0,
  "snowfallSumCm": 0,
  "precipitationHours": 0,
  "precipitationProbabilityMaxPct": 4,
  "windSpeedMaxKmh": 10.7,
  "windGustsMaxKmh": 14,
  "windDirectionDominantDeg": 311,
  "sunriseLocal": "2026-10-20T07:23",
  "sunsetLocal": "2026-10-20T18:25",
  "daylightDurationSeconds": 39736,
  "uvIndexMax": 4.2,
  "pm25MeanUgM3": 11.1,
  "pm25MaxUgM3": 16.3,
  "pm10MeanUgM3": 14.5,
  "pm10MaxUgM3": 19,
  "usAqiMax": 53,
  "europeanAqiMax": 50,
  "ozoneMaxUgM3": 84,
  "nitrogenDioxideMaxUgM3": 43,
  "earthquakeCount": 1,
  "maxEarthquakeMagnitude": 2.51,
  "sourceApis": ["OPEN_METEO_FORECAST", "OPEN_METEO_AIR_QUALITY", "USGS"],
  "message": null,
  "scrapedAt": "2026-10-23T05:23:56.736Z"
}
```

#### Field Reference

Fields that belong to a different record type are null. Location fields repeat on every record so each row is self-contained.

| Field | Type | Nullable | Description |
|---|---|---|---|
| `status` | string | No | `OK` for data records, `NOT_FOUND_OR_ERROR` for diagnostic records. |
| `recordType` | string | No | `CURRENT_CONDITIONS`, `DAILY_WEATHER`, `EARTHQUAKE` or `DIAGNOSTIC`. |
| `locationInput` | string | No | Location exactly as supplied in the input. |
| `locationName` | string | Yes | Resolved place name. Null for coordinate inputs. |
| `country` | string | Yes | Resolved country. Null for coordinate inputs. |
| `admin1` | string | Yes | Resolved first-level region, for example a state or province. |
| `population` | integer | Yes | Place population from the geocoding result. |
| `geocodingMatch` | string | Yes | `TOP_RESULT` for place names, `COORDINATES` for coordinate inputs. |
| `latitude`, `longitude` | number | Yes | Resolved location coordinates used for all requests. |
| `elevationMeters` | number | Yes | Elevation in meters from the forecast grid or geocoding result. |
| `timezone` | string | Yes | IANA timezone of the location, for example `Asia/Shanghai`. All dates and local times use it. |
| `recordDate` | string | Yes | Date of the record in the location timezone, `YYYY-MM-DD`. |
| `dayOffset` | integer | Yes | Days relative to the location's today: negative for past days, `0` for today. Daily records only. |
| `observationTimeLocal` | string | Yes | Timestamp of the current-conditions record in local time. Current records only. |
| `currentTemperatureC` | number | Yes | Current temperature in degrees Celsius. |
| `currentApparentTemperatureC` | number | Yes | Current apparent (feels-like) temperature in degrees Celsius. |
| `currentHumidityPct` | integer | Yes | Current relative humidity in percent. |
| `currentPrecipitationMm` | number | Yes | Precipitation in the last observation interval, millimeters. |
| `currentWeatherCode`, `currentWeatherCondition` | integer, string | Yes | Current WMO weather code and its text mapping. |
| `currentWindSpeedKmh`, `currentWindGustsKmh` | number | Yes | Current wind speed and gusts in km/h. |
| `currentPressureHpa` | number | Yes | Current surface pressure in hPa. |
| `isDay` | boolean | Yes | Whether the observation time is daytime at the location. |
| `weatherCode`, `weatherCondition` | integer, string | Yes | Daily WMO weather code and its text mapping. |
| `temperatureMaxC`, `temperatureMinC`, `temperatureMeanC` | number | Yes | Daily maximum, minimum and mean temperature in degrees Celsius. |
| `apparentTemperatureMaxC` | number | Yes | Daily maximum apparent temperature in degrees Celsius. |
| `precipitationSumMm` | number | Yes | Daily precipitation sum in millimeters. |
| `rainSumMm`, `snowfallSumCm` | number | Yes | Daily rain sum in millimeters and snowfall sum in centimeters. |
| `precipitationHours` | number | Yes | Hours with precipitation during the day. |
| `precipitationProbabilityMaxPct` | integer | Yes | Maximum hourly precipitation probability of the day, percent. |
| `windSpeedMaxKmh`, `windGustsMaxKmh` | number | Yes | Daily maximum wind speed and gusts in km/h. |
| `windDirectionDominantDeg` | integer | Yes | Dominant wind direction in degrees. |
| `sunriseLocal`, `sunsetLocal` | string | Yes | Sunrise and sunset in local time, ISO 8601 without offset. |
| `daylightDurationSeconds` | integer | Yes | Daylight duration in seconds. |
| `uvIndexMax` | number | Yes | Daily maximum UV index. |
| `pm25MeanUgM3`, `pm25MaxUgM3` | number | Yes | Daily mean and maximum PM2.5 concentration in ug/m3, aggregated from hourly values. |
| `pm10MeanUgM3`, `pm10MaxUgM3` | number | Yes | Daily mean and maximum PM10 concentration in ug/m3. |
| `usAqiMax`, `europeanAqiMax` | number | Yes | Daily maximum US and European air quality index values. AQI has no mean field because index values are not concentrations. |
| `ozoneMaxUgM3`, `nitrogenDioxideMaxUgM3` | number | Yes | Daily maximum ozone and nitrogen dioxide concentrations in ug/m3. |
| `earthquakeCount` | integer | Yes | Number of returned USGS events on this date within the radius and magnitude settings. See the limitations on capped counts. |
| `maxEarthquakeMagnitude` | number | Yes | Strongest magnitude among the returned events on this date. |
| `eventId` | string | Yes | USGS event identifier. Earthquake records only. |
| `eventTimeUtc` | string | Yes | Earthquake origin time in UTC ISO 8601 format. |
| `magnitude`, `magnitudeType` | number, string | Yes | Event magnitude and its type (`ml`, `mw`, and similar USGS codes). |
| `depthKm` | number | Yes | Hypocenter depth in kilometers. |
| `placeDescription` | string | Yes | USGS place description, for example `23 km WSW of Gustine, CA`. |
| `eventLatitude`, `eventLongitude` | number | Yes | Event epicenter coordinates. |
| `distanceFromLocationKm` | number | Yes | Haversine distance between the location and the epicenter in kilometers. |
| `searchRadiusKm` | integer | Yes | Radius used for the USGS search that returned this event. |
| `tsunamiPossible` | boolean | Yes | USGS tsunami flag for the event. |
| `alertLevel` | string | Yes | USGS PAGER alert level: `green`, `yellow`, `orange` or `red`, when issued. |
| `significance` | integer | Yes | USGS event significance score, 0 to 1000. |
| `feltReports` | integer | Yes | Number of felt reports submitted to USGS. |
| `eventUrl` | string | Yes | USGS event page URL. |
| `sourceApis` | array of string | No | APIs that contributed to the record: `OPEN_METEO_FORECAST`, `OPEN_METEO_AIR_QUALITY`, `USGS`. |
| `message` | string | Yes | Diagnostic message. Only set on diagnostic records, or null on data records. |
| `scrapedAt` | string | No | Record creation timestamp in UTC ISO 8601 format. |

### Record Types

| Type | When produced | Key fields |
|---|---|---|
| `CURRENT_CONDITIONS` | Once per resolved location | `observationTimeLocal`, all `current...` fields, `isDay` |
| `DAILY_WEATHER` | Once per location per day in the window | `recordDate`, `dayOffset`, daily weather fields, air-quality aggregates, `earthquakeCount` |
| `EARTHQUAKE` | Once per returned USGS event | `eventId`, `eventTimeUtc`, `magnitude`, `distanceFromLocationKm` |
| `DIAGNOSTIC` | When a location cannot be resolved or its forecast fails | `status` is `NOT_FOUND_OR_ERROR`, `message` explains the failure |

Filter with `recordType` to consume one kind at a time.

### Key-Value Store Summary

Every run stores one `SUMMARY` record in the default Key-Value Store:

| Field | Description |
|---|---|
| `startedAt`, `finishedAt` | Run window in UTC ISO 8601 format. |
| `locationsRequested`, `locationsResolved`, `locationsFailed` | Location accounting for the run. |
| `recordsStored` | Records written to the dataset, including diagnostics. |
| `recordsByType` | Record counts per `recordType`. |
| `chargeLimitReached` | True when the run stopped early because the charged-results limit was hit. |
| `commercialEndpointUsed` | True when a user-supplied or operator-configured Open-Meteo key was used and the customer endpoints served the run. The key itself is never stored. |
| `openMeteoKeySource` | Which key served the run: `USER_INPUT` (the caller's key), `OPERATOR` (the operator's configured key) or `NONE`. |
| `locations` | Per-location detail: resolved name and coordinates, timezone, per-source status (`OK`, `ERROR`, `DISABLED`, `NOT_FOUND_OR_ERROR`), record counts and the first error message. |
| `filtersApplied` | Effective window, radius, magnitude and event-cap settings. |

### Error and Empty-Result Handling

Locations fail independently, and sources fail independently within a location:

- A place name with no geocoding result, or a location whose forecast request fails, produces one diagnostic record and the batch continues:

```json
{
  "status": "NOT_FOUND_OR_ERROR",
  "recordType": "DIAGNOSTIC",
  "locationInput": "Atlantis City",
  "locationName": null,
  "country": null,
  "admin1": null,
  "latitude": null,
  "longitude": null,
  "message": "Place not found in the Open-Meteo Geocoding API: Atlantis City",
  "scrapedAt": "2026-10-23T05:23:56.736Z"
}
```

- When air quality or the USGS catalog fails for a location, daily records are still written with the affected fields null, and the location's summary entry records which source failed and why.
- Zero earthquakes is a normal result, not an error: daily records report `earthquakeCount: 0` and no `EARTHQUAKE` records are written.

Filter diagnostic records out downstream with `status != "OK"`. Diagnostic records are not charged.

### Usage Examples

#### Apify Console

1. Open the Actor page and click **Start**.
2. Leave the default locations (Shanghai, Berlin, San Francisco) or replace them with your own place names or coordinates.
3. Set `forecastDays` and `pastDays` to shape the daily window, and adjust the earthquake radius and magnitude floor if needed.
4. Read records in the **Output** tab, separating them by `recordType`, and check the Key-Value Store record `SUMMARY` for per-source health.

#### cURL

```bash
curl -X POST "https://api.apify.com/v2/acts/luochengfengqi~weather-environment-by-location/run-sync-get-dataset-items?token=YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "locations": ["Tokyo", "37.77,-122.42"],
    "forecastDays": 5,
    "pastDays": 0,
    "includeAirQuality": true,
    "includeEarthquakes": false
  }'
```

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("YOUR_API_TOKEN")

run = client.actor("luochengfengqi/weather-environment-by-location").call(run_input={
    "locations": ["Shanghai", "San Francisco"],
    "forecastDays": 7,
    "pastDays": 2,
    "earthquakeRadiusKm": 300,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    if item["recordType"] == "DAILY_WEATHER":
        print(item["locationName"], item["recordDate"], item["temperatureMaxC"], item["usAqiMax"], item["earthquakeCount"])
    if item["recordType"] == "EARTHQUAKE":
        print("quake", item["magnitude"], item["placeDescription"], item["distanceFromLocationKm"])

summary = client.key_value_store(run["defaultKeyValueStoreId"]).get_record("SUMMARY")
print(summary["value"]["recordsByType"])
```

#### Node.js

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

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

const run = await client.actor('luochengfengqi/weather-environment-by-location').call({
    locations: ['Berlin, Germany', '52.52,13.41'],
    forecastDays: 10,
    includeEarthquakes: false,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
const rainyDays = items.filter((item) => item.recordType === 'DAILY_WEATHER' && (item.precipitationSumMm ?? 0) > 5);
console.log(rainyDays.map((item) => [item.locationInput, item.recordDate, item.precipitationSumMm]));
```

### Pricing

This Actor uses pay-per-event pricing. Every dataset record is charged as one `weather-record` event at $0.002 per record: the current-conditions record, each daily record, and each earthquake record. Diagnostic records are free. The default input (3 locations, 9 days each, up to 20 earthquakes each) produces roughly 30 to 90 records, so a default run costs about $0.06 to $0.18 in event charges, plus standard Apify platform usage for compute.

### Limitations and Notes

- Past days come from the same forecast model run as the forecast, not from a historical observation archive. They are suitable for short lookbacks and continuity with the forecast; use an archive product for climatology or audited historical records.
- Air-quality values are CAMS model estimates from Open-Meteo, not station measurements. Daily aggregates are computed from the hourly model values of the location's local dates; AQI fields report daily maxima only.
- Daily earthquake counts are computed over the events actually returned, which are the strongest `maxEarthquakeEvents` events in the window. In very active regions and windows, raise the cap if exact daily counts matter; `maxEarthquakeMagnitude` is reliable because results are ordered by magnitude.
- USGS magnitudes and place descriptions are revised by USGS after events occur. Re-running the same window later can return updated values.
- Place-name resolution takes the top geocoding result, which favors larger places with the same name. The resolved name and country are on every record; use coordinates when a specific same-name place is required.
- Forecast resolution follows the Open-Meteo model grid (roughly 9 to 25 km depending on region). Coastal and mountain locations can differ from point observations.
- Timestamps named `Local` carry no UTC offset, by design: they are wall-clock times in the record's `timezone`, which is stored on the same record. `eventTimeUtc` and `scrapedAt` are true UTC timestamps.

### Sources, Licenses and Commercial Use

Weather and geocoding data comes from Open-Meteo, which aggregates national weather services' model output; earthquake data comes from the USGS earthquake catalog, a United States government source. Records name their contributing APIs in `sourceApis`.

Open-Meteo offers a subscription with commercial customer endpoints alongside its free endpoints. This Actor resolves keys in a fixed priority: a key supplied by the caller in the `openMeteoApiKey` input is used first; when the input is empty, the operator's key, configured on the Actor as the `OPEN_METEO_API_KEY` environment variable, is used. In both cases the Actor calls the `customer-api.open-meteo.com`, `customer-geocoding-api.open-meteo.com` and `customer-air-quality-api.open-meteo.com` endpoints, so standard runs are covered by the operator's Open-Meteo subscription and callers only need their own key when they prefer their own quota and billing. The `openMeteoKeySource` field in the summary records which key served the run (`USER_INPUT` or `OPERATOR`) without ever storing the key itself; keys are used only as request parameters during the run and are never written to the dataset or the summary. The free endpoints remain only as a fallback for deployments where no key is configured at all. USGS data is a public-domain United States government work; USGS asks API users to be reasonable about request volume, which the per-location single-query design respects.

# Actor input Schema

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

One entry per location. Accepted formats: (1) a place name such as 'Shanghai', 'Berlin, Germany' or 'San Francisco' (the top geocoding result is used); (2) decimal coordinates such as '31.23,121.47'; (3) labeled coordinates such as 'lat:31.23,lon:121.47'.

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

Number of forecast days to return per location, including today (1 to 16). Combined with Past Days this sets the daily record window.

## `pastDays` (type: `integer`):

Number of past days to include before today (0 to 30), using the same forecast model run. Set to 0 for forecast-only output.

## `includeAirQuality` (type: `boolean`):

When enabled, hourly Open-Meteo air-quality data (PM2.5, PM10, US and European AQI, ozone, nitrogen dioxide) is aggregated into daily mean and maximum fields on each daily record.

## `includeEarthquakes` (type: `boolean`):

When enabled, the USGS earthquake catalog is searched around each location and returned as earthquake records; each daily record also gains the count and strongest magnitude of returned events on that date.

## `earthquakeRadiusKm` (type: `integer`):

Radius around each location for the USGS earthquake search, in kilometers (10 to 2000). Larger radii return more events in seismically active regions.

## `minEarthquakeMagnitude` (type: `number`):

Minimum magnitude for returned USGS events (0 to 10). The default 2.5 keeps locally noticeable events and filters micro-earthquakes.

## `maxEarthquakeEvents` (type: `integer`):

Maximum USGS events returned per location (0 to 200), strongest first. Daily earthquake counts are computed over the returned events, so a low cap can undercount very active dates.

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

Optional Open-Meteo subscription key. When supplied, your key is used on the commercial customer endpoints for geocoding, forecast and air quality. When left empty, the operator's configured Open-Meteo key is used instead, so runs are covered commercially by default.

## Actor input object example

```json
{
  "locations": [
    "Shanghai",
    "Berlin",
    "San Francisco"
  ],
  "forecastDays": 7,
  "pastDays": 2,
  "includeAirQuality": true,
  "includeEarthquakes": true,
  "earthquakeRadiusKm": 300,
  "minEarthquakeMagnitude": 2.5,
  "maxEarthquakeEvents": 20
}
```

# Actor output Schema

## `records` (type: `string`):

No description

## `summary` (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": [
        "Shanghai",
        "Berlin",
        "San Francisco"
    ],
    "forecastDays": 7,
    "pastDays": 2,
    "includeAirQuality": true,
    "includeEarthquakes": true,
    "earthquakeRadiusKm": 300,
    "minEarthquakeMagnitude": 2.5,
    "maxEarthquakeEvents": 20
};

// Run the Actor and wait for it to finish
const run = await client.actor("luochengfengqi/weather-environment-by-location").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": [
        "Shanghai",
        "Berlin",
        "San Francisco",
    ],
    "forecastDays": 7,
    "pastDays": 2,
    "includeAirQuality": True,
    "includeEarthquakes": True,
    "earthquakeRadiusKm": 300,
    "minEarthquakeMagnitude": 2.5,
    "maxEarthquakeEvents": 20,
}

# Run the Actor and wait for it to finish
run = client.actor("luochengfengqi/weather-environment-by-location").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": [
    "Shanghai",
    "Berlin",
    "San Francisco"
  ],
  "forecastDays": 7,
  "pastDays": 2,
  "includeAirQuality": true,
  "includeEarthquakes": true,
  "earthquakeRadiusKm": 300,
  "minEarthquakeMagnitude": 2.5,
  "maxEarthquakeEvents": 20
}' |
apify call luochengfengqi/weather-environment-by-location --silent --output-dataset

```

## MCP server setup

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

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/UzAGULXQTJ1IfAnVi/builds/VLzod9NldZ0Z5Tbu5/openapi.json
