Errors & rate limits

Error shape

Every error is JSON with a human-readable detail string — show it to the user:

{ "detail": "The basic tier only supports: harm-nl. Upgrade to Pro for all models." }

Status codes

CodeMeaning & what to do
200 / 201 / 204OK / created (slice) / deleted.
400Bad request — e.g. asking /v1/grib for an image-only model, or a missing required field.
401Missing or invalid token. Check the Authorization: Bearer wf_pat_… header.
403Not allowed: the model isn't in your tier (upgrade), or the request exceeds your tier's size cap. Narrow the bbox / params / window.
404Slice token not found (deleted or never existed).
422Validation: unknown model or param, missing params, or a bbox that's malformed or outside the model domain. Remember bbox is west,east,south,north.
429Rate limited — see below.
503No data yet: the model is inactive, hasn't published a run, or its file is briefly unavailable. Retry later.
500Slicing failed unexpectedly. Retry; persistent failures are a bug — let us know.

Rate limits — 429

Downloads are rate-limited per account. A 429 includes a Retry-After header (seconds) — wait that long and retry. A simple retry-aware wrapper is in Samples. Don't hammer on a tight loop; back off.

Daily quota

API downloads count against the same daily download limit as the web app — there's no separate API metering. Check where you stand any time:

  • GET /v1/auth/me returns daily_download_limit (null = unlimited) and daily_downloads_used_today.
  • Listing models with one model is free; downloading data is what counts.
  • Hitting the cap returns an error with a detail explaining it — upgrade or wait for the daily reset.

See also: retry samples · all guides.