Browse the docs

Public API

API Errors and Limits

Every error code the API can answer, what it means, and the limits on requests and credits.

This page lists every error the Public API can answer and every limit on a key.

What it does

An error always has this shape, and the code never changes its meaning:

{ "error": { "code": "spend_cap_reached", "message": "...", "request_id": "...", "period": "day", "cap": 2000, "used": 1990, "need": 25 } }

Build your code on code, not on message. Quote request_id when you write to support.

When to use it

Read this page when a call fails, and before you put your code into use.

Every option explained

Limits

LimitValue
Requests a minuteWhat you set on the key, up to 120
Spend a day and a monthWhat you set on the key, in Credits. Days and months run on India time.
KeysUp to 10 on an account
WebhooksUp to 3 on an account
Prompt2,000 characters

A job that is failing or blocked stops counting against your cap, because it costs nothing. Your balance is always the last limit.

Errors

CodeStatusWhat to do
invalid_request400Check the fields. reason may name the one that is wrong.
invalid_json400The body is not valid JSON
idempotency_key_required400Add an Idempotency-Key header
key_missing401Add the Authorization header
key_invalid401Check the key
key_revoked401This key was revoked. Make a new one.
key_expired401This key has expired. Make a new one.
insufficient_credits402Top up. need and have say how much.
spend_cap_reached402Raise the cap on this key, or wait
plan_required403Change to a plan with the API
api_closed403The API is not open for this account
scope_missing403Add the scope named in scope to this key
feature_closed403This tool is not open for this account
account_blocked403Contact support
email_unverified403Verify your email on the website
terms_not_accepted403Accept the latest terms on the website
age_required403Confirm your age on the website
not_found404No such id on this account
asset_not_found404An asset id in the request is not on this account
idempotency_conflict409This key was used with another request. Use a new one.
idempotency_in_progress409The first call is still running. Wait and try again.
content_blocked422Stopped by the content rules. Nothing was charged.
prompt_required, text_required422Add the words
text_too_long422Shorten it to max
ratio_not_supported, count_not_supported, seconds_not_supported, tier_not_supported, mode_not_supported422Pick a value from this list
too_many_references, reference_required, frame_not_supported, product_required422Check the pictures in the request
language_not_supported, voice_not_found422Pick one from GET /voices
upload_type, upload_size, upload_dimensions, upload_not_found, upload_blocked422Check the file
rights_required, consent_required422Confirm the rights or the consent
influencer_not_ready, presenter_not_ready422Finish it on the website
media_not_supported422This tool does not take this kind of file
limit_reached422This account has reached a limit of this tool
authorization_pending, slow_down, access_denied, expired_token400See Connect an app
rate_limited429Wait for the seconds in Retry-After
internal_error500Our fault. Try again, and quote request_id if it stays.
unavailable503Paused for a moment. Try again shortly.

A job that ends badly has an error of its own: generation_failed, with its held credits sent back, content_blocked, or the code that stopped it before it started.

Common problems

I get rate_limited on a slow script

Your limit counts every call, including reading a job. Use a webhook in place of asking every second.

A call failed. Did it charge me?

No error charges you. To be sure, send the same call with the same Idempotency-Key: you get the job if there was one, and a new one if not.

Related guides

Updated 1 Nov 2026