One project key
Use the same Jevrouter key for chat, images and videos. Choose the exact model in the request body.
Video model guide · Updated October 7, 2026
Choose text-to-video for a prompt, image-to-video for an image, or a reference and extension endpoint for those inputs. Flash and Pro are separate variants with separate schemas and quotes.
Use the same Jevrouter key for chat, images and videos. Choose the exact model in the request body.
Set a maximum reservation for each task and choose which models your key can access.
Retrieve progress, outputs and the settled bill. Retrying with the same idempotency key keeps the original task.
8 currently available variants. Names such as Flash, Pro, 5B and Ultra Fast identify separate variants; they are not interchangeable request parameters. Catalog capabilities below are declarations, not independent performance measurements.
Start with Wan 2.6 Text-to-Video →
| Endpoint | Task | Published options |
|---|---|---|
| Wan 2.6 · image to video Flash | Image to video | duration: 2–15 · resolution: 720p, 1080p |
| Wan 2.6 · image to video Pro | Image to video | duration: 5, 10, 15 · resolution: 1080p, 2k, 4k |
| Wan 2.6 · image to video spicy | Image to video | duration: 5, 10, 15 · resolution: 720p, 1080p |
| Wan 2.6 · image to video | Image to video | duration: 5, 10, 15 · resolution: 720p, 1080p |
| Wan 2.6 · reference to video Flash | Reference to video | duration: 5, 10 · size: 1280*720, 720*1280, 1920*1080, 1080*1920 |
| Wan 2.6 · reference to video | Reference to video | duration: 5, 10 · size: 1280*720, 720*1280, 1920*1080, 1080*1920 |
| Wan 2.6 Text-to-Video | Text to video | duration: 5, 10, 15 · size: 1280*720, 720*1280, 1920*1080, 1080*1920 |
| Wan 2.6 · video extend | Video extend | duration: 5, 10, 15 · resolution: 720p, 1080p |
Open an endpoint to see required source media, conditional rules and the full parameter schema. Supplying a prompt alone is not sufficient for an image or reference job.
USD per generated video, for the exact inputs below. Live quotes checked (UTC+8). These dated examples are not a price guarantee.
| Duration | Size | Reserve up to | Estimate |
|---|---|---|---|
| 5s | 1280 × 720 | $0.50 | $0.50 |
| 10s | 1280 × 720 | $1.00 | $1.00 |
| 5s | 1920 × 1080 | $0.75 | $0.75 |
We reserve the quoted maximum before submission, settle the confirmed generation cost and release the remainder. Set jev.max_cost_usd to bound the reservation. If the current quote exceeds that limit, generation is rejected before it starts.
The estimated charge is not a receipt. Check the settled request record for what you actually paid. Other variants and input combinations require their own quote.
This example creates one billable five-second text-to-video task with a fixed model and a reservation limit. Allow alibaba/wan-2.6/text-to-video:video on your key and load it into JEVROUTER_API_KEY. Use either the cURL or Python example for a test; running both creates separate jobs.
curl --fail-with-body https://api.jevrouter.io/v1/videos \
+ -H "Authorization: Bearer $JEVROUTER_API_KEY" \
+ -H "Content-Type: application/json" \
+ -H "Idempotency-Key: my-first-wan26-video" \
+ -d @- <<'JSON'
{
"model": "alibaba/wan-2.6/text-to-video:video",
"input": {
"prompt": "A yellow sailboat on a quiet lake",
"duration": 5,
"size": "1280*720",
"enable_prompt_expansion": false,
"shot_type": "single"
},
"jev": {
"max_cost_usd": "0.50"
}
}
JSONSave data.id. Retrieve GET /v1/videos/REQUEST_ID with the same authorization header, at least three seconds apart, until data.status is completed or failed. Completed results appear in data.outputs. Keep the same idempotency key when recovering an interrupted submission.
Python 3.10+; no extra packages. Save the script as generate_video.py and run it with your key in the environment. It persists video-task.json before submitting, then polls and saves video.mp4. Keep the state file to resume the same job; use a new JEV_VIDEO_STATE filename only for a deliberately new generation. Run one process per state file.
import json
import os
import shutil
import time
import uuid
from pathlib import Path
from urllib.error import HTTPError, URLError
from urllib.parse import quote, urlsplit
from urllib.request import Request, urlopen
API = "https://api.jevrouter.io/v1/videos"
KEY = os.environ["JEVROUTER_API_KEY"]
STATE = Path(os.environ.get("JEV_VIDEO_STATE", "video-task.json"))
# One state file per intended video. Keep it when retrying or resuming.
# Run only one copy of this script against a state file at a time.
if not STATE.exists():
with STATE.open("x") as file:
json.dump({"idempotency_key": str(uuid.uuid4()), "body": {
"model": "alibaba/wan-2.6/text-to-video:video",
"input": {
"prompt": "A yellow sailboat on a quiet lake",
"duration": 5,
"size": "1280*720",
"enable_prompt_expansion": False,
"shot_type": "single"
},
"jev": {
"max_cost_usd": "0.50"
}
}}, file)
state = json.loads(STATE.read_text())
def save():
temporary = STATE.with_name(STATE.name + ".tmp")
temporary.write_text(json.dumps(state))
temporary.replace(STATE)
def api(url, body=None):
headers = {"Authorization": "Bearer " + KEY}
if body is not None:
headers.update({"Content-Type": "application/json",
"Idempotency-Key": state["idempotency_key"]})
request = Request(url, data=json.dumps(body).encode() if body is not None else None,
headers=headers, method="POST" if body is not None else "GET")
try:
with urlopen(request, timeout=90) as response:
return response.status, json.load(response)
except HTTPError as error:
return error.code, json.loads(error.read())
except (URLError, TimeoutError):
raise SystemExit("Connection interrupted. Keep the state file and run again to resume.")
if not state.get("request_id"):
status, result = api(API, state["body"])
if status == 200:
state["request_id"] = result["data"]["id"]
else:
error = result.get("error", {})
recoverable = status in (409, 503) and error.get("code") in (
"request_already_exists", "outcome_unknown")
request_id = (error.get("details") or {}).get("request_id") or error.get("request_id")
if not recoverable or not request_id:
raise SystemExit(result)
state["request_id"] = request_id
save()
task_url = API + "/" + quote(state["request_id"], safe="")
print("Task:", state["request_id"])
deadline = time.monotonic() + 900
while time.monotonic() < deadline:
time.sleep(5)
status, result = api(task_url)
error = result.get("error", {})
if status == 429 or (status in (409, 503) and error.get("code") in (
"request_already_exists", "outcome_unknown")):
continue # Inspect the same task; never submit a replacement.
if status != 200:
raise SystemExit(result)
task = result["data"]
if task["status"] == "failed":
raise SystemExit(task.get("error") or "Video generation failed")
if task["status"] != "completed":
continue
print("Outputs:", task["outputs"])
outputs = task["outputs"]
if outputs and isinstance(outputs[0], str):
media_url = outputs[0]
parts = urlsplit(media_url)
if parts.scheme != "https" or not parts.hostname or parts.username or parts.password:
raise SystemExit("Unexpected media URL; inspect outputs manually")
# Separate media request: NEVER send your Jevrouter key to a media host.
with urlopen(media_url, timeout=120) as response, open("video.mp4", "wb") as output:
shutil.copyfileobj(response, output)
print("Saved video.mp4")
else:
print("This model returned structured outputs; inspect the printed result.")
break
else:
raise SystemExit("Still pending. Keep the state file and run again to resume.")Read the full tutorial: status, errors, billing and safe retries →
We verified live text-to-video quotes for the three parameter combinations below on October 7. We have not independently generated a Wan 2.6 video in this integration check, or benchmarked its quality, speed or audio output.
A model being listed does not mean every variant or option has been independently tested. Start with your own representative inputs before choosing on output quality.
Use the explicit model above when you need that particular variant. Use jev/auto and task: "text-to-video" when you want routing among compatible models allowed by your key. Auto must also be enabled on the project and allowed on the key.
Auto checks task type and parameter compatibility, then compares live quotes for up to eight candidates shortlisted by catalog price. It chooses within that shortlist and your limit. It does not promise the best quality or search every possible model. Model-specific input fields can narrow the compatible pool.
Read the video API contract →Closing your connection does not cancel an accepted job. The platform tracks completion and settlement independently. Results may be ready before billing finishes; inspect the request record for the confirmed charge.
Media links are retained for up to seven days and can expire earlier. Download while available and keep your own copy. Customer callbacks and task cancellation are not supported.