Introduction
Wan 2.5 Image to video turns the still you send in image_url into a 5- or 10-second clip with sound. The image decides subject, wardrobe, set, light direction and the clip's proportions; the optional prompt, up to 1,500 characters, describes what happens after it. There is no aspect-ratio field on this endpoint, so crop the image to the delivery shape before sending it. With only a written idea and no still, use the text-led endpoint instead.
Choose a Wan 2.5 mode by starting material
| What you have at the start | Mode |
|---|---|
| a written scene or script | Wan 2.5 Text to video |
| an approved opening image | Wan 2.5 Image to video |
Key features & highlights
The opening frame carries the look
image_url accepts JPEG, PNG, BMP or WebP up to 20 MB, with each side between 240 and 8,000 pixels. Anything already visible in that file, such as a label, a silhouette or a costume, does not need describing again, so the prompt can spend its words on motion, camera and sound.
Audio generated with the picture, or timed to your track
Every clip returns with sound generated alongside the picture. Add audio_url, a WAV or MP3 of 3 to 30 seconds and up to 15 MB, when a recorded line or music cue should set the timing: the face comes from the frame and the mouth timing from the audio. A track longer than the clip is cut at the end; a shorter one leaves the remainder silent.
Two lengths and three resolutions
duration_seconds is exactly 5 or 10, and resolution is 480p, 720p (the default) or 1080p. Higher tiers cost more per second and take longer to return. Short clips hold hands and hair better, so settle the motion at five seconds before committing to ten.
Request parameters
| Parameter | Required | Description |
|---|---|---|
image_url | Yes | The opening frame. Subject, wardrobe, set, light direction and the clip's proportions all come from it, so crop it first. at least 1 characters |
prompt | No | Optional. What happens after the frame: one action, one camera behaviour, a line about sound. at most 1500 characters |
negative_prompt | No | What must not appear: a second person, captions, a prop the frame keeps bringing back. Up to 500 characters, so keep it to a short list. at most 500 characters |
resolution | No | 480p, 720p or 1080p, default 720p. Higher tiers cost more per second and take longer to return. |
duration_seconds | No | Exactly 5 or 10. Short clips hold hands and hair better, so settle the look at five first. |
audio_url | No | A voice line or music cue for the clip to follow, so speech and beats land where you expect. WAV or MP3, 3 to 30 seconds and up to 15 MB. at least 1 characters |
enable_prompt_expansion | No | Off by default. Turn it on for a one-line idea; leave it off when the prompt is already a precise action. Default: |
seed | No | 0 to 2147483647. Fix it when comparing resolution or length from the same frame; for a random draw, leave the field out rather than sending 0. |
Pricing
| Specification | Price |
|---|---|
| $0.045 / second |
| $0.09 / second |
| $0.135 / second |
Use cases
Product motion from one packshot
The published serum-bottle example sends a product still and asks only for a slow quarter-turn camera arc while a band of window light slides across the glass; the bottle itself does not move. Because the frame already fixes label and silhouette, the prompt carries only light and motion, rendered at 720p for five seconds.
A portrait that speaks a recorded line
Send an approved portrait as image_url and the voice line as audio_url. The person's appearance comes from the image and the mouth timing from the file, so the review is about delivery rather than lip sync.
A longer studio take with guarded details
The slip-dress example runs ten seconds at 1080p from a studio portrait: a weight shift, a turn toward the lens and two slow steps under a locked camera. Its negative prompt, "extra people, text, jewellery changes", stops accessories from changing and extra figures from appearing over the longer duration.
Rain, water and other sound with a visible source
In the umbrella example, two figures stay nearly still while rain drums on the umbrella above them, so the motion belongs to the water and the sound has a source you can see. When the event is continuous like this, five seconds is usually enough.
Prompt guide & pro tips
Prepare the frame first
Crop to the delivery shape and check that the image already shows the wardrobe, set and light you want. The clip keeps the image's proportions and inherits its look, so a mistake in the still carries straight into the video.
Describe only the motion
The prompt is optional, but one clear action line gives far steadier motion. Write one action, one camera behaviour and a note on sound. Put anything the frame keeps bringing back, such as a second person, captions or a prop, into negative_prompt. Turn enable_prompt_expansion on for a one-line idea and leave it off when the prompt is already a precise action.
Adapt the included example
Start from the published example at duration_seconds 5 and resolution 720p, with your own publicly accessible image in image_url.
The camera arcs a slow quarter turn around the dropper bottle while a soft band of window light slides across the glass and the liquid inside catches it. The bottle itself does not move. Quiet room tone, no music.
The frame fixes the label and silhouette; the prompt asks only for a camera arc and moving light.
Compare takes with a fixed seed
Fix seed when comparing resolution or length from the same frame, and change one field per run. For a random draw, leave the field out rather than sending 0. Play the full clip with sound before delivery.
API quick start
# Generate the idempotency key once; reuse it when retrying after a lost response.
export SPICY_IDEMPOTENCY_KEY="${SPICY_IDEMPOTENCY_KEY:-$(uuidgen)}"
curl -X POST https://api.spicyapi.ai/api/v1/jobs/createTask \
-H "Authorization: Bearer $SPICY_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $SPICY_IDEMPOTENCY_KEY" \
-d '{
"model": "alibaba/wan-2.5/image-to-video",
"input": {
"duration_seconds": 5,
"image_url": "https://example.com/reference.png",
"resolution": "720p"
}
}'
# Copy data.taskId from the response into TASK_ID, then poll the status.
TASK_ID="TASK_ID_FROM_RESPONSE"
curl "https://api.spicyapi.ai/api/v1/jobs/recordInfo?taskId=$TASK_ID" \
-H "Authorization: Bearer $SPICY_API_KEY"
See the API reference for authentication, the complete schema, polling, and error handling.




























