Build
Video API
Turn a text prompt into an MP4: create a video, poll it, then download it.
1. Create a video
Set MINIROUTER_API_KEY to a funded API key. This starts a 4-second clip, holds credit and saves its id.
curl --fail-with-body --retry 0 https://api.minirouter.sh/v1/videos \
-H "Authorization: Bearer $MINIROUTER_API_KEY" \
-H "Content-Type: application/json" \
--data '{
"model": "google/veo-3.1-lite-generate-001",
"prompt": "A paper boat drifting down a rainy street at dusk",
"seconds": 4,
"size": "1280x720"
}' | tee video.json
VIDEO_ID=$(jq -r .id video.json)2. Poll until it finishes
Repeat every 10 seconds until status is completed or failed.
curl --fail-with-body https://api.minirouter.sh/v1/videos/$VIDEO_ID \
-H "Authorization: Bearer $MINIROUTER_API_KEY"3. Download the MP4
Downloads are free for 24 hours after completion.
curl --fail-with-body https://api.minirouter.sh/v1/videos/$VIDEO_ID/content \
-H "Authorization: Bearer $MINIROUTER_API_KEY" \
--output video.mp4Use the OpenAI SDK
Point the client at MiniRouter and turn off retries: a retried create starts a second video.
// npm install openai@7.4.0
import OpenAI from 'openai';
import { writeFile } from 'node:fs/promises';
import { setTimeout as sleep } from 'node:timers/promises';
const client = new OpenAI({
baseURL: 'https://api.minirouter.sh/v1',
apiKey: process.env.MINIROUTER_API_KEY,
maxRetries: 0,
});
let video = await client.videos.create({
model: 'google/veo-3.1-lite-generate-001',
prompt: 'A paper boat drifting down a rainy street at dusk',
seconds: '4', size: '1280x720',
});
while (video.status === 'queued' || video.status === 'in_progress') {
await sleep(10_000);
video = await client.videos.retrieve(video.id);
}
if (video.status === 'failed') throw new Error(video.error?.message);
const content = await client.videos.downloadContent(video.id);
await writeFile('video.mp4', Buffer.from(await content.arrayBuffer()));# pip install openai==2.53.0
import os
from openai import OpenAI
client = OpenAI(
base_url='https://api.minirouter.sh/v1',
api_key=os.environ['MINIROUTER_API_KEY'],
max_retries=0,
)
video = client.videos.create_and_poll(
model='google/veo-3.1-lite-generate-001',
prompt='A paper boat drifting down a rainy street at dusk',
seconds='4',
size='1280x720',
poll_interval_ms=10_000,
)
if video.status == 'failed':
raise RuntimeError(video.error.message)
client.videos.download_content(video.id).write_to_file('video.mp4')Only create, retrieve and download are supported. Values from video.controls work even where the SDK types omit them; TypeScript needs a cast.
Choose a model
Text-to-video models in the live catalog. Open a model for its full price table, or copy its ID.
17 models for text to video
Alibaba
- Wan v2.5 Text-to-Video Preview480p, 720p, 1080p · 5 or 10 seconds · from $0.0525/s
alibaba/wan-v2.5-t2v-preview - Wan v2.6 Text-to-Video720p, 1080p · 2–15 seconds · from $0.105/s
alibaba/wan-v2.6-t2v - Wan v2.7 Text-to-Video720p, 1080p · 2–15 seconds · from $0.105/s
alibaba/wan-v2.7-t2v
ByteDance
- Seedance v1.0 Pro480p, 720p, 1080p · 2–12 seconds · from $0.025515/s
bytedance/seedance-v1.0-pro - Seedance v1.0 Pro Fast480p, 720p, 1080p · 2–12 seconds · from $0.010185/s
bytedance/seedance-v1.0-pro-fast - Seedance v1.5 Pro480p, 720p, 1080p · 4–12 seconds · audio · from $0.012705/s
bytedance/seedance-v1.5-pro
- Veo 3.1720p, 1080p, 4K · 4, 6 or 8 seconds · audio · from $0.21/s
google/veo-3.1-generate-001 - Veo 3.1 Fast Generate720p, 1080p, 4K · 4, 6 or 8 seconds · audio · from $0.105/s
google/veo-3.1-fast-generate-001 - Veo 3.1 Lite Generate720p, 1080p · 4, 6 or 8 seconds · audio · from $0.0315/s
google/veo-3.1-lite-generate-001
Kling AI
- Kling v2.5 Turbo Text-to-Video720p, 1080p · 5 or 10 seconds · from $0.0441/s
klingai/kling-v2.5-turbo-t2v - Kling v2.6 Text-to-Video720p, 1080p · 5 or 10 seconds · audio · from $0.0441/s
klingai/kling-v2.6-t2v - Kling v3.0 Text-to-Video720p, 1080p · 3–15 seconds · audio · from $0.1764/s
klingai/kling-v3.0-t2v
MiniMax
- MiniMax H3768p, 2K · 4–15 seconds · from $0.084/s
minimax/minimax-h3 - MiniMax H3 Max480p, 768p · 5–15 seconds · from $0.0525/s
minimax/minimax-h3-max
xAI
- Grok Imagine480p, 720p · 1–15 seconds · from $0.0525/s
spacexai/grok-imagine-video - Grok Imagine Video 1.5480p, 720p, 1080p · 1–15 seconds · from $0.084/s
spacexai/grok-imagine-video-1.5 - Grok Imagine Video 1.5 Lite480p, 720p, 1080p · 1–15 seconds · from $0.021/s
spacexai/grok-imagine-video-1.5-lite
List models in code
Video models are the GET /v1/models entries with "type": "video".
curl -s https://api.minirouter.sh/v1/models | jq '.data[]
| select(.type == "video")
| {id, controls: .video.controls, prices: .video.pricing.prices}'- video.controls.sizes
- Accepted
sizevalues, each with a pricetierandaspect_ratio. - video.controls.seconds
- Accepted durations.
- video.controls.audio
trueif the model can add sound.- video.controls.max_
prompt_ chars - Longest accepted prompt.
- video.pricing.prices
usd_per_secondbytierandaudio.
Request body
- model
- Required. A video model
id. - prompt
- Required. Up to
max_prompt_charscharacters. - seconds
- Required. One of
video.controls.seconds, as a number or string. - size
- Required. One of
video.controls.sizes, such as1280x720. - audio
- Optional, default
false.trueadds sound where the model supports it, at the audio price.
Send JSON or multipart fields, up to 256 KiB. Video is text to video only: image_url, file parts and any other field return 400.
Read the status
Create and poll return the video object. cost is a MiniRouter extension.
{
"id": "req_5f2c9e8a1b7d4c3e9f6a0b2d8c4e1f7a",
"object": "video",
"model": "google/veo-3.1-lite-generate-001",
"status": "in_progress",
"progress": 50,
"created_at": 1793145600,
"completed_at": null,
"expires_at": null,
"seconds": "4",
"size": "1280x720",
"error": null,
"cost": {
"status": "pending",
"usd": null
}
}Video status
- queued
- Accepted, not started yet.
- in_
progress - Generating.
progressis 0 while queued, 50 while generating and 100 when completed. - completed
- Ready to download until
expires_at. - failed
errorsays why. Nothing is charged.
Cost status
- pending
- Credit is held.
usdisnull.A completed video stays pending until the provider reports its cost. - settled
usdis the final charge.- released
- The hold was returned.
usdis"0".
Pricing and holds
Prices are per second of output, by size tier and audio, and include MiniRouter's 5% fee.
- 01HoldThe extra second covers clips that run long. The minimum hold is $0.00002.At create: (
seconds+ 1) × the per-second price. - 02GenerateA failed or cancelled video releases the hold.
- 03SettleWhat the provider bills, at the listed price and never more than the hold. The rest returns.
For example, 4 seconds at $0.0315 a second holds $0.1575. If the provider bills 4 seconds, you pay $0.126 and $0.0315 returns.
Video is paid from credit; provider keys (BYOK) are not used. Key spend limits apply to the hold.
Limits
- Hours content is kept after completion
- 24
- Videos in progress per account
- 2
- Minutes before a running video is cancelled
- 45
- Charged for a failed video
- $0
A video counts toward the 2 until its cost settles. Polls and downloads count toward your key's rate limit. Only the account that created a video can read it.
Errors
invalid_request- 400. A field is missing, unsupported or not in
video.controls, or the provider refused the prompt. Nothing is charged. insufficient_credits- 402. Your balance cannot cover the hold.
rate_limited- 429. Too many requests on this key, polls included.
videos_unavailable- 503. Video is paused, or your account already has 2 videos in progress. Nothing is charged.
video_capacity- 503. Provider or download capacity is full. Retry after
Retry-After. video_request_failed- 502. The create was not confirmed and may still run. Its
x-minirouter-request-idis the videoid: poll it before creating another. video_not_found- 404. No video with this
idon your account. video_not_ready- 409. Not completed yet. Failed videos have no content.
video_expired- 410. More than 24 hours since completion.
video_content_unavailable- 502. The download failed. Retry; downloads are free.
Other codes are in Errors.