Skip to content

Errors and retries

{
"error": {
"type": "conflict",
"message": "v7 is live, not v6. Check what changed, then send `expect: \"v7\"`.",
"param": "expect",
"request_id": "req_8a4f2fedbd4af9da"
}
}

Every error has this body. message is written for a person and says what to do. param names the request field the error is about, such as cases[0].input, or is null. request_id is also in the Pensieve-Request-Id header of every response; quote it when you ask for help.

Status type Means Retry?
400 invalid_request A field is missing, unknown or wrong; param names it No: fix the request
401 authentication No key, an unknown key, or a revoked one No
403 permission The key can’t do this No
404 not_found No such model, call, release or route No
409 conflict The object’s state refuses it, such as promoting before sign-off, or a stale expect No: read the state, then decide
429 rate_limit Too many requests; Retry-After says when to try again Yes
501 not_available Part of the API, but not served here yet No
500 server Something failed on Pensieve’s side Yes

The SDKs try again on their own, twice by default: after a dropped connection, a timeout, or a 408, 429, 500, 502, 503 or 504. They wait half a second, then a second, doubling up to 8 seconds, with some jitter. A Retry-After header wins, up to a minute. They never retry a 501 or any other 4xx.

Every POST takes an Idempotency-Key header. Send the same key again within 24 hours and you get the first answer back, with Idempotent-Replayed: true, instead of the work being done twice. Send the same key with a different request and you get a conflict.

The SDKs make up a key for every POST and keep it across their retries. Pass your own to make a retry safe across processes, such as a job that may run twice:

await pensieve.models.decide("grade-audit", { input }, { idempotencyKey: `grade-${trial.task}` });
client.models.decide("grade-audit", input=case, idempotency_key=f"grade-{case['task']}")

The sandbox allows 300 requests per key every 10 seconds. Live limits are set per workspace.