Errors
Every error is JSON with a stable machine code:
json
{
"error": true,
"code": "UNSUPPORTED_OPTION",
"message": "last_frame_url is not supported by this model",
"param": "last_frame_url"
}details (validation issues, provider context) and param (the offending field)
appear when they add information. The same table is embedded machine-readably in the
OpenAPI spec as x-error-codes.
All error codes
| Code | HTTP | Meaning |
|---|---|---|
VALIDATION_ERROR | 400 | The request body or query failed schema validation. `details` lists the individual problems. |
INVALID_PARAM | 400 | A path parameter has the wrong type (e.g. a non-integer key or webhook id). |
INVALID_IDEMPOTENCY_KEY | 400 | The Idempotency-Key header is malformed. Allowed: 1-200 characters of A-Z a-z 0-9 _ . - |
AUTH_REQUIRED | 401 | No credentials. Send `X-API-Key: aiv_sk_...` or `Authorization: Bearer <key or session JWT>`. |
INVALID_API_KEY | 401 | The API key is malformed, unknown, or revoked. |
KEY_EXPIRED | 401 | The API key is past its expiry date. Create or rotate a key on the dashboard. |
TOKEN_MALFORMED | 401 | The Bearer token is not a structurally valid JWT. |
TOKEN_EXPIRED | 401 | The session JWT has expired — log in again. |
TOKEN_INVALID | 401 | The session JWT failed verification. |
USER_NOT_FOUND | 401 | The session JWT is valid but its user no longer exists. |
PASSWORD_CHANGED | 401 | The session JWT was issued before the last password change. Log in again. |
INVALID_TICKET | 401 | The SSE ticket is invalid, expired, or bound to a different job. |
INSUFFICIENT_CREDITS | 402 | Your balance does not cover the job cost. Nothing was charged. |
insufficient_scope | 403 | The API key lacks the required scope (`required_scope` names it), or an API key attempted session-only key management. |
upgrade_required | 403 | A paid-plan feature on a free key (e.g. /batch), or the free trial is exhausted. `pricing_url` links to plans. |
ACCOUNT_BANNED | 403 | The account is suspended. Contact support@aiveed.io. |
NOT_ELIGIBLE | 403 | The account cannot perform this action (e.g. unverified email, locked credits). `reason`/`reasons` explain. |
CONTENT_POLICY_VIOLATION | 403 | The prompt or input media failed content moderation. Repeated violations can suspend the account. |
JOB_NOT_FOUND | 404 | No job with that id belongs to you. |
KEY_NOT_FOUND | 404 | No such API key (or it is already revoked). |
WEBHOOK_NOT_FOUND | 404 | No webhook config with that id belongs to you. |
NOT_FOUND | 404 | The endpoint or referenced resource does not exist. |
KEY_LIMIT_REACHED | 409 | Maximum active API keys reached — revoke one first. |
KEY_REVOKED | 409 | The key is revoked and cannot be rotated. |
WEBHOOK_LIMIT_REACHED | 409 | Maximum active webhooks reached — delete one first. |
CANNOT_CANCEL | 409 | Only queued jobs can be cancelled; this one already left the queue. |
PAYLOAD_TOO_LARGE | 413 | JSON bodies are capped at 1 MB; uploads at their per-kind size cap (image 10 MB, audio 5 MB, video 50 MB). |
UNSUPPORTED_MEDIA_TYPE | 415 | The uploaded file type is not allowed for that `kind`. |
UNSUPPORTED_OPTION | 422 | A request option is not supported by this model (or a webhook URL is not https/publicly routable). `param` names the offending field. |
RATE_LIMIT_EXCEEDED | 429 | Over your per-minute request limit. Honor `Retry-After` and the X-RateLimit-* headers. |
concurrency_limit_reached | 429 | Your key already has `max_concurrent` jobs in flight — wait for one to finish. |
TOO_MANY_STREAMS | 429 | Too many SSE streams open for this account. Close one before opening another, or poll GET /v1/jobs/{id} instead. |
INTERNAL_ERROR | 500 | Unexpected server error. Safe to retry with the same Idempotency-Key. |
PROVIDER_ERROR | 502 | The upstream generation provider is temporarily unavailable. Charged jobs that fail are refunded automatically. |
GATEWAY_TIMEOUT | 504 | The generation service did not respond in time. The job may still be running — poll GET /v1/jobs/{id} rather than resubmitting, or the work could be charged twice. |
GENERATION_FAILED | 500 | Fallback code when a submission fails without a more specific cause. |
EXTEND_FAILED | 500 | Fallback code when a video extension fails without a more specific cause. |
SKIPPED | — | Batch per-item only: not submitted because an earlier item failed with INSUFFICIENT_CREDITS. |
Retry guidance
- 429 — wait
Retry-Afterseconds, then retry. - 5xx / 502 — safe to retry with the same
Idempotency-Key; a charged job that fails is refunded automatically. - 4xx (other) — fix the request; retrying unchanged will fail again.