API documentation

8 REST endpoints returning JSON. Base: https://whataweather.com/api/v1. Open CORS. Server cache 15-60 min. OpenAPI 3.0 spec: openapi.json.

Authentication

The API is public and no key is required to start. If you go over 60 req/min/IP, write to [email protected] for a free key that goes in the X-Api-Key header and raises the limit. Without a key, send no special header.

GET/api/v1/weather

Current weather + 7-day forecast. Open-Meteo proxy with 15-minute cache.

ParamTypeRequiredDescription
citystringconditionalCity name. If omitted, lat+lon required.
latnumberconditionalDecimal latitude. Required if no city.
lonnumberconditionalDecimal longitude. Required if no city.
curl 'https://whataweather.com/api/v1/weather?city=madrid'
const r = await fetch( 'https://whataweather.com/api/v1/weather?city=madrid' ); const d = await r.json(); console.log(d.current.temperature_2m);
import requests r = requests.get('https://whataweather.com/api/v1/weather', params={'city':'madrid'}) print(r.json()['current']['temperature_2m'])
{ "city": "Madrid", "coordinates": {"lat": 40.4168, "lon": -3.7038}, "current": {"temperature_2m": 18.5, "weather_code": 2, "is_day": 1, "wind_speed_10m": 12.4}, "daily": {"time":["2026-05-11"], "temperature_2m_max":[24], "temperature_2m_min":[12]}, "units": {"temperature":"celsius","wind":"km/h"}, "attribution": "WhatAWeather + Open-Meteo", "updated": "2026-05-11T12:00:00Z" }
400 missing city or (lat & lon). 404 city not found. 500 upstream error.

GET/api/v1/reservoirs

Full list of Spanish basins and reservoirs with KPIs (capacity, current %, weekly delta). 60-minute cache.

curl https://whataweather.com/api/v1/reservoirs

GET/api/v1/reservoirs/{id}

Individual record by id or slug (e.g. alcantara, ebro, la-serena).

curl https://whataweather.com/api/v1/reservoirs/alcantara
404 not found.

GET/api/v1/alerts

Active AEMET alerts filtered by Spanish autonomous community. Pending official scraping: currently returns placeholder data marked in attribution.

ParamTypeDescription
ccaastringvalencia, cataluna, madrid, andalucia, etc.
curl 'https://whataweather.com/api/v1/alerts?ccaa=valencia'

GET/api/v1/lightning

Strikes in the last minutes within a bbox. Placeholder until Blitzortung is integrated.

ParamTypeDescription
bboxstringlat1,lon1,lat2,lon2 (SW -> NE order).
minutesintegerWindow in minutes (default 10).
curl 'https://whataweather.com/api/v1/lightning?bbox=-10,35,5,44&minutes=10'

GET/api/v1/wildfire-risk

Wildfire risk (Fire Weather Index + Ignition Risk Index).

ParamTypeDescription
citystringCity. Also supports lat+lon.
curl 'https://whataweather.com/api/v1/wildfire-risk?city=sevilla'

GET/api/v1/storms

Named storms (active + historical), backed by /data/named-storms.json.

curl https://whataweather.com/api/v1/storms

GET/api/v1/snow-level

Current snow line + 24h/48h forecast per mountain range.

ParamTypeDescription
rangestringpirineos | cantabrica | sierra_nevada | central | iberica.
curl 'https://whataweather.com/api/v1/snow-level?range=pirineos'

Rate limits

60 req/min/IP without key. If exceeded you will get 429 Too Many Requests. Wait 60 s or request a key by email to raise the limit to 600 req/min.

Error codes

  • 400 bad request (missing required parameters).
  • 404 not found (invalid slug, non-existing city).
  • 429 rate limit exceeded.
  • 500 internal or upstream error (Open-Meteo, MITECO).

All errors return JSON: { "error": "...", "message": "..." }.

Cache

Server caches each call in memory:

  • /weather: 15 minutes per (lat,lon).
  • /reservoirs, /reservoirs/{id}: 60 minutes.
  • /storms, /snow-level: 60 minutes.
  • /alerts, /lightning: 5 minutes.
  • /wildfire-risk: 30 minutes.

We also send Cache-Control: public, max-age=300 so your CDN and browser cooperate.

Summary terms

  • Required attribution: visible link to https://whataweather.com.
  • No API reselling. You may sell products built on top.
  • No mass scraping. Request a free key for more volume.
  • No warranties: data provided "as is".