Discord

1. Get an API key

Create an account, verify your email, then create a key from /dashboard. It's shown once, in the form llmr_sk_live_… — store it like any other secret. New accounts start on prepaid credits — top up at /settings/credits before sending live traffic. Key format, scopes, per-key limits, and test vs. live keys: Authentication.

2. Generate a video or image

VideoRouter's flagship endpoints are video and image generation — one API in front of every open-weight model host (Fal, WaveSpeedAI, Atlas Cloud, Replicate, Novita, MachGen) plus the closed frontier models (Veo, Imagen, Grok Imagine). Video is async, job-based: POST /v1/videos to create a job, then poll GET /v1/videos/{id} for status. Billed per requested second at creation time; polling is free.

# video/image have no auto-routing — always name a real model
import requests

resp = requests.post(
    "https://videorouter.sh/api/v1/videos",
    headers={"Authorization": "Bearer llmr_sk_live_...", "Content-Type": "application/json"},
    json={"model": "minimax/h3/fal", "prompt": "a paper airplane gliding over a city", "duration_secs": 8},
)
job = resp.json()
# -> {"id": "video_...", "status": "pending", ...}

# poll
status = requests.get(
    f"https://videorouter.sh/api/v1/videos/{job['id']}",
    headers={"Authorization": "Bearer llmr_sk_live_..."},
).json()
# -> {"status": "in_progress"} then {"status": "completed", "url": "https://..."}

Image generation is synchronous instead — POST /v1/images returns the image (or a real usage.cost-carrying error) in the same request, matching OpenRouter's /api/v1/images contract. Text-to-image and image-to-image share this one endpoint — pass reference images via input_references instead of a separate edit call:

curl
curl https://videorouter.sh/api/v1/images \
  -H "Authorization: Bearer llmr_sk_live_..." \
  -H "content-type: application/json" \
  -d '{
    "model": "openai/gpt-image-1/openai",
    "prompt": "a red panda astronaut floating in space",
    "aspect_ratio": "16:9",
    "resolution": "2K"
  }'
# -> {"data": [{"b64_json": "..."}], "usage": {"cost": 0.0421, ...}}

Editing an existing image works the same way — pass the source image's URL (or a base64 data: URI) as an input_references entry alongside the edit instruction in prompt. Every model in the catalog tagged Image-to-Image accepts this — OpenAI's GPT Image family, Black Forest Labs' Kontext models, and Qwen Image Edit among them:

curl
curl https://videorouter.sh/api/v1/images \
  -H "Authorization: Bearer llmr_sk_live_..." \
  -H "content-type: application/json" \
  -d '{
    "model": "qwen/image-edit/atlas-cloud",
    "prompt": "remove the freckles from her face",
    "input_references": [
      {"image_url": {"url": "https://example.com/portrait.jpg"}}
    ]
  }'
# -> {"data": [{"url": "https://..."}], "usage": {"cost": 0.0315, ...}}

Full parameter reference, model catalogs, and pricing: Video generation · Image generation. Upscaling an existing video or image (no prompt needed) works the same way, on the same endpoints: Video upscaling · Image upscaling.

3. Chat completions still work

The same key also serves an OpenAI-compatible POST /v1/chat/completions — point any existing OpenAI SDK at our base_url and swap the key, no new client library needed. Setting model:"auto" lets our router pick the cheapest text model that clears the quality bar for your prompt; pinning an explicit model id skips the router entirely.

curl
# model:"auto" — VideoRouter picks the cheapest model that fits
curl https://videorouter.sh/api/v1/chat/completions \
  -H "Authorization: Bearer llmr_sk_live_..." \
  -H "content-type: application/json" \
  -d '{
    "model": "auto",
    "messages": [{"role": "user", "content": "Write a Python web scraper"}]
  }'

Auto-routing modes, the OpenAI SDK example, and streaming: Chat completions.

Choosing a model

Browse /models to find a model and copy its id, or fetch the full, current list at GET /v1/models. Chat model ids are creator/model (e.g. anthropic/claude-opus-4.8). Video/image ids are the same shape — "minimax/h3" — and by default automatically pick whichever host is cheapest right now, with fallback across every host confirmed to serve that checkpoint. Append a host to prefer one without giving up that fallback: "minimax/h3/fal" tries Fal first, still falls back to the rest of the pool if Fal itself errors — see Provider selection. Every model, explicit or auto-routed, is billed the same way: provider list price plus a flat 2.5% platform fee across every mode — see /pricing.

Not sure which chat model to pick? Leave model:"auto" — the router predicts what your query needs (reasoning, code, tools, vision, context length) and picks the cheapest model in the catalog that meets it. Every deployment also carries automatic provider failover, so a single upstream outage doesn't fail your request. Video and image generation have no auto-router at all — pick a model id from the catalog directly (model:"auto" on /v1/videos just defaults to machgen/minimax-h3 every time, no routing decision made).

Errors & rate limits

Errors are OpenAI-shaped: {"error": {"message", "type", ...}}.

Status Meaning
401missing, invalid, or expired API key
402prepaid credit balance is ≤ $0, or your key's monthly spend cap is reached — top up at /settings/credits
429per-key RPM/TPM limit hit — a Retry-After header tells you how long to back off

A retryable upstream failure (timeout, 429, or 5xx from the provider) doesn't reach you as an error — the gateway automatically walks the ordered fallback list for that model first. You only see an error if every candidate fails.

Next steps