Errors & conventions
Conventions
- HTTPS + JSON for all request and response bodies.
- Timestamps are ISO-8601 UTC (e.g.
2026-06-04T02:14:36Z). - IDs are UUID strings.
- Reads are scoped to your account automatically — you only ever see your own jobs, models, datasets, and usage.
Error shape
Any non-2xx response carries a JSON body with a detail message:
json
{ "detail": "job not found" }Status codes
| Code | Meaning | Typical cause |
|---|---|---|
200 | OK | Successful read. |
201 | Created | A run was submitted (POST /jobs). |
204 | No Content | Successful write with no body (e.g. revoke a key). |
400 | Bad Request | Malformed body or invalid field. |
401 | Unauthorized | Missing or invalid API key. |
403 | Forbidden | Key lacks the required scope. |
404 | Not Found | Unknown ID, or a result that doesn't exist yet. |
409 | Conflict | Idempotency-key reuse with a different payload. |
422 | Unprocessable | Schema validation failed. |
Idempotency
Every run submission carries an idempotency_key. Re-submitting with the same key returns the existing job rather than creating a duplicate — so retrying after a network error is always safe. Pick a stable key per logical run (e.g. a slug or a hash of the run config).
Polling
Telemetry is poll-based. For a live run, fetch GET /jobs/{id}/metrics?since_step=N with the last step you've seen and append the new points client-side — a few seconds between polls is plenty. Result and usage rows appear once a run completes.