Sign in
ActivePOST /v1/videos

xW 2.7 S

Image-to-video generation: animate a still image from a text prompt, with optional audio input.

xW 2.7 S turns a single input image into a short video guided by a text prompt. It supports 720p/1080p output, 2–15 second durations, an optional audio track to drive motion, and a negative prompt. The endpoint is **asynchronous**: POST returns `202` with a `requestId` and `pollUrl` immediately, and the finished video is delivered via polling (`GET /v1/videos/:requestId`) or via an HMAC-signed webhook if you supply `webhookUrl`. Signed video URLs are valid for 23 hours. Every request must be tagged with `endUserEmail` so videos can be grouped and managed per end-user inside your account.

Authentication. Add Authorization: Bearer xm_live_… to every request.

How to get an API key

Account responsibility. Every request must include the real email of YOUR end-user via endUserEmail. You are accountable for what they generate — monitor activity and act on abuse, or your account may be suspended.

Read acceptable use

Quick example

Send a generation in 5 lines. Pick your language below.

curl
curl -X POST https://api.xmode.ai/v1/generations \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW2.7S",
  "prompt": "A girl dancing gracefully in a flower field, camera slowly pushing in",
  "image": "https://example.com/input-image.png"
}'

Request parameters

The fields you can include in the request body. Anything not listed is ignored.

NameTypeRequiredDefaultDescription
endUserEmailstring (email)yes

REQUIRED. Email of YOUR real end-user inside your product — the person who actually triggered this video. We use it to attribute every request and give you a chain of responsibility: you can list, audit, and delete that user's videos. Do NOT pass a fake address, a shared placeholder, or someone else's email — that's a policy violation.

Example: "alice@your-product.com"

modelstringyes

Public model alias. Required — pass the alias of the video model you want to use (e.g. xW2.7S).

Example: "xW2.7S"

promptstringyes

English text prompt describing the motion, action, and mood you want from the input image. Max ~2000 tokens.

Example: "A girl dancing gracefully in a flower field, camera slowly pushing in"

imagestring (https URL)yes

Input image to animate (publicly fetchable HTTPS URL). Supported formats JPEG, PNG (no transparency), BMP, WEBP. Width and height 240–8000 px, aspect ratio between 1:8 and 8:1, max 20 MB.

Example: "https://example.com/input-image.png"

negative_promptstringno

Elements to exclude from the video.

Example: "blurry, distorted face, extra limbs"

audio_urlstring (https URL)no

Optional audio track (HTTPS URL) to drive the video. Supported formats WAV, MP3. Duration 2–30 seconds, max 15 MB.

Example: "https://example.com/speech.mp3"

resolution"720p" | "1080p"no"1080p"

Output video resolution. Affects price (see Pricing).

Example: "1080p"

durationintegerno5

Video duration in seconds (2–15). Billed per second of output.

Example: 10

prompt_extendbooleannotrue

When enabled, the system expands and optimizes your prompt before generation. Free.

seedinteger | nullnonull (auto)

Determinism seed (0–2147483647). Pass null or omit for an auto-generated seed.

Example: 42

webhookUrlstring (https URL)no

Optional public HTTPS URL we will POST the final record to once the video is succeeded or failed. The body is identical to what GET /v1/videos/:requestId returns. Each delivery is HMAC-signed (`X-XMode-Signature: v1=<hex>`) and timestamped (`X-XMode-Timestamp`); reject anything older than 5 minutes. Private/loopback IPs are refused (SSRF guard).

Example: "https://your-app.example.com/hooks/xmode"

Response

On a successful generation you receive a 200 with this shape. Output URLs are signed and valid for 23 hours.

JSON
{
  "requestId": "req_8sV2kQ1aJpL9wDvE",
  "model": "xW2.7S",
  "status": "queued",
  "prompt": "A girl dancing gracefully in a flower field, camera slowly pushing in",
  "endUserEmail": "alice@your-product.com",
  "createdAt": "2026-06-09T19:45:15.204Z",
  "pollUrl": "https://api.xmode.ai/v1/videos/req_8sV2kQ1aJpL9wDvE"
}
NameTypeRequiredDefaultDescription
requestIdstringyes

