Weather, air and hazards — each answer stamped with how fresh it is
The Weather Intelligence API returns weather and environmental data as clean JSON.
13 active endpoints, on 1, 2 and 3 credit tiers.
- POST/weather-intel/v1/environment_current
- POST/weather-intel/v1/forecast
- POST/weather-intel/v1/air_quality
- POST/weather-intel/v1/alerts
- POST/weather-intel/v1/hazards_nearby
- POST/weather-intel/v1/disasters
- POST/weather-intel/v1/earthquakes
- +6 more
What Weather & Hazards endpoints does ReefAPI ship?
13 live read endpoints. Read-only data API: no writes, no account actions, no dashboard access on the target site.
Weather & Hazards API
3 of 13 endpoints, ready to run
Current conditions plus hourly and daily forecast — temperature, feels-like, humidity, wind and gusts, pressure, cloud, dew point, UV and precipitation, with a condition symbol on every hour.
{ "ok": true, "meta": { "api": "weather-intel", "endpoint": "forecast", "mode": "live", "latency_ms": 15.8, "record_count": 27, "cache_hit": false }, "data": { "location": { "lat": 41.0082, "lon": 28.9784 }, "units": "metric", "current": { "time": "2026-08-29T13:00:00Z", "temperature": 25.4, "feels_like": 25.4, "humidity_pct": 57.2, "wind_speed": 7, "wind_gust": null, "wind_direction_deg": 19.5, "pressure_hpa": 1015.5, "cloud_cover_pct": 94.5, "fog_pct": 0, "dew_point": 16.3, "uv_index_clear_sky": 3.2, "precipitation": 0, "precipitation_window_hours": 1, "symbol": { "code": "cloudy", "condition": "cloudy", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": null } }, "hourly": [ { "time": "2026-08-29T13:00:00Z", "temperature": 25.4, "feels_like": 25.4, "humidity_pct": 57.2, "wind_speed": 7, "wind_gust": null, "wind_direction_deg": 19.5, "pressure_hpa": 1015.5, "cloud_cover_pct": 94.5, "fog_pct": 0, "dew_point": 16.3, "uv_index_clear_sky": 3.2, "precipitation": 0, "precipitation_window_hours": 1, "symbol": { "code": "cloudy", "condition": "cloudy", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": null } }, { "time": "2026-08-29T14:00:00Z", "temperature": 24.5, "feels_like": 24.5, "humidity_pct": 61.4, "wind_speed": 6.8, "wind_gust": null, "wind_direction_deg": 15.3, "pressure_hpa": 1015.6, "cloud_cover_pct": 32.8, "fog_pct": 0, "dew_point": 16.4, "uv_index_clear_sky": 1.6, "precipitation": 0, "precipitation_window_hours": 1, "symbol": { "code": "fair_day", "condition": "mostly_clear", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": "day" } }, { "time": "2026-08-29T15:00:00Z", "temperature": 24.1, "feels_like": 24.1, "humidity_pct": 62.8, "wind_speed": 6.2, "wind_gust": null, "wind_direction_deg": 17.9, "pressure_hpa": 1015.5, "cloud_cover_pct": 15.6, "fog_pct": 0, "dew_point": 16.4, "uv_index_clear_sky": 0.6, "precipitation": 0, "precipitation_window_hours": 1, "symbol": { "code": "fair_day", "condition": "mostly_clear", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": "day" } } ], "daily": [ { "date": "2026-08-29", "date_basis": "solar-approx UTC+2", "temperature_min": 21.2, "temperature_max": 25.4, "wind_speed_max": 7, "humidity_mean_pct": 70, "precipitation_total": 0, "symbol": { "code": "fair_day", "condition": "mostly_clear", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": "day" }, "sunrise": "2026-08-29T03:27:11Z", "sunset": "2026-08-29T16:42:20Z", "polar": null, "moon": { "phase": 0.548, "name": "full_moon", "illumination_pct": 97.8 }, "samples": 9 }, { "date": "2026-08-30", "date_basis": "solar-approx UTC+2", "temperature_min": 20.1, "temperature_max": 27, "wind_speed_max": 6, "humidity_mean_pct": 75.9, "precipitation_total": 0.5, "symbol": { "code": "clearsky_day", "condition": "clear", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": "day" }, "sunrise": "2026-08-30T03:28:10Z", "sunset": "2026-08-30T16:40:45Z", "polar": null, "moon": { "phase": 0.582, "name": "waning_gibbous", "illumination_pct": 93.6 }, "samples": 24 }, { "date": "2026-08-31", "date_basis": "solar-approx UTC+2", "temperature_min": 20.6, "temperature_max": 27.8, "wind_speed_max": 7, "humidity_mean_pct": 72.1, "precipitation_total": 0, "symbol": { "code": "clearsky_day", "condition": "clear", "intensity": "normal", "is_showers": false, "has_thunder": false, "day_night": "day" }, "sunrise": "2026-08-31T03:29:10Z", "sunset": "2026-08-31T16:39:08Z", "polar": null, "moon": { "phase": 0.616, "name": "waning_gibbous", "illumination_pct": 87.4 }, "samples": 24 } ], "source": { "source": "MET Norway Locationforecast 2.0", "source_url": "https://api.met.no", "license": "CC BY 4.0", "source_updated_at": "2026-08-29T13:16:30Z", "fetched_at": "2026-08-29T13:31:21Z", "staleness_minutes": 19, "stale": false, "confidence": "high" }, "astronomy_note": "Sunrise/sunset/moon-phase + apparent-temperature computed offline (NOAA solar equations; public-domain math)", "attribution": [ "Weather data by the Norwegian Meteorological Institute (MET Norway), CC BY 4.0 — https://api.met.no" ], "disclaimer": "Informational only — NOT for life-safety decisions. Always follow your national meteorological/civil-protection authority for warnings." } }
How the Weather & Hazards API works
Weather & Hazards is a normal ReefAPI surface — the same four rules that hold for every other engine on the key.
No OAuth app, no request signing, no per-site account. One key covers all 184 engines.
Every route is a POST with a JSON body. Parameters are validated against the published schema before anything is charged.
Credits, not seats. Failed and blocked calls are never charged, and cache hits cost nothing.
One envelope everywhere. meta carries latency_ms, record_count and the endpoint that answered.
Deciding whether to warn a customer about their delivery window
The question is never 'what is the weather'. It is whether conditions at a destination are bad enough to change a promise you have already made.
{"lat": 41.0082, "lon": 28.9784, "days": 3}Hourly rows carry precipitation, wind and gusts with a condition symbol, so a threshold can be evaluated per delivery hour rather than per day.
{"country": "germany", "severity_min": "orange"}Official warnings from the national service, filtered by severity, for the cases where the forecast is not the story.
Every response carries the source, its licence, when the source itself last updated and how many minutes stale that makes the reading — so a decision can be made on data whose age is known rather than assumed.
curl -X POST https://api.reefapi.com/weather-intel/v1/forecast \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"lat":41.0082,"lon":28.9784,"days":3}'{
"ok": true,
"data": { … },
"meta": {
"api": "weather-intel",
"endpoint": "forecast",
"mode": "live",
"latency_ms": …,
"record_count": …
},
"error": null
}What each action reads, and in which units and timezone
weather-intel is thirteen actions over nine different public datasets, and they do not share a unit system or a timestamp convention. The forecast actions speak UTC, the archive speaks local wall-clock, and the US path passes some NWS strings through untouched. Every response also carries a source block with source_updated_at, fetched_at, staleness_minutes, stale and confidence, so you can tell how old the underlying model run was.
| Action | Underlying record | Units and timestamps |
|---|---|---|
| forecast (default) | MET Norway Locationforecast 2.0, hourly for ~2.5 days then 6-hourly to ~day 9 | metric = C, m/s, mm; every time is UTC with a trailing Z |
| forecast source=us_nws | NWS gridpoint forecast; grid_id, grid_x, grid_y under us_official | temperature converted to C, but wind_speed stays a string like "10 mph" and times carry a local offset such as -04:00 |
| historical | Open-Meteo ERA5 archive, 1940-01-01 onward | read daily_units: wind is km/h and snowfall cm even in metric, and time is a local date with no zone |
| air_quality | OpenAQ nearest-station measurements | ug/m3; aqi_us on US EPA PM2.5 2024 breakpoints, aqi_eu on the 1-6 EAQI band, each with its own scale string |
| air_quality_forecast | Open-Meteo CAMS forecast plus pollen | ug/m3 and grains/m3; pollen is the European domain only and null elsewhere |
| alerts, EU country | EUMETNET MeteoAlarm, EMMA region level | fields identifier, geocode_emma_id and title; timestamps +00:00 |
| alerts, US state code | NWS api.weather.gov | fields id (urn:oid:...), headline, instruction, response and ends; timestamps in the state's local offset |
| marine | Open-Meteo ocean-wave grid | meters, seconds, degrees; on land every wave value is null with an on_land_note |
| earthquakes | USGS fdsnws catalog | magnitude with magnitude_type (mww, mb), depth_km, distance_km, PAGER alert |
| hazards_nearby and disasters | GDACS | alert_level green/orange/red plus alert_score, distance_km, report_url |
| geocode | Open-Meteo geocoding over GeoNames | GeoNames id, IANA timezone, elevation_m, feature_code (PPLA, PPL, AIRP) |
In alerts, country="CA" means California, not Canada. Any two-letter US state or marine code routes to NWS, and a MeteoAlarm member slug or ISO2 routes to the European feed. Canada is covered by neither, and an unrecognized value returns INVALID_PARAM naming both vocabularies.
Where the numbers come from, and how honest the payload is about them
Measured across forecast, air quality and seismic feeds. The freshness block is the through-line.
Responses carry the source, its URL and licence, when the source last updated, when we fetched it, how many minutes stale that makes it and an explicit stale flag with a confidence label. Weather data is only as good as its timestamp, and the timestamp is not something you have to infer from when you called.
The response names the nearest station and how far away it is, how many stations were inside the radius, and how many readings were skipped for being stale. An index computed from a station five kilometres away is a different claim from one measured at the corner, and this is the only endpoint shape that lets you tell.
The US and European indices are returned together with the dominant pollutant for each and the underlying per-pollutant values. The two scales disagree by design, so returning one and calling it the AQI would be picking an answer on the caller's behalf.
The upstream is the official service for the region rather than a resold aggregate, and the attribution is in the payload. Hourly rows carry feels-like, gusts, dew point and UV alongside the basics, which is what a threshold rule actually needs.
Earthquakes filter by magnitude, depth, radius and window; wildfires by sensor, confidence and radiative power; natural events by category and bounding box. Each event carries its review status, so a preliminary automatic detection is distinguishable from a reviewed one.
Every payload carries a disclaimer saying it is informational and must not be used for life-safety decisions. That is not boilerplate. These are aggregated public feeds with real staleness and real gaps, and the official warning channel for a region is the one people should be evacuating on. We would rather say so in the data than in a footnote.
What people build with Weather & Hazards
The jobs this data is most often used for.
endpoints
credits per call
Weather apps call environment_current and forecast to show conditions.
Logistics uses alerts and hazards_nearby to route around severe weather.
Risk tools use disasters and earthquakes to monitor exposure.
What Weather & Hazards data costs
The cheapest call here is 1 credit, so $15/mo (Pro) buys 10,000 of them — $1.50 per 1,000 credits. Credits roll over and never expire, and failed or blocked calls are not charged.
Full pricing →- 1,000 free credits on signup, no card
- One key, all 184 APIs, one credit pool
- Failed and blocked calls are never charged
- Credits roll over and never expire
Call it in two lines
Sign up, get 1,000 credits and one key that works on every engine. Then this is the whole protocol.
curl -X POST https://api.reefapi.com/weather-intel/v1/forecast \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"lat":41.0082,"lon":28.9784,"days":3}'import requests
r = requests.post(
"https://api.reefapi.com/weather-intel/v1/forecast",
headers={"x-api-key": REEF_KEY},
json={
"lat": 41.0082,
"lon": 28.9784,
"days": 3
},
)
print(r.json()["data"])Have a question? We got answers.
The questions people actually ask before wiring up Weather & Hazards.
Get a free key →Are the timestamps UTC or local?▾
It depends on the action, so read the string rather than assuming. A forecast for Istanbul returned current.time "2026-08-26T22:00:00Z" and every hourly step in UTC, while the daily buckets carry date_basis "solar-approx UTC+2" because a calendar day is grouped around local solar time. historical returns "2024-01-01T05:28" with no zone at all, and source=us_nws returns "2026-08-26T17:00:00-04:00". geocode gives you the IANA timezone for the point if you need to convert.
What does units=imperial actually change?▾
Temperature, wind speed and precipitation only. The same New York coordinate returned temperature 23.6 with wind in m/s under metric and temperature 75.4 with wind_speed 11.2 mph under imperial. Pressure stays pressure_hpa in both, humidity stays a percentage, and the field name never changes, so you cannot infer the unit from the key. On historical the daily_units block is authoritative and reports km/h for wind and cm for snowfall.
How far ahead does forecast go, and how fine is each step?▾
hours accepts 1 to 90 and days accepts 1 to 10. The steps are hourly for roughly the first 2.5 days and then 6-hourly out to about day 9, so step 40 is not 40 hours away. Each step carries its own timestamp and you should read that rather than counting. Daily aggregates include a samples count, 24 for a fully covered day, which drops for the partial first and last days.
How do I tell whether the data is stale?▾
Every response carries a source block. A measured MET Norway forecast showed source_updated_at 19:16Z against fetched_at 22:43Z, staleness_minutes 207, stale false and confidence medium. The same field set on the NWS path read staleness_minutes 45 with confidence high, and the MeteoAlarm feed read 551. Log staleness_minutes rather than the time you made the call.
Why do the pollutants in one air_quality response come from different places?▾
Because each pollutant is taken from the nearest station that actually reports it. A London lookup with radius_km 25 returned pm25 from Tower Hamlets at 6.15 km, pm10 from Camden at 1.68 km and no2 from Marylebone Road at 2.53 km, while nearest_station_km 1.68 describes the closest station overall rather than the source of any one value. Each pollutant carries its own station, station_distance_km, provider and age_hours, and that pm10 reading was 142.7 hours old while pm25 was 1.7. stale_readings_skipped counts what was dropped before those survivors were chosen.
Why did alerts come back with count 0 when there are clearly warnings?▾
active_only defaults to true, which keeps only warnings where onset is at or before now and expires is still ahead. A measured German call returned 7 warnings with active_only false and 0 with the default, because every warning in that snapshot had already expired and the feed's source_updated_at was 551 minutes old. Set active_only false to see the full feed and apply your own window against expires.
In earthquakes, what is the difference between a null field and a zero?▾
A magnitude 5.8 event near Toride returned felt_reports 153, cdi 5.7, mmi 4.624 and pager_alert "green". A magnitude 4.4 event 340 km away returned all four as null. Null means USGS never computed the value, usually because nobody filed a felt report, and it is not the same as zero shaking. tsunami is a genuine boolean, and status is "reviewed" or "automatic", which tells you whether a human has checked the solution.
What happens if I call marine for a point on land?▾
You get ok true, the full hourly array, and every wave field null, plus an on_land_note saying the coordinate is outside the ocean-wave grid and that nothing was fabricated. Berlin returned 24 rows of nulls. A point at 40.5, -70.0 in the Atlantic returned wave_height 0.98 m with wave_period 6.25 s and a current sea state. Check for a non-null wave_height rather than for an empty array.
What is the Weather & Hazards API?▾
Weather & Hazards API is a ReefAPI endpoint group for weather & hazards It returns live JSON through POST requests under /weather-intel/v1.
Is the Weather & Hazards API free to try?▾
Yes. ReefAPI starts with 1,000 free credits, no card required. Weather & Hazards calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Weather & Hazards login or account?▾
No login to Weather & Hazards is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Weather & Hazards data?▾
The page example is captured from a live environment_current call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Weather & Hazards API use?▾
Weather & Hazards actions currently cost 1-3 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Weather & Hazards from an AI assistant or MCP client?▾
Yes. Connect ReefAPI once through MCP and your assistant can call weather-intel actions with the same key, credit pool and JSON envelope used by normal REST requests.
19 Utilities & AI APIs on the same key
One key, one credit pool, one response envelope. If you are pulling Weather & Hazards, you are one call away from the rest of the category — no second contract, no second integration.
Need something this API does not do?
Name the endpoint, the field, or a source we do not carry yet. We ship new APIs every week and you would be first to get the key. Real people read every message and reply the same day.
Try it on your own data before you pay anything
The call above is the real endpoint, not a recording. A free key gives you 1,000 credits, the other 183 APIs, and the same envelope everywhere.
Endpoints, parameters and credit costs on this page are read from the live catalog and cannot drift from what the API accepts. Field notes were captured on 2026-08-30.