Errors & status codes
How Temporis reports success and failure, what each status means, and how to handle them.
Response shape
The shape of a response depends on what happened:
- A successful ingest returns 204 No Content with no body.
- A successful prediction returns 200 with a JSON body.
- Any error returns the relevant HTTP status with a JSON body of the form
{ "detail": "..." }.
{ "detail": "Data profile not found." }Status codes
| Status | Meaning | Where |
|---|---|---|
| 200 OK | Prediction succeeded; body holds the samples. | predict |
| 204 No Content | Ingest succeeded; no body. | ingest |
| 400 Bad Request | Invalid prediction parameters. | predict |
| 401 Unauthorized | Missing or invalid access token. | all requests |
| 402 Payment Required | No card on file, or a payment issue. | predict |
| 404 Not Found | Data source not found (ingest); data profile not found or not ready to serve (predict). | ingest, predict |
| 409 Conflict | Data source archived (ingest); not enough data (predict). | ingest, predict |
| 502 Bad Gateway | Prediction failed — a transient server-side error. | predict |
Handling errors
Most failures map to a clear next action:
- 401 — check that the
Authorizationheader is present and the token is valid. See Authentication. - 402 — add or fix a credit card in the dashboard under Billing, then retry.
- 404 — make sure the data source or data profile exists, and that the profile is ready to serve.
- 409 on predict — ingest more history until the profile meets its minimum, then retry.
- 409 on ingest — the data source is archived; unarchive it or write to another source.
- 502 — transient. Retry with exponential backoff.
A simple branch on the status code covers all of these:
import time, requests
def predict(payload, token, retries=3):
for attempt in range(retries):
resp = requests.post(
"https://api.temporis.co/v1/predict",
headers={"Authorization": f"Bearer {token}"},
json=payload,
)
if resp.status_code == 200:
return resp.json()
if resp.status_code == 502:
time.sleep(2 ** attempt) # transient: back off and retry
continue
detail = resp.json().get("detail", "")
if resp.status_code == 402:
raise RuntimeError(f"Billing: {detail} — add a card in the dashboard.")
if resp.status_code == 409:
raise RuntimeError(f"Not ready: {detail} — ingest more history.")
resp.raise_for_status() # 400 / 401 / 404: fix the request
raise RuntimeError("Prediction failed after retries.")Retries
Retry the right things
A 502 is safe to retry — it is transient. Ingest is idempotent (writes upsert on the (timestamp, name) key), so retrying a failed ingest is always safe. Avoid blindly retrying 4xx responses; fix the request first.