Concepts
Errors & limits
Errors are predictable JSON. Every job also reports how much it cost in credits_charged.
Error shape
Every failure comes with success: false and an error object with a stable code (for your code to branch on) and a human-readable message:
{
"success": false,
"error": {
"code": "insufficient_credits",
"message": "Not enough credits."
}
}
Common codes
| HTTP | code | What happened |
|---|---|---|
| 401 | invalid_api_key | Key missing, malformed, invalid, or revoked. |
| 403 | api_disabled | API disabled globally, or your account isn't in the beta / has no active plan. |
| 400 | invalid_request | Invalid parameters (missing field, value outside the enum/range). |
| 400 | insufficient_credits | Not enough balance for the job. Check GET /balance and top up. |
| 404 | not_found | Model slug or generation id doesn't exist. |
| 429 | rate_limit | Rate limit exceeded. Wait and retry (backoff). |
Rate limits
Generations are capped at roughly 20 per minute per account (uploads share the same cap). The rest of the /dev surface has a higher global limit. On a 429, apply exponential backoff before retrying.
Credits
Each generation debits credits from the account balance. The cost is model/tool-specific and comes back in credits_charged on the completed job. Check your balance at any time:
curl https://caranguejo.art/api/v1/dev/balance \
-H "Authorization: Bearer $CK"
{ "data": { "credits": 4820 } }