Best Performance & Best Value
The same model holds both recommendation positions for this capability.
Wan / Curated model
Both the performance and value recommendation for text-to-video in the supplied Arena table.
Usage-based pricing
Approximate supplied reference price per second. Resolution, duration and actual billing may vary.
Get API AccessModel capabilities
Modalities
text → video
Best fit
Video generation from written concepts
Where this model sits in the current curated selection.
The same model holds both recommendation positions for this capability.
External benchmark data, with its source and verification status.
| Functionality | Source | Score | Snapshot |
|---|---|---|---|
| Text → Video | Arena | 1476 | Supplied Arena snapshot · date pending |
Arena scores are external benchmark signals. Scores and score gaps are taken from the supplied recommendation table. The external leaderboard source and snapshot date still need confirmation. They do not describe a literal percentage difference in real-world quality.
Read the methodologyImplementation
Copy a model test, replace the API key with your own, and run.
Copy the Python or cURL test for Wan 3.0. Replace the API-key placeholder with your own key and run.
Wan 3.0 · text to video · Submits a five-second video test and polls for the resulting video URL.
import json
import time
from urllib.parse import quote
from urllib.error import HTTPError
from urllib.request import Request, urlopen
API_KEY = "YOUR_ROTEN_API_KEY"
def send(url, payload=None):
data = json.dumps(payload).encode("utf-8") if payload is not None else None
request = Request(url, data=data, headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/json"})
try:
with urlopen(request, timeout=180) as response:
return json.load(response)
except HTTPError as error:
raise SystemExit(f"HTTP {error.code}: {error.read().decode('utf-8')}")
payload = json.loads(r'''{
"prompt": "An indigo geometric shape moves slowly across a midnight navy background.",
"duration": 5,
"size": "720p",
"model": "wan3.0-video"
}''')
result = send("https://api.roten.ai/v1/video/generations", payload)
task_id = result["task_id"]
for attempt in range(120):
result = send("https://api.roten.ai/v1/video/generations" + "/" + quote(str(task_id), safe=""))
status = result.get("status")
if status == "completed":
print(result["url"])
break
if status == "failed":
raise SystemExit(json.dumps(result.get("error", result)))
if status not in ("pending", "processing"):
raise SystemExit("Unexpected task response: " + json.dumps(result))
time.sleep(5)
else:
raise SystemExit("The video is still processing. Task ID: " + str(task_id))# Requires curl and Python 3 for reading JSON responses.
set -eu
API_KEY='YOUR_ROTEN_API_KEY'
created=$(curl --fail-with-body --silent --show-error 'https://api.roten.ai/v1/video/generations' \
-H "Authorization: Bearer $API_KEY" \
-H 'Content-Type: application/json' \
--data '{
"prompt": "An indigo geometric shape moves slowly across a midnight navy background.",
"duration": 5,
"size": "720p",
"model": "wan3.0-video"
}')
task_id=$(printf '%s' "$created" | python3 -c 'import json,sys;from urllib.parse import quote;print(quote(str(json.load(sys.stdin)["task_id"]),safe=""))')
attempt=0
while [ "$attempt" -lt 120 ]; do
result=$(curl --fail-with-body --silent --show-error "https://api.roten.ai/v1/video/generations/$task_id" \
-H "Authorization: Bearer $API_KEY")
status=$(printf '%s' "$result" | python3 -c 'import json,sys;print(json.load(sys.stdin).get("status",""))')
case "$status" in
completed) printf '%s' "$result" | python3 -c 'import json,sys;print(json.load(sys.stdin)["url"])'; exit 0 ;;
failed) printf '%s\n' "$result" >&2; exit 1 ;;
pending|processing) sleep 5 ;;
*) printf '%s\n' "$result" >&2; exit 1 ;;
esac
attempt=$((attempt + 1))
done
printf 'Video still processing. Task ID: %s\n' "$task_id" >&2
exit 1Python tests use the standard library. Video cURL tests also use Python 3 to read task responses.
Built for production
Talk to us about volume pricing, model selection and migration.