Video generation

Live
Submit asynchronous video jobs and reconcile their status.
Open in ChatGPT
(opens in new tab)
Last verified: 2026-09-08

Choose a Wan 3 mode

modelrush/wan3-spicy, modelrush/wan3-pro-spicy, modelrush/wan3-prime-spicy, and modelrush/wan3-prime-pro-spicy use one asynchronous endpoint with three modes:
ModeRequired mediaUse it for
text-to-videoNoneGenerate from a prompt
image-to-videofirst_frame; optional last_frameAnimate a still or interpolate keyframes
reference-to-videoAt least one reference arrayPreserve subjects, motion, or sound from image, video, and audio references
Wan 3 accepts prompts up to 20,000 characters and a fixed duration of 2–30 whole seconds; omitting duration defaults to 5 seconds, and -1 is not available. Billing uses the requested or default duration. It supports adaptive or fixed aspect ratios and native audio; prompt expansion is available on Prime tiers only. Standard and Prime Spicy support 480P, 720P, and 1080P; Pro and Prime Pro Spicy support 1080P, 2K, and 4K. The Prime tiers trade a higher per-second rate for faster turnaround.

Submit a text-to-video job

bash
curl https://api.modelrush.ai/v1/videos/generations \
-H "Authorization: Bearer $MODELRUSH_API_KEY" \
-H "Content-Type: application/json" \
-d '{"model":"modelrush/wan3-spicy","mode":"text-to-video","prompt":"A lunar fox tracing a request across glowing regions","duration":5,"resolution":"1080P","ratio":"16:9","audio":true}'
For image-to-video, set mode to image-to-video and add first_frame plus an optional last_frame. For reference-to-video, set mode to reference-to-video and send up to 10 reference_images, 5 reference_videos, and 5 reference_audios. Reference videos must have at least 16 frames per second and total no more than 15 seconds; reference videos plus generated duration cannot exceed 30 seconds. Reference audio must total no more than 15 seconds. The API returns 202 with a generation ID and queued status.

Edit a video with Wan 2.7 Video Edit

modelrush/wan2.7-videoedit edits one source video. Send exactly one {"type":"video"} item in media (MP4 or MOV, 2–10 seconds, 240–4,096 pixels per side, aspect ratio 1:8 to 8:1, up to 100 MB) and up to 4 reference_image items (JPEG, PNG, BMP, or WebP, 240–8,000 pixels per side, 1:8 to 8:1, up to 20 MB). Omit duration or send 0 to keep the source length; 2–10 trims the output from the start and never extends the source.
Billing uses input-video seconds plus output-video seconds, measured to the millisecond. A 5.02-second source edited at full length bills 5.02 + 5.02 = 10.04 seconds; at $0.110 per second that is $1.1044, held as $1.11 because holds round up to the next whole cent. The gateway measures the source before creating the job and returns the estimate in billing on the 202 response. Settlement uses the provider-reported seconds when they are available, otherwise the authorized estimate (reported as usage_source: "estimated" in billing on the prediction), and never exceeds the hold; fewer seconds release the difference.
Register a public HTTPS endpoint with POST /webhooks/endpoints. ModelRush sends signed prediction.succeeded or prediction.failed events as soon as the asynchronous task completes. Verify the signature and deduplicate by event ID. See webhooks.
Polling remains the recovery path when webhook delivery is delayed:
bash
curl https://api.modelrush.ai/v1/videos/generations/GENERATION_ID \
-H "Authorization: Bearer $MODELRUSH_API_KEY"
Use bounded backoff until the video endpoint returns completed or failed; read video_url on success. After 24 hours, a completed job still returns completed, with video_url null and output_expired true. The unified Prediction endpoint uses succeeded and outputs. See asynchronous jobs.

Spicy model API references

Open a model page for its request parameters and current prices. The four Wan 3 landing pages include a developer API section below the Playground. Read GET /v1/models for current schemas and key-specific access; GET /api/model-pricing returns public prices without authentication; with a valid Bearer API key, it returns the prices applicable to that account.
Model and API referenceModel IDEndpoint
Wan 3 Spicymodelrush/wan3-spicyPOST /v1/videos/generations
Wan 3 Pro Spicymodelrush/wan3-pro-spicyPOST /v1/videos/generations
Wan 3 Prime Spicymodelrush/wan3-prime-spicyPOST /v1/videos/generations
Wan 3 Prime Pro Spicymodelrush/wan3-prime-pro-spicyPOST /v1/videos/generations
Wan 2.7 I2V Spicymodelrush/wan2.7-i2v-spicyPOST /v1/videos/generations
Wan 2.2 I2V Spicymodelrush/wan2.2-i2v-spicyPOST /v1/videos/generations
Wan Animate Spicymodelrush/wan-animatePOST /v1/videos/generations
FlashVSR Spicymodelrush/flashvsrPOST /v1/videos/generations
Video polling via GET /v1/videos/generations/:id ends with completed or failed and returns video_url on success. The unified GET /v1/predictions/:id instead uses succeeded and outputs. Follow the contract of the poll_url you use. Wan 3 reference-video time plus generated time cannot exceed 30 seconds. Only Prime and Prime Pro currently accept prompt_extend; check the per-model schema. LoRA supports three optional weight arrays, 480P/720P and 5/8 seconds. Wan Animate and FlashVSR use the video generation endpoint with source media. FlashVSR duration must equal the input video length rounded to the nearest whole second (minimum 1); otherwise the request fails with video_duration_mismatch (or video_duration_unverified if the video cannot be read) before any charge.
All Spicy models require adult-access confirmation on the account. API keys must permit the selected model and capability. Keep keys server-side and reuse Idempotency-Key for retries where supported. Wan Animate has the additional signed-quote and x-request-id requirements in the video documentation.

