Errors, limits, billing
Error format
Section titled “Error format”The envelope matches OpenAI, so existing error handling needs no changes:
{ "error": { "message": "Rate limit reached for requests. Limit: 60 requests/min.", "type": "rate_limit_exceeded", "param": null, "code": "rate_limited" }}Status codes
Section titled “Status codes”| HTTP | type |
What happened, and what to do |
|---|---|---|
400 |
invalid_request_error |
Bad parameter: a size the model does not accept, a file sent to a model that cannot read files, a parameter combination the model rejects (code: "invalid_request", the model’s reason is in message). Check the catalog |
400 |
content_filter |
The upstream filter rejected the request. Rephrase the prompt |
401 |
invalid_request_error |
Key missing, revoked or wrong |
402 |
insufficient_quota |
Balance too low — or reserved by generations still running (see concurrent generations). Top up in your account or wait for them to finish |
403 |
invalid_request_error |
The key lacks the required scope |
404 |
invalid_request_error |
Model not found (model_not_found) |
413 |
api_error |
Audio file over 25 MB on /audio/transcriptions. Shrink the file |
429 |
rate_limit_exceeded |
Per-minute request limit (code: "rate_limited") or concurrent generation limit (code: "concurrency_limit_exceeded") exceeded |
500 |
api_error |
Our fault. Retry with exponential backoff |
502 |
api_error |
The upstream did not answer. Retry, or pick another model |
Rate limit
Section titled “Rate limit”The default is 60 requests per minute per key, over a fixed 60-second window: the counter resets once a minute. Exceeding it returns 429 and two headers:
retry-after: 37x-ratelimit-limit-requests: 60retry-after is how many seconds to wait. The official OpenAI SDKs read it and back off on their own; a hand-rolled client should do the same.
The limit is per key, not per account — if you need more concurrency, spread the load across several keys.
Concurrent generations
Section titled “Concurrent generations”Video, music and images run in parallel, but not without a cap. At most this many jobs run at once per account:
| What | Jobs at once |
|---|---|
Video (/videos) |
10 |
Music (/music) |
10 |
Images (/images/*) |
20 |
Above the cap you get 429 with code: "concurrency_limit_exceeded" and an X-Mixen-Concurrent-Limit header — wait until one job reaches completed or failed, then retry. If your integration needs more, contact support: the limit is raised per key.
While a job runs, its price is reserved on your balance. A new job is checked against the free remainder: with 100 RUB on the balance and a 67 RUB video running, a second identical video gets 402 — the money only covers the job already started.
Billing
Section titled “Billing”- Charges come off your single Mixen balance, shared with the bot and the web account.
- You are charged on completion. A failed generation (
failed,502, a stalled video job) is not billed. - The price is whatever the catalog shows at the time of the request. See Models and pricing for the billing units.
- Chat spend appears in the response’s
usagefield; when streaming it arrives as a final chunk if you passstream_options: {"include_usage": true}.
Retries
Section titled “Retries”A reasonable production strategy:
429— wait outretry-after, then retry.500and502— up to three attempts, waiting 1, 2, then 4 seconds.400,401,402,403,404— do not retry. These are request or account problems; a retry returns the same answer and spends your limit.
Timeouts
Section titled “Timeouts”Set your HTTP client timeout to at least 120 seconds for images and long chats: aborting on the client side does not cancel a generation already under way, and you will still be charged. Video and music need no timeout at all — they are asynchronous.