Errors
Errors
Handle stable HTTP statuses and machine-readable error codes without exposing secrets or raw internal failures.
By Wilson Sik Founder, Reviral Last updated
HTTP status codes
- 400
- Malformed JSON or invalid full-render body
- 401
- Missing, invalid, or revoked key
- 402
- Insufficient credits
- 404
- Model or owned job not found
- 409
- Price lock changed or idempotency key conflict
- 413
- file_too_large or conversation_too_large
- 415
- unsupported_type: only JPG, PNG, WebP, MP4, MP3, and WAV are accepted
- 422
- validation_error; reference failures use details[].code = invalid_reference, reference_image_count, reference_image_required, reference_image_size, reference_video_count, reference_video_size, reference_video_too_long, reference_video_unsupported, reference_audio_count, reference_audio_needs_visual, reference_audio_size, or reference_audio_unsupported
- 422
- content_refused: the model's content rules refused this request. Change the prompt or the reference images; the same request is usually refused again. error.creditsCharged is 0 once your credits are returned.
- 429
- Rate limit exceeded; read Retry-After
- 502
- Generation, upload storage, or status service unavailable
- 503
- Catalog or rate limiter temporarily unavailable
- 504
- Start timed out; retry with the same idempotency key and body
Error envelope
Every endpoint except the five listed below returns this shape on error.
{
"error": {
"code": "validation_error",
"message": "Request validation failed",
"details": [
{
"field": "durationSec",
"message": "Duration is not available for this model.",
"code": "invalid_choice"
}
]
},
"docs": "/docs/api"
}When a charged image job fails (422 content_refused or 502 generation_failed from generate-media or image-ads), the error also carries jobId, the job you can check with GET /api/v1/jobs/{id}, and creditsCharged, the credits it still holds: 0 once your credits were returned. Reusing that request's Idempotency-Key returns this same answer; send a new key to try again.
Legacy envelope (render, characters, media-search)
POST /api/v1/render's own key check, and every response from GET/POST /api/v1/characters, GET/DELETE /api/v1/characters/{id}, and POST /api/v1/media-search, use this older shape instead: an ok: false flag, a short string error code, an optional human-readable message or detail, and the same docs field.
{
"ok": false,
"error": "invalid_body",
"message": "name: Required",
"docs": "https://reviral.ai/api/v1/render"
}Operational updates
Check API status before escalating a temporary 502 or 503.