Wan Animate: confirm a signed quote before submission

For new modelrush/wan-animate requests, remove duration. The server measures the reference video, which must be longer than 0 and no longer than 30 seconds. The output follows that reference length; 5/8 seconds is not an output-length control. The quote measures the reference and reads the current price without starting a generation or reserving credits. Review billing.maximum_charge_cents (whole cents, rounded up for the task) before submitting. The final customer charge cannot exceed this confirmed maximum; unused reserved credits are released. A quote is valid for 10 minutes. Normal account, media-access and credential requirements still apply.
Public API: POST https://api.modelrush.ai/v1/videos/generations/quote, then POST https://api.modelrush.ai/v1/videos/generations. Use Authorization: Bearer with a server-side API key permitted for this model. Agent runtime: POST https://modelrush.ai/api/agent/v1/videos/generations/quote, then POST https://modelrush.ai/api/agent/v1/videos/generations. Use the Agent credential with media:write and an active Agent run, not a public API key. The quote has no generation charge; it does not waive an Agent subscription or other service requirements.
  1. Create one UUID and persist it with the exact JSON body before submission. Include model, image, video, mode (animate or replace), resolution (480P or 720P), and any optional prompt/seed/region. Do not include duration.
  2. Send that body to the selected quote route with Content-Type: application/json and x-request-id: UUID. A successful HTTP 200 response contains quote_token, request_id, expires_at and billing. Check request_id matches, then show the maximum charge for approval.
  3. Submit the same body and x-request-id to the matching generation route. Add x-modelrush-video-edit-quote: quote_token. Keep the same account, Agent run where applicable, region, source bytes and settings. Idempotency-Key does not replace this UUID or signature. Changing it cannot authorize an extra task under the same quote.
  4. Save the returned id and poll_url. Poll the returned route with its required credential. A video status route uses completed/failed; the unified prediction route uses succeeded/failed. Do not submit a second job to check progress.
Missing/invalid UUID or signature: HTTP 400 video_edit_quote_required. Expired quote, changed media/settings or changed price: HTTP 409 video_edit_quote_changed. Do not automatically accept a new maximum. Fetch a fresh quote with the same UUID and body after a definitive quote rejection, show it and confirm again. If the first submission has not been attempted and its quote expired, refresh before submitting. For a timeout, lost response or uncertain 5xx, preserve the original UUID, body and signature and retry that exact generation request once to recover its result. An already accepted matching request replays before quote expiry/media validation, so do not replace an expired token during uncertain recovery. If uncertainty remains, stop and investigate using the request ID; never switch UUID just to bypass it. HTTP 409 idempotency_conflict means the ID belongs to a different request; stop rather than overwrite it. Keep signed quotes private and do not log credentials.
Already accepted requests from before this change can replay with their original Idempotency-Key and retained body, including the old duration value. Replay returns the existing task and does not reserve or charge again. This compatibility is only for matching accepted tasks. It does not permit a new unsigned request, a changed request or a new UUID. If there is no known accepted task, migrate to the signed quote flow.
Download the runnable Node.js example at wan-animate-quoted-request.mjs. Set MODELRUSH_API_KEY for public, or MODELRUSH_AGENT_TOKEN for agent, on the server. State files contain the private quote token; keep them out of Git. The quote command never submits a generation. Replace MAX_CENTS with the displayed integer only after approval. The submit/recover commands can reserve credits and start a paid task. They make one request each and never auto-retry. refresh keeps the same UUID/body and requires a new review; use it only before the first submission or after a definitive video_edit_quote_changed response.
sh
curl --fail --output wan-animate-quoted-request.mjs https://modelrush.ai/examples/wan-animate-quoted-request.mjs
cat > wan-animate-body.json <<'JSON'
{"model":"modelrush/wan-animate","image":"https://YOUR_HOST/character.png","video":"https://YOUR_HOST/reference.mp4","mode":"animate","resolution":"480P"}
JSON
node wan-animate-quoted-request.mjs quote wan-animate-state.json wan-animate-body.json public
node wan-animate-quoted-request.mjs submit wan-animate-state.json MAX_CENTS
# recover: same saved UUID, body and token; no new task ID
node wan-animate-quoted-request.mjs recover wan-animate-state.json MAX_CENTS
# refresh: review the returned maximum again before submit
node wan-animate-quoted-request.mjs refresh wan-animate-state.json
# Agent: use a separate state file and MODELRUSH_AGENT_TOKEN
node wan-animate-quoted-request.mjs quote wan-animate-agent-state.json wan-animate-body.json agent