Every error from the API is JSON with a stable code and a human-readable English error:

{ "error": "Unauthorized: Session has been revoked.", "code": "session_revoked" }

Branch on code, never on the text. The text may change; codes will not. New codes may be added, so treat an unknown code by its HTTP status.

code HTTP Meaning What the app does
invalid_api_key 403 The gateway's key was revoked or disabled (an unknown key from an unregistered gateway gets the HTML 404 of section 2) "Service unavailable". It is a gateway problem, not the user's
method_not_allowed 405 Wrong HTTP method Fix the client
missing_credentials 400 login without username or password Ask again
invalid_credentials 401 Wrong username or password Ask again
account_disabled 403 Line disabled or banned Show it. Keep the session token
account_expired 403 Line expired Show it. Keep the session token: after the reseller renews the line, refresh-session works again
restreamer_not_allowed 403 Restreamer lines cannot use this API Show it
wrong_reseller 403 The reseller's key no longer serves this session's line Show it. Keep the session token
access_denied 403 Access refused from where the device is (temporary IP block, reseller's domain lock) Show it. Keep the session token and try again later
token_missing 401 No Authorization: Bearer header Fix the client
session_expired 401 The session token expired but can still be renewed Call refresh-session once, then retry
session_invalid 401 The session token is not valid here (malformed, from another key, or too old to renew) Sign in / pair again
session_revoked 401 This device was signed out or unlinked, or logout-all was used Sign in / pair again
credentials_changed 401 The line's username or password changed (also seen some time after a logout-all) Sign in / pair again
account_not_found 401 The line no longer exists Sign in / pair again
invalid_parameter 400 A parameter is missing or out of range Fix the request
not_in_package 403 The content exists but this line's package does not include it "Not included in your plan"
not_found 404 No movie or series with that id Treat as gone
unknown_endpoint 404 No such action Fix the client
rate_limited 429 Too many history-update reports for the line, or more than one diagnostics batch a minute from the device (Retry-After) history-update: drop that report, do not retry it. diagnostics: keep the records and send them after Retry-After
temporarily_unavailable 503 Try again shortly Retry with backoff

Not every failure is JSON. The 404 HTML page of section 2 (gateway not recognized), your gateway's own rate limit (429/503) and server errors (5xx) come without code. When there is no code, go by the status, and treat 429 and 5xx as temporary: retry with backoff, and never sign the user out because of them. A 429 with code rate_limited is the panel's own limit on history and diagnostics reports (above).

The streaming nodes answer with bare HTTP status codes, not JSON (section 7.4).

API responses carry Cache-Control: no-store (except the channel map of playback-routes, which has its own max-age and ETag): do not cache them in shared caches.