CloseRouter

Video API

Video generation is asynchronous: create a task, wait for completion, then download the result. Use the same API key throughout.

1. Choose a model

Find the operation and its supported duration, resolution and aspect ratio. Replace YOUR_VIDEO_MODEL_ID and the example parameters with values from the catalog.

curl
curl https://api.closerouter.dev/v1/videos/models \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY"

2. Check the price

This request neither generates video nor charges you. Save max_cost_usd from the response. To pin an option, use the same provider.option_id in the quote and generation.

curl
curl https://api.closerouter.dev/v1/videos/quote \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "YOUR_VIDEO_MODEL_ID",
  "prompt": "A slow camera move over a mountain lake",
  "duration": 5,
  "aspect_ratio": "16:9"
}'

3. Create a task

Replace MAX_COST_FROM_QUOTE with the quoted amount and use the same parameters. Another POST creates a new generation.

curl
curl https://api.closerouter.dev/v1/videos \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "model": "YOUR_VIDEO_MODEL_ID",
  "prompt": "A slow camera move over a mountain lake",
  "duration": 5,
  "aspect_ratio": "16:9",
  "max_cost_usd": "MAX_COST_FROM_QUOTE"
}'

Task accepted — HTTP 202

Abbreviated response. Save id for the next steps.

JSON
{
  "id": "TASK_ID",
  "status": "pending",
  "polling_url": "https://api.closerouter.dev/v1/videos/TASK_ID"
}

4. Check progress

Replace TASK_ID with the returned ID. While the task is unfinished, poll its status instead of submitting another generation.

curl
curl https://api.closerouter.dev/v1/videos/TASK_ID \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY"

Completed result

Abbreviated example with an illustrative amount. usage.cost is the final USD cost when available in the response.

JSON
{
  "id": "TASK_ID",
  "status": "completed",
  "unsigned_urls": [
    "https://api.closerouter.dev/v1/videos/TASK_ID/content?index=0"
  ],
  "usage": {
    "cost": 0.15
  }
}

5. Download the file

The unsigned_urls links require authentication: use a key belonging to the task’s account. The zero-based index selects an output.

curl
curl https://api.closerouter.dev/v1/videos/TASK_ID/content?index=0 \
  -H "Authorization: Bearer $CLOSEROUTER_API_KEY" \
  --output video.mp4

Task states

StatusAction
pendingAccepted; keep polling.
in_progressProcessing; do not submit a new POST.
completedDownload the authenticated result.
failedRead error before taking another action.

Extend, upscale and edit

Check operation and source support for the selected provider. Each action creates a new task. Quote each action at /videos/quote first, then submit the same parameters and returned max_cost_usd to /videos.

Extend a video

Quote request body. Use your own completed task and parameters supported by the operation.

JSON
{
  "model": "YOUR_VIDEO_MODEL_ID",
  "operation": "extend",
  "video": {
    "id": "SOURCE_TASK_ID",
    "index": 0
  },
  "prompt": "Continue the camera movement",
  "duration": 5
}

Upscale a video

Quote request body. Use your own completed task and parameters supported by the operation.

JSON
{
  "model": "YOUR_VIDEO_MODEL_ID",
  "operation": "upscale",
  "video": {
    "id": "SOURCE_TASK_ID",
    "index": 0
  },
  "resolution": "1080p"
}

Edit a video

Quote request body. Use your own completed task and parameters supported by the operation.

JSON
{
  "model": "YOUR_VIDEO_MODEL_ID",
  "operation": "edit",
  "video": {
    "id": "SOURCE_TASK_ID",
    "index": 0
  },
  "prompt": "Make the scene snowy"
}

Sources and restrictions

Use video: {"url": "https://example.com/source.mp4"} instead of video.id when the operation supports an external source. For extension, duration is the number of added seconds. extend and edit require prompt; upscale requires resolution.

Do not send input, native provider fields, provider.options or callback_url. Chat Completions does not generate video; analyzing video input is a separate text-model capability.

Uncertain outcome

If the response includes closerouter.reconciliation_pending, the final outcome is still being reconciled. Keep the task ID and poll its status; submitting again may create a separate paid task.