REST API
Limits and errors
The error format, the codes you will meet most, per-minute request limits, and how to handle them.
Error format
Every error is answered with the right HTTP status and a body of always the same shape:
{
"error": {
"code": "INSUFFICIENT_CREDITS",
"message": "Not enough credits for this model"
}
}Branch on code, which never changes. message is written for people and follows the Accept-Language header, so it can be shown to your users as it is.
The codes you will meet most
| Status | Code | Meaning | What to do |
|---|---|---|---|
| 400 | BAD_REQUEST | The body or parameters do not match the schema | Check the field named in message |
| 400 | JOB_ALREADY_SENT | The job was already sent to the model and cannot be cancelled | Wait for the result; no credits are returned |
| 400 | JOB_NOT_CANCELABLE | The job has already finished | Nothing |
| 400 | WEBHOOK_URL_INVALID | webhookUrl is not a public HTTPS address on port 443 | Use an HTTPS address reachable from the internet. See Webhooks |
| 401 | UNAUTHORIZED | The key is missing, wrong, revoked or expired | Check the Authorization header or make a new key |
| 402 | INSUFFICIENT_CREDITS | Not enough balance for this request | Top up credits in the studio |
| 403 | EMAIL_UNVERIFIED | The account's email is not verified | Verify the email in the studio |
| 403 | ACCOUNT_SUSPENDED | The account is suspended | Contact the team on Telegram |
| 404 | NOT_FOUND | The job, file or project does not exist or is not this account's | Check the id |
| 429 | TOO_MANY_ACTIVE_JOBS | 5 jobs are already running | Wait for one to finish, then try again |
| 429 | RATE_LIMITED | Too many requests within a minute | Wait as message says, then try again |
When the input breaks a model's rules, for example an option that does not exist, a reference file that is too large, or an unsupported combination of settings, the answer is 400 with a code that names the rule. No credits are taken for a refused request.
Limits
| Limit | Value |
|---|---|
Jobs running at the same time (QUEUED, SUBMITTED, RUNNING) | 5 per account |
| Variations per request | 1 to 5 |
| Requests that start a generation or upload | 30 per minute per key |
| Other requests | 120 per minute per key |
| Ids per download-link request | 100 |
| Items per list page | 50 |
Per-minute limits are counted per API key, so several keys do not use up each other's allowance.
Handling tips
- Retry with a delay for
429and for5xxerrors. A growing delay (2, 4, 8 seconds) is enough. - Do not blindly retry
POST /jobsafter a dropped connection. CheckGET /jobs?sort=newest&limit=5first to be sure the job was not created, so credits are not taken twice. - A
FAILEDjob is already refunded. Nothing needs doing to get the refund.

