Limits, quotas & headers
Plans
| Plan | Units / month | Burst / s (per key) | Endpoints |
|---|---|---|---|
| Free | 10,000 | 5 | weather, health, stations |
| Starter | 500,000 | 20 | weather, health, stations, history, radar_grid |
| Pro | 5,000,000 | 100 | weather, health, stations, history, radar_grid, radar_volume, variants |
| Enterprise | custom | 200 | weather, health, stations, history, radar_grid, radar_volume, variants |
The monthly quota belongs to the organization (all live keys together) and resets on the 1st at 00:00 UTC.
Units
The quota counts weighted units. Only responses with status < 400 are charged.
| Request | Units |
|---|---|
/v2/weather | 1; 2 with hours > 48 or past_hours > 0 |
/v2/health, /v2/stations | 1 |
/v2/history | 1 per started 31 days (hourly) / 366 days (daily) |
/v2/radar/grid, /v2/radar/volume | 2 |
/v2/radar/volume/rain/… frames | 0 |
/v2/meta/* | free, no key |
Burst limit
Each key has a token bucket that refills at the plan’s rate per second (capacity = rate). Mobile keys additionally have a bucket per installation (X-Install-Id, at most 20/s). An empty bucket answers 429 rate-limited with Retry-After.
Response headers
Keyed responses carry the IETF RateLimit headers (r = remaining after this request, t = seconds until reset):
RateLimit-Policy: "burst";q=20;w=1, "month";q=500000;w=2592000
RateLimit: "burst";r=19;t=1, "month";r=412345;t=1048576
X-Request-Id: 7f3c…Mobile keys add "install"; unlimited plans omit "month". Quote X-Request-Id when you contact support.
Errors
All errors are RFC 9457 application/problem+json with type, code, title, status and detail. Match on code — it is the stable slug below. type is a URI that may change (it is about:blank until the public API address is final).
| Status | code | When |
|---|---|---|
| 401 | unauthorized | no key, unknown key |
| 401 | key-revoked | the key was revoked |
| 401 | app-archived | the key’s app is archived (reversible — restore the app) |
| 401 | key-expired | the key passed its expiry |
| 403 | organization-disabled | the organization is disabled |
| 403 | plan-feature-missing | endpoint (or variant ≠ stable) not in your plan |
| 403 | scope-missing | in the plan, but the key’s scopes exclude it |
| 403 | origin-not-allowed | web key with allowed origins; Origin sent and matches none |
| 403 | bundle-required | mobile key with bundle IDs; X-Ios-Bundle-Identifier / X-Android-Package missing |
| 403 | bundle-not-allowed | mobile key with bundle IDs; the bundle/package header matches none |
| 429 | rate-limited | burst bucket empty; wait Retry-After seconds |
| 429 | quota-exceeded | monthly units used up; Retry-After = seconds until the 1st (UTC) |
| 503 | auth-unavailable | temporary; retry shortly |
HTTP/1.1 429 Too Many Requests
Content-Type: application/problem+json
Retry-After: 1
{"type": "about:blank", "code": "rate-limited", "title": "Too many requests", "status": 429, "detail": "…"}