Weather & Environmental Data by Location
Pricing
Pay per usage
Weather & Environmental Data by Location
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.
Pricing
Pay per usage
Rating
0.0
(0)
Developer
luochengfengqi
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
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
- Input Formats
- Input Parameters
- Output Schema
- Record Types
- Key-Value Store Summary
- Error and Empty-Result Handling
- Usage Examples
- Pricing
- Limitations and Notes
- 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
{"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).
{"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:
{"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: 0and noEARTHQUAKErecords are written.
Filter diagnostic records out downstream with status != "OK". Diagnostic records are not charged.
Usage Examples
Apify Console
- Open the Actor page and click Start.
- Leave the default locations (Shanghai, Berlin, San Francisco) or replace them with your own place names or coordinates.
- Set
forecastDaysandpastDaysto shape the daily window, and adjust the earthquake radius and magnitude floor if needed. - Read records in the Output tab, separating them by
recordType, and check the Key-Value Store recordSUMMARYfor per-source health.
cURL
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
from apify_client import ApifyClientclient = 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
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
maxEarthquakeEventsevents in the window. In very active regions and windows, raise the cap if exact daily counts matter;maxEarthquakeMagnitudeis 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
Localcarry no UTC offset, by design: they are wall-clock times in the record'stimezone, which is stored on the same record.eventTimeUtcandscrapedAtare 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.