Video Generation
Generate short AI videos from text prompts or a starting image using veo-3.1-lite. Billed at $0.017 per second. An 8-second clip costs $0.136.
Overview
The Video API generates short clips (4, 6, or 8 seconds) from natural-language prompts. Choose text-to-video (t2v) for purely prompt-driven generation, or image-to-video (i2v) to animate a starting image.
Pricing is $0.017 per second. There is no daily generation cap — only your balance limits usage.
| Duration | Cost |
|---|---|
| 4 seconds | $0.068 |
| 6 seconds | $0.102 |
| 8 seconds | $0.136 |
Generation Modes
t2v — Text to Video
Generate a video purely from a text prompt. The model synthesizes motion, scene, and style from your description. start_image must not be provided.
i2v — Image to Video
Animate a starting image guided by the text prompt. Provide start_image as either a data URL (data:image/jpeg;base64,...) or an https:// URL. HTTP and private-range URLs (localhost, 192.168.x.x, etc.) are rejected. Max payload: 4 MB.
// Image-to-video: animate a starting frame
const response = await fetch("https://getvrex.com/api/v1/videos", {
method: "POST",
headers: {
"Authorization": "Bearer sk-your-api-key",
"Content-Type": "application/json",
},
body: JSON.stringify({
prompt: "The figure slowly raises their hand, cinematic",
seconds: 4,
mode: "i2v",
start_image: "https://your-cdn.com/starting-frame.jpg",
// or: start_image: "data:image/jpeg;base64,/9j/4AAQ..."
}),
});r2v — Reference to Video ("Ingredients")
Condition the video on 1–3 reference images via ref_images (data URL or https:// URL, max 4 MB each). start_image must not be provided. Always renders an 8 s clip — seconds is normalized to 8.
Quick Start
# Text-to-video (t2v)
curl -X POST https://getvrex.com/api/v1/videos \
-H "Authorization: Bearer sk-your-api-key" \
-H "Content-Type: application/json" \
-d '{
"prompt": "A drone shot of a coastal city at golden hour",
"seconds": 8,
"mode": "t2v"
}'
# Poll for completion
curl https://getvrex.com/api/v1/videos/{id} \
-H "Authorization: Bearer sk-your-api-key"Generation typically takes 30–120 seconds depending on duration and GPU load. Poll every 3–5 seconds or use webhooks for zero-latency notification.
API Reference
/videosSubmit an async video generation job.
Request Body
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
| prompt | string | Required | — | Text description of the video to generate. 1–2000 characters. |
| seconds | number | Optional | 8 | Duration of the generated video. One of: 4, 6, 8 (t2v/i2v). r2v is always 8 s — any value is normalized to 8. |
| mode | string | Optional | t2v | "t2v" (text-to-video), "i2v" (image-to-video, requires start_image), or "r2v" (reference-to-video / "Ingredients", requires ref_images). |
| start_image | string | Optional | — | Required when mode="i2v" (forbidden otherwise). A data URL ("data:image/jpeg;base64,...") or an HTTPS image URL. Max 4 MB. Private-range URLs are rejected. |
| ref_images | string[] | Optional | — | Required when mode="r2v" (1–3 items; forbidden otherwise). Each item a data URL or HTTPS image URL, max 4 MB. Private-range URLs are rejected. |
| size | string | Optional | 1280x720 | Output resolution. One of: "1280x720", "720x1280", "1920x1080". |
| model | string | Optional | veo-3.1-lite | Model to use. Currently fixed to "veo-3.1-lite". |
| webhook_url | string | Optional | — | HTTPS URL to receive video.completed and video.failed events. |
| output_format | string | Optional | url | Response shape for the video URL. One of: "url" (presigned), "raw_key" (R2 object key). |
Response (202 Accepted)
{
"id": "vg_a1b2c3d4e5f6",
"status": "queued",
"estimated_cost_usd": 0.136,
"queue_position": 1,
"poll_url": "/api/v1/videos/vg_a1b2c3d4e5f6"
}Errors
| Code | Status | Description |
|---|---|---|
| VALIDATION_ERROR | 400 | Invalid request — missing prompt, invalid seconds, bad size, or a mode/image mismatch (e.g. i2v without start_image) |
| MINOR_SAFETY / ARTIST_IMPERSONATION / HATE_SPEECH | 400 | Prompt blocked by the acceptable-use policy (one of these specific codes) |
| INSUFFICIENT_BALANCE_FOR_VIDEO | 402 | Insufficient balance. Please top up your account. |
| WALLET_NOT_FOUND | 404 | No billing wallet exists yet for the account (top up to initialise) |
| QUEUE_FULL | 429 | Video generation queue at capacity (sends Retry-After) |
| DAILY_CAP_REACHED | 429 | Per-tier daily video cap reached (resets midnight UTC) |
| UPLOAD_ERROR / CREDIT_ERROR / INTERNAL_ERROR | 500 | Failed to process an input image, charge, or create the job |
| FEATURE_DISABLED | 503 | Video generation is temporarily disabled |
/videos/:idPoll the status of a video generation job.
Response
{
"id": "vg_a1b2c3d4e5f6",
"status": "completed",
"seconds": 8,
"actual_seconds": 8,
"mode": "t2v",
"size": "1280x720",
"model": "veo-3.1-lite",
"video_url": "https://r2.getvrex.com/video-gen/...",
"cost_usd": 0.136,
"actual_cost_usd": 0.136,
"error": null,
"created_at": "2025-01-01T12:00:00.000Z",
"completed_at": "2025-01-01T12:01:15.000Z"
}Possible statuses: pending, queued, processing, completed, failed
video_url is a presigned download URL for the MP4 (valid 1 hour). null until status is completed.
Webhook Event
Set webhook_url in the POST request to receive video.completed and video.failed events. Your server must respond with 2xx within 10 seconds. Note: webhook field names differ from the GET response (video_gen_id, duration_sec, actual_cost_usd; no status/mode).
{
"event": "video.completed",
"video_gen_id": "vg_a1b2c3d4e5f6",
"video_url": "https://r2.getvrex.com/video-gen/...",
"duration_sec": 8,
"actual_cost_usd": 0.136,
"timestamp": "2025-01-01T12:01:15.000Z"
}{
"event": "video.failed",
"video_gen_id": "vg_a1b2c3d4e5f6",
"error": "NonRetryable: Engine reported failure for jobId=…",
"timestamp": "2025-01-01T12:01:15.000Z"
}FAQ
How long does video generation take?
Generation typically takes 30–120 seconds depending on duration, mode, and GPU load. i2v jobs may be slightly faster than t2v for short clips.
What image formats are accepted for i2v?
JPEG, PNG, and WebP via data URL (data:image/jpeg;base64,...) or an https:// URL. The image must be under 4 MB. HTTP URLs and private-range addresses (localhost, RFC-1918) are rejected.
Are failed generations refunded?
Yes. Balance is automatically refunded for any failed generation.
How long are video URLs valid?
Presigned URLs expire after 1 hour. Re-fetch job status to get a fresh URL.