Skip to content
API Reference

Wan Spicy

The Wan Spicy models animate a single image into a video. wan2.7-i2v-spicy adds audio — generated, or driven by a track you supply — and a negative prompt; wan2.2-i2v-spicy can pin the last frame as well as the first.

For the rest of the Wan family (Wan 2.7 and Wan 3.0), see Wan.

POST https://llm.siraya.ai/v1/videos/generations
GET https://llm.siraya.ai/v1/videos/{video_id}
DELETE https://llm.siraya.ai/v1/videos/{video_id}

Send async: true and poll

Renders typically take one to three minutes. Send "async": true to get an id back immediately, then poll GET /v1/videos/{video_id} until status is completed or failed — or pass a callbackUrl to be notified instead. See Asynchronous generation.

Supported Models

Model ID Inputs Resolutions seconds
wan2.7-i2v-spicy image · negative prompt · audio 720p, 1080p (default 1080p) 2–15 (default 5)
wan2.2-i2v-spicy image · optional last frame 480p, 720p (default 480p) exactly 5 or 8 (default 5)
Authorization string Required
Your API Key (e.g., Bearer <API_KEY>).

Body

Every field is sent flat, at the top level of the request body.

model string Required
wan2.7-i2v-spicy or wan2.2-i2v-spicy.
prompt string Required
A text description of the motion and scene.
image string Required
The first frame, URL or base64. JPEG, PNG (no alpha), BMP or WEBP; 240–8000 px per side; aspect ratio ≤ 8:1; ≤ 20 MB.
last_image string
wan2.2-i2v-spicy only. The last frame, URL or base64.
seconds integer Default: 5
Video length. wan2.7-i2v-spicy: 2–15. wan2.2-i2v-spicy: exactly 5 or 8 — anything else is a 400 before the job starts. The spelling duration is also accepted; if both arrive, seconds wins.
resolution string
Output tier. wan2.7-i2v-spicy: 720p or 1080p (default 1080p). wan2.2-i2v-spicy: 480p or 720p (default 480p).
negative_prompt string
wan2.7-i2v-spicy only. Content to steer away from.
audio_url string
wan2.7-i2v-spicy only. An https:// WAV or MP3 track, 2–30 s, ≤ 15 MB, that drives the content.
generate_audio boolean Default: true
wan2.7-i2v-spicy only. Whether the video carries audio; false mutes it even when audio_url is set. The spelling audio is also accepted; if both arrive, generate_audio wins.
seed integer
Random seed for reproducibility. Omit it, or pass 0, for a random seed.
prompt_extend boolean Default: true
Rewrites the prompt before generation. Free on wan2.7-i2v-spicy; on wan2.2-i2v-spicy each rewritten request is surcharged — turn it off if you don't need it.
async boolean Recommended: true
When true, the request returns immediately with a video id you poll for status. When false (the default), it waits for generation to finish and returns the completed video URL.
callbackUrl string
Only used when async is true. An https:// URL the router will POST the result to, so you don't have to poll.
curl https://llm.siraya.ai/v1/videos/generations \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer <API_KEY>" \
  -d '{
    "model": "wan2.7-i2v-spicy",
    "prompt": "She turns toward the camera and smiles",
    "image": "https://your-domain.com/portrait.jpg",
    "seconds": 5,
    "resolution": "720p",
    "async": true
  }'
import requests

url = "https://llm.siraya.ai/v1/videos/generations"
headers = {
    "Content-Type": "application/json",
    "Authorization": "Bearer <API_KEY>"
}
data = {
    "model": "wan2.7-i2v-spicy",
    "prompt": "She turns toward the camera and smiles",
    "image": "https://your-domain.com/portrait.jpg",
    "seconds": 5,
    "resolution": "720p",
    "async": True
}

response = requests.post(url, headers=headers, json=data)
print(response.json())

Example Response

{
  "id": "video_9M1Ll0p-27nCK2vX82bHn...",
  "object": "video",
  "status": "processing",
  "model": "wan2.7-i2v-spicy",
  "seconds": 5,
  "usage": { "completion_tokens": 0, "total_tokens": 0 }
}

Examples

First and last frame (wan2.2-i2v-spicy)

{
  "model": "wan2.2-i2v-spicy",
  "prompt": "The car drives from the city into the desert",
  "image": "https://your-domain.com/city.jpg",
  "last_image": "https://your-domain.com/desert.jpg",
  "seconds": 8,
  "resolution": "720p",
  "prompt_extend": false,
  "async": true
}

Audio-driven (wan2.7-i2v-spicy)

{
  "model": "wan2.7-i2v-spicy",
  "prompt": "The singer performs the song",
  "image": "https://your-domain.com/singer.jpg",
  "audio_url": "https://your-domain.com/song.mp3",
  "negative_prompt": "blurry, distorted face",
  "seconds": 10,
  "resolution": "1080p",
  "async": true
}

Poll for status

curl https://llm.siraya.ai/v1/videos/<video_id> \
  -H "Authorization: Bearer <API_KEY>"
{
  "id": "video_9M1Ll0p-27nCK2vX82bHn...",
  "object": "video",
  "status": "completed",
  "seconds": 2,
  "resolution": "720p",
  "model": "wan2.7-i2v-spicy",
  "output_url": "https://.../result_00.mp4",
  "usage": { "completion_tokens": 0, "total_tokens": 0 }
}
Field Present Meaning
id always Opaque — pass it as-is to the status and delete endpoints; don't parse it
status always processing · completed · failed
seconds, resolution completed Echoed from your request — not measured from the output
output_url completed Signed and expiring — download promptly rather than storing it as a stable link
error failed { "code": "...", "message": "..." }
usage always Always zero — no token concept

Delete a task

curl -X DELETE https://llm.siraya.ai/v1/videos/<video_id> \
  -H "Authorization: Bearer <API_KEY>"

Only completed tasks can be deleted. A task that is still processing answers 409; a failed task is refused too, and the deletion is not retried for you. A successful delete returns { "id": "...", "object": "video", "deleted": true, "deleted_at": "...", "model": "..." }.

Behavior worth knowing

seconds and resolution are echoes. The finished task carries neither, so the status response reports what you asked for at create time.

wan2.2-i2v-spicy validates duration hard. Exactly 5 or 8; anything else is a clean 400 naming the allowed values, before the job starts.

Image URLs must be public. The input is fetched by the model service itself; a URL behind authentication fails the task with a download error. For large images, prefer a URL over base64 — the request-body size limit applies to the whole payload.

Errors

A request-time refusal is final — retrying the same body won't help.

Status Meaning
400 Parameter validation — a seconds outside the model's range, a resolution the model doesn't offer (e.g. Input should be '1080P' or '720P'), or a missing image
401 Invalid API key
404 Unrecognized model code
409 DELETE on a task that is not completed
200 with status: "processing" Accepted — keep polling. A task that fails after starting reports status: "failed" with an error object