Errors carry an error code, a human message, and a next field telling you the recommended remediation. Build your retries and fallbacks against error — never parse message for branching.
The error shape
HTTP 403
{
"error": "MODEL_NOT_ALLOWED",
"message": "This model isn't enabled for your account.",
"next": "Email sales@getvivix.com to request access — we typically respond within 24h.",
"model": "video-cinematic-4k",
"request_id": "req_abc123xyz"
}
Always pass request_id when you write to support — it lets us pull up your exact log line in seconds instead of digging through traces. Every error has one.
Error codes
Auth · 401 / 403
Code
When
What to do
401 UNAUTHORIZED
Missing or malformed Authorization header.
Add Authorization: Bearer vvx_live_…. Make sure there's no quote/whitespace around the token.
401 KEY_INVALID
The key doesn't exist in our records.
Generate a new key in Settings → API. The old one was probably revoked or never existed.
401 KEY_REVOKED
The key was revoked by the user (you, or your admin).
Generate a new one. Revocation is permanent.
403 TIER_LOCKED
API access requires Pro or Ultimate. Your account is on Free or Standard.
You're over your per-minute call limit (Pro 240, Ultimate 600).
Back off. Read Retry-After header (in seconds) and retry after that. Long-term: batch where possible or upgrade tier.
429 CONCURRENCY_LIMIT
Too many in-flight jobs at once (Pro 5, Ultimate 20).
Wait for one of your in-flight generations to finish, then retry.
Server · 5xx
Code
When
What to do
500 INTERNAL_ERROR
Something went wrong on our side.
Retry with exponential backoff (start at 1s, double each time, max 30s). Capture the request_id for support.
503 PROVIDER_DOWN
The underlying model provider is having an outage.
Retry after 60s. We mirror most popular models across providers — falling back may take a few minutes if a major provider is down.
Recommended patterns
Idempotent retries. Generation requests are safe to retry — if the original succeeded, the retry creates a brand-new generation (and you pay twice). If you need true idempotency, dedupe on your side using a request hash before calling.