Errors
Envelope
Section titled “Envelope”Every failed call returns a JSON body with the same shape, and the matching HTTP status.
{ "error": { "code": "model_busy", "message": "model sam3 is busy; retry shortly", "retryable": true, "retryAfterMs": 5000 }}| Field | Meaning |
|---|---|
code |
A stable, machine-readable code. Branch on code, not on message. |
message |
A human-readable explanation. The wording can change. |
retryable |
true when repeating the same request unchanged can succeed. |
retryAfterMs |
Suggested wait in milliseconds. 0 when there is no hint. |
429 and 503 responses also carry a Retry-After header in whole seconds.
A failed call costs 0 credits. Nothing is charged when a call returns an error.
| Status | Code | Retryable | Meaning |
|---|---|---|---|
| 400 | invalid_request |
No | The request is malformed, a field is out of range, or the image fails the upload checks. |
| 400 | invalid_image |
No | The image passed the upload checks but could not be decoded. The same handle keeps answering this code. |
| 400 | unsupported |
No | The request is valid but uses something not available yet, such as image.url. |
| 401 | unauthorized |
No | The API key is missing, malformed, invalid, expired or revoked. |
| 402 | insufficient_balance |
No | The balance cannot cover the price of the call. |
| 403 | model_locked |
No | The key’s scope or the account’s pool does not allow the model. |
| 403 | email_unverified |
No | The key owner has not verified an email address. |
| 404 | not_found |
No | The path does not exist. |
| 404 | image_not_found |
No | The img_ handle is unknown, expired or evicted. Upload the image again. |
| 409 | idempotency_conflict |
No | The Idempotency-Key was used with a different request body. |
| 409 | request_in_progress |
No | The first request with this Idempotency-Key is still running. |
| 413 | payload_too_large |
No | The request body or the image exceeds the size limit. |
| 429 | rate_limited |
Yes | The per-minute limit of the pool was reached (funded accounts: only when the balance cannot pay for the call). |
| 429 | daily_limit_reached |
No | The daily allowance of the public pool is used up. |
| 500 | internal_error |
No | An unexpected server error. |
| 502 | upstream_error |
Yes | The call failed at the processing stage. |
| 502 | bad_model_output |
No | The model returned an unusable result. |
| 503 | model_unavailable |
Yes | No GPU node is serving the model right now. During a short loss of contact with the only worker (about a minute), only interactive calls get this error, with Retry-After: 5; sync and batch calls wait in the queue until their deadline. |
| 503 | model_busy |
Yes | The queue of the model is full or the expected wait is too long. |
| 503 | unavailable |
Yes | A temporary shortage, for example while image processing is busy or image storage is unavailable. |
| 504 | upstream_timeout |
Yes | The call passed its deadline. |
The constraints that produce 400 invalid_request are listed per field in the API reference.
daily_limit_reached carries Retry-After until the next UTC day, but repeating the same request before then fails again. Add credit to unlock higher limits. See Rate limits and pools.
Retry guidance
Section titled “Retry guidance”- Repeat a call only when
retryableistrue. - Wait at least
retryAfterMs(orRetry-Afterseconds) before the next attempt. Formodel_unavailableandmodel_busywithout a hint, the server suggests 5000 ms. - Send an
Idempotency-Keyon calls that spend credits, so that a repeated call cannot be charged or run twice. - On
404 image_not_found, upload the image again; the call can then be repeated. - Other 4xx errors need a change to the request or the account before another attempt.
Request id
Section titled “Request id”Every response, errors included, carries an X-Request-Id header: 16 random hexadecimal characters generated by the server. A value sent by the client is ignored. Successful inference responses also carry a call id in the id field (call_<uuid>). Quote either value when contacting support.
Idempotency
Section titled “Idempotency”Send Idempotency-Key: <1 to 128 printable ASCII characters> on any POST that spends credits.
- Within an account, a key is remembered for 24 hours.
- Repeating a request with the same key and the same body returns the original response, status and body, with the header
Idempotent-Replayed: true. The call is not charged and not run again. - The same key with a different body is
409 idempotency_conflict. - The same key while the first request is still running is
409 request_in_progress. - Only final outcomes are stored:
2xxand permanent4xx. A402,429or5xxfrees the key, so the same request can be retried under it.
curl https://api.stack.foldbun.com/v1/ocr \ -H "Authorization: Bearer $FOLDBUN_API_KEY" \ -H "Idempotency-Key: 6d1a8b3e-1f6e-4f0c-9d54-2b8f7c1e0a11" \ -H "Content-Type: application/json" \ -d '{"image": {"id": "img_2dedd0716bfd46ec29b286a279d18b6fc80631e5d90fedb5c63eb36f231622e6"}}'