Errors
Every non-2xx response from https://api.mouse.dev uses a single JSON error envelope. Error messages name the offending field or limit and never echo your request content (state, instructions, or criteria).
Error envelope
Section titled “Error envelope”{ "error": { "type": "invalid_request_error", "code": "state_too_long", "message": "state is 71,204 tokens; mouse-preview-2026-10-13 reads at most 65,536. Nothing was truncated or billed.", "param": "state" }}| Field | Type | Description |
|---|---|---|
error.type | string | Broad error category: invalid_request_error, authentication_error, billing_error, rate_limit_error, or api_error. |
error.code | string | Machine-readable error code for programmatic branching (see table below). |
error.message | string | Human-readable explanation naming the limit or parameter. Never contains request content. |
error.param | string (optional) | Dotted path of the offending request field (e.g. "state", "questions.intent.criteria", "examples") or header ("authorization"). |
Every error response includes Mouse-Request-Id, Mouse-Region, Mouse-Data-Retention: none, and Cache-Control: no-store. 4xx responses are never billed.
HTTP status codes and error codes
Section titled “HTTP status codes and error codes”| Status | error.type | error.code | param | Description & resolution |
|---|---|---|---|---|
400 | invalid_request_error | invalid_calibration_profile | calibration | The calibration token is malformed, truncated, tampered with, or signed with a retired key. Fit a new profile with POST /v1/calibrations. |
401 | authentication_error | missing_api_key | — | Missing Authorization: Bearer sk_mouse_... header. |
401 | authentication_error | invalid_api_key | — | Key does not start with sk_mouse_, fails its CRC32 checksum, is expired, or has been revoked. |
402 | billing_error | insufficient_credits | authorization | Prepaid credit balance is $0.00. Top up or enable auto-reload at /console/billing. |
404 | invalid_request_error | model_not_found | — | Unknown model string. Query GET /v1/models for active aliases (mouse-1, mouse) and snapshots. |
409 | invalid_request_error | profile_model_mismatch | — | The supplied calibration profile was fitted on a different model snapshot than the one serving this request. Pin the model version or refit the profile. |
413 | invalid_request_error | request_too_large | body | Raw HTTP request body exceeds 4,000,000 bytes (4 MB). |
422 | invalid_request_error | invalid_schema | <field.path> | Request body failed schema validation (e.g. missing state or questions, unknown field inside a question, choice criteria passed as an array instead of an object, or invalid calibration label). |
422 | invalid_request_error | state_too_long | state | state exceeds 65,536 tokens. Nothing is truncated or billed; trim state to the fields relevant to your questions. |
422 | invalid_request_error | too_many_questions | questions | More than 128 questions in a single request. |
422 | invalid_request_error | too_many_options | questions.<id>.criteria | A question has more than 1,024 options. |
422 | invalid_request_error | too_few_examples | examples | Fewer than 200 examples sent to POST /v1/calibrations. |
422 | invalid_request_error | too_many_examples | examples | More than 5,000 examples sent to POST /v1/calibrations. |
422 | invalid_request_error | too_few_examples_per_question | examples | No question signature in POST /v1/calibrations had at least 50 labeled examples. |
429 | rate_limit_error | rate_limited | — | Exceeded the per-key request rate limit (200 RPS, burst 400). Includes Retry-After. |
429 | rate_limit_error | token_rate_limited | — | Exceeded the per-key input token rate limit (20,000,000 TPM). Includes Retry-After. |
503 | api_error | engine_timeout | — | The GPU worker did not respond within the 10-second engine deadline. Includes Retry-After: 2. |
Handling retries and timeouts
Section titled “Handling retries and timeouts”When calling POST /v1/systemone on a user-facing or hot agent path:
- Do not retry
400,401,402,404,409,413, or422: These are deterministic client errors; fix the request or fall back to baseline harness logic immediately. - Honor
Retry-Afteron429and503: Both429 Too Many Requestsand503 Service Unavailableinclude aRetry-Afterheader (in integer seconds). On background or batch paths, retry with exponential backoff + jitter afterRetry-After. - Bound total latency on critical paths: In interactive agent loops (such as tool-call gating or message routing), set a per-request deadline (e.g.
1,500 msto3,000 ms) with0or1retry and fall back to your deterministic floor if the call times out.
async function systemOneWithFallback(payload: unknown) { const res = await fetch("https://api.mouse.dev/v1/systemone", { method: "POST", headers: { Authorization: `Bearer ${process.env.MOUSE_API_KEY}`, "Content-Type": "application/json", }, body: JSON.stringify(payload), signal: AbortSignal.timeout(2_500), });
if (res.status === 429 || res.status === 503) { const retryAfterSec = Number(res.headers.get("retry-after") ?? "1"); await new Promise((r) => setTimeout(r, retryAfterSec * 1_000)); // Optional single retry for background jobs }
if (!res.ok) { const { error } = await res.json(); throw new Error(`[${error.code}] ${error.message}`); } return res.json();}