API reference
Errors & limits
Conventional HTTP semantics; error bodies are {"detail": …}. The cases worth coding for:
| Status | When | Handle by |
|---|---|---|
| 401 | Missing/invalid credentials | Check the key; revoked keys 401 immediately |
| 402 | Not enough credits for the run | Top up, subscribe to the metered lane, or use BYOK |
| 403 | API key hit a session-only endpoint (key management), or flagged account | Use a session JWT for key management |
| 404 | Unknown event/report, or a report you don't own | Report access is owner-scoped |
| 409 | quote_expired — dynamic quote moved >15% past your quoted_credits | Re-check the quote and retry; no report row was created, nothing charged |
| 429 | Rate limited — 5 council runs/hour per account | Back off; reads are not run-limited |
Report failure semantics
A run that fails mid-council flips to status: "failed" with an error_message, and credits auto-refund to the pool they came from (free or paid). Metered-lane failures are never billed. Deploy-interrupted runs auto-resume once; double failures refund.
Robust polling loop
while True:
r = get(f"/api/reports/{rid}").json()
if r["status"] == "completed": break
if r["status"] == "failed":
raise RuntimeError(r.get("error_message")) # already refunded
time.sleep(5) # runs take 30-120s; MCP's run tool polls for youDegraded runs are not failures
If a provider times out or 503s, the council completes with the remaining models: runtime.degraded: true and runtime.provider_failures name the dropouts. You are charged normally (the report is real) — weigh consensus size in your own logic.