Introduction
LTX 2.5 Image to video animates an opening frame you supply for 5 to 20 whole seconds at 720p, 1080p, 2K or 4K. image_url and prompt are required; last_image_url adds an optional closing frame, and duration_seconds, resolution and seed behave as they do on Text to video. There is no aspect_ratio field: the opening frame fixes subject and composition and sets the output shape. Clips come back with a generated soundtrack and tasks run asynchronously. Upload only frames you are authorised to use; you are responsible for how the output is used.
Choose a LTX 2.5 mode by starting material
| What you have at the start | Mode |
|---|---|
| a written scene or script | LTX 2.5 Text to video |
| an approved opening image | LTX 2.5 Image to video |
Key features & highlights
The opening frame is followed closely
Identity, wardrobe, set and light come from image_url, and that frame is followed closely. It is the reliable route to a literal result: an uncensored opening frame comes back literal rather than softened. Because the image already carries the look, the prompt only has to carry what changes after it.
An optional frame for where the shot lands
last_image_url fixes the final composition and is valid only alongside image_url. It constrains the ending, not the route: the motion between the two frames is still generated, and across a long clip the middle can wander a long way. Two frames that disagree on light or wardrobe produce a visible negotiation between them, so prepare them as a continuous pair.
The same length, resolution and sound as the text endpoint
duration_seconds runs from 5 to 20 whole seconds, and longer clips wander further from a supplied closing frame. resolution offers 720p (default), 1080p, 2k (about 2560 px wide) and 4k. The output includes a generated audio track with no field to disable it, so plan to mute or replace it in the edit when you need your own mix.
Request parameters
| Parameter | Required | Description |
|---|---|---|
prompt | Yes | Required. Describe what changes after the frame - action, camera, light - not the frame itself. at least 1 characters |
image_url | Yes | The opening frame. It fixes subject and composition and sets the output shape. |
last_image_url | No | Optional closing frame, valid only alongside |
resolution | No | 720p, 1080p, 2k or 4k. 2k comes back about 2560 px wide. |
duration_seconds | No | Whole seconds, 5 to 20. Longer clips wander further from a supplied closing frame. |
seed | No | Hold it constant when you step up the resolution so only one variable has changed. |
Pricing
| Specification | Price |
|---|---|
| $0.09 / second |
| $0.13 / second |
| $0.19 / second |
| $0.30 / second |
Use cases
A time-of-day transition between two approved frames
In the beach-to-bonfire example, image_url shows a couple on the beach at sunset and last_image_url shows the same two at night, wrapped in one blanket by a bonfire. The request runs 10 seconds at 1080p, and the prompt describes the passage rather than the destination: the sun going down and the firelight taking over. Pinning the ending lets the model invent the middle without drifting past a frame that is already approved.
Board-to-board shots for an edit
When a shot has to start on one storyboard frame and end on another, send both as image_url and last_image_url. The outgoing composition then matches the next cut, which is what makes a generated clip usable in a timeline instead of only as a standalone piece.
Motion added to a finished still
The candlelit-tub frame already holds the candles, the enamel and the wet emerald silk, so its prompt covers only the change: sinking into the water, hands dragged through soaked hair, eyes opening toward the camera. The deco-pool-backfall example is a physics beat instead, a backwards fall into water with rising bubbles and caustics crawling over the columns while the camera sinks along.
Prompt guide & pro tips
Describe what changes, not what is already there
Everything visible in the opening frame is set by the image. Spend the prompt on who moves, in which direction and how fast, then on the camera and any change in light. The candlelit-tub prompt starts with the first action ("She pushes up off the rim of the tub") and ends on "Slow drift-in, warm candle light only".
Name the landing when you send a closing frame
With last_image_url, say in the prompt that the shot ends on the supplied final frame and describe what happens on the way there. The bonfire brief does exactly this: "Begin on the two of them on the beach at sunset and end on the supplied final frame". Keep subject, wardrobe and light continuous between the two images before you write anything.
Scale duration to the distance travelled
The single-action examples run 5 seconds; the sunset-to-night transition uses 10. Start with a short clip and review subject, edges, light and camera continuity across the whole output before lengthening it. Scrub water shots such as the pool example frame by frame, because water is where an animated still usually falls apart.
Direct the sound and lock the seed
Because audio is always generated, write the sound into the prompt: the pool brief asks for "no music, only muffled underwater tone". When the motion is right, keep seed and the prompt fixed and raise only resolution. The seed makes runs comparable, not frame-identical, so check the final render again at full resolution.
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": "lightricks/ltx-2.5/image-to-video",
"input": {
"duration_seconds": 5,
"image_url": "https://example.com/reference.png",
"prompt": "A slow aerial shot drifting over a misty pine forest at sunrise",
"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.