Unique id of the video request. Use it with GET /v1/videos/:requestId to poll.

modelstringyes

Public alias of the model that will produce the video.

status"queued" | "processing" | "succeeded" | "failed" | "expired"yes

Lifecycle marker. POST always returns `queued`. GET returns the current state. `expired` means the request succeeded more than 23 hours ago and signed URLs no longer work — re-run if you need the video again.

pollUrlstringno

Present on `queued` responses only. Absolute URL to GET for status. Recommended polling cadence: every 5 seconds until terminal.

videosarrayno

Present only when status=`succeeded`. Each item has `id`, `expiresAt`, optional `duration`/`resolution`, and EITHER `url` (signed, valid 23 h) OR `error: { code: "storage_failed" }` if our storage layer dropped that video. After 23 h the video is no longer accessible — save a copy on your side or re-generate.

errorobjectno

Present only when status=`failed`. `{ code, message }`. Same code values as the top-level error format (validation_error, content_policy, provider_error, provider_timeout, internal_error).

costobjectno

Present only when status=`succeeded`. `{ xTokens: number }`. Debited at request time; refunded automatically on `failed`.

finishedAtstring (ISO 8601)no

Present on terminal statuses (`succeeded`, `failed`, `expired`).

endUserEmailstringyes

Echoed back so you can confirm the grouping. Always lowercase.

createdAtstring (ISO 8601)yes

When the request was accepted (POST time).

Use cases

Common patterns. Copy any block, replace the API key, and you have a runnable request.

Basic image-to-video

Animate an input image from a text prompt. Defaults to 1080p and 5 seconds.

curl
curl -X POST https://api.xmode.ai/v1/generations \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW2.7S",
  "prompt": "A girl dancing gracefully in a flower field, camera slowly pushing in",
  "image": "https://example.com/input-image.png"
}'

Higher resolution + custom duration

Set `resolution` and `duration`. A 10-second 1080p product spin.

curl
curl -X POST https://api.xmode.ai/v1/generations \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW2.7S",
  "prompt": "A product rotating slowly with dramatic lighting",
  "image": "https://example.com/product-photo.jpg",
  "resolution": "1080p",
  "duration": 10
}'

Audio-driven + negative prompt

Pass `audio_url` to drive the motion and `negative_prompt` to exclude artefacts.

curl
curl -X POST https://api.xmode.ai/v1/generations \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW2.7S",
  "prompt": "A character speaking and gesturing naturally",
  "image": "https://example.com/character.png",
  "audio_url": "https://example.com/speech.mp3",
  "negative_prompt": "blurry, distorted face, extra limbs",
  "resolution": "720p",
  "duration": 8,
  "seed": 42
}'

Skip polling — receive a webhook

Pass `webhookUrl` and we POST the final record there once the video is done. The body is the same shape as GET /v1/videos/:requestId. Verify `X-XMode-Signature: v1=<hex>` against your account webhook secret (HMAC-SHA256 of `"<timestamp>.<rawBody>"`).

curl
curl -X POST https://api.xmode.ai/v1/generations \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW2.7S",
  "prompt": "Cinematic slow zoom on a lighthouse at golden hour",
  "image": "https://example.com/lighthouse.jpg",
  "webhookUrl": "https://your-app.example.com/hooks/xmode"
}'

Limits & pricing

  • Resolutions: 720p / 1080p
  • Duration: 2–15 seconds
  • Max input size: 20 MB input image
  • Max audio size: 15 MB audio
  • Prompt max tokens: ~2000
  • Pricing: Billed per second of output; `1080p` bills at a higher rate than `720p`. per second (Cost = duration × per-second rate, debited at request time. Failed videos are refunded automatically.)
Errors follow our standard format — see all error codes →