Errors & Status Codes
Forecast, Decision, Windows and Hours often return HTTP 200 — readforecast_status,access,decision_statusin JSON. HTTP 429 = rate limit (Community 120/day). Loxone: O1=12 offline — see offline sections in Forecast / Flex.
SpotpriceAPI splits errors into two kinds: business states (your request worked, but data is limited) come back as HTTP 200 with a status field in JSON. Broken requests (bad parameters, too many calls) use normal HTTP 400 or 429.
Everyday example
You call Decision without a free account. HTTP says 200 OK — looks fine! But decision_status is not_available and the list is empty. Your app must read that field, not only the green HTTP code.
When to use this page
- Building error handling in your app
- Getting empty arrays with HTTP 200
- Debugging 429 or 400 from Windows
Core rule
| Situation | HTTP | What to check |
|---|---|---|
| Tier too low, missing data | 200 | decision_status, forecast_status, access |
| Bad parameters | 400 | error field |
| Too many requests | 429 | rate_limit_exceeded, Retry-After header |
| Server trouble | 500 | Retry later; check /v1/status |
Status fields (HTTP 200)
| Field | Used on | Common values |
|---|---|---|
forecast_status | Forecast, Decision, Windows | ok, degraded, missing |
decision_status | Decision, Windows, Hours Demand | ok, empty, placeholder, incomplete_input, invalid_input, not_available |
telemetry_status | Plant Telemetry | ok, incomplete_input, invalid_input, not_available |
pv_status | PV Forecast | ok, incomplete_input, weather_missing, not_available |
weather_status | Plant Weather | ok, incomplete_input, weather_missing, not_available |
What they mean
| Value | Plain English | Typical cause |
|---|---|---|
not_available | Feature locked for your tier | Basic calling Decision |
incomplete_input | Required field missing | No battery.soc_pct |
invalid_input | Bad values | Meter went backwards |
empty | Valid request, no matching result | Window has no prices |
placeholder | Too few prices to decide | Fewer than 4 priced hours |
degraded | Data old but usable | Cache older than 3 hours |
missing | No forecast at all | Pipeline issue |
HTTP 400 on Decision Windows
error | Cause |
|---|---|
invalid_range | start is not before end |
incomplete_request | Missing a window (start+end or window_* hours or flex_pack/slot_id merge) or missing count/segments/energy_kwh+max_power_kw. Omitting mode/role defaults to cheapest/consume |
invalid_count | Bad number |
invalid_mode / invalid_role | Wrong enum |
count_too_large | Exceeds tier horizon |
HTTP 429 example
{
"error": "rate_limit_exceeded",
"message": "API rate limit exceeded. Retry after the time indicated in Retry-After.",
"limit": "community 120/day",
"limit_scope": "api_key_day",
"limit_value": 120,
"used": 120,
"remaining": 0,
"retry_after_seconds": 3600
}
Also check header Retry-After.
Step by step: handle errors in your app
1. If HTTP is 429 or 400 — log body, wait, retry (backoff on 429). 2. If HTTP is 200 — read decision_status / forecast_status / telemetry_status first. 3. On not_available — show upgrade hint from response if present. 4. On incomplete_input — read missing[] for which fields to fix. 5. Only then process arrays (forecast[], decision[], slots[], charge_hours[]).
Common mistakes
- Treating empty
decision[]on HTTP 200 as success - Retrying 429 immediately without waiting
- Ignoring
degraded— prices may be stale
Next steps
- Rate limits — avoid 429
- Authentication — avoid
not_available - Decision Windows — 400 errors in context
Register for Community or code samples with your personal key.