Sign in
ActivePOST /v1/videos

xW 3.0 S Pro

The high-resolution ladder of xW 3.0 S.

xW 3.0 S Pro is xW 3.0 S with a super-resolution finishing pass, and it exists for one reason: resolution above what the base model reaches. It takes the same inputs and runs the same three capabilities — a prompt alone, keyframes, or reference material — so the choice between the two models is a choice of tier list.

  • Same inputs and the same three capabilities as xW 3.0 S, finished at higher tiers
  • Where the two models overlap, this one upscales rather than rendering natively — compare them on your own material
  • Billed per second of video: the output, plus the length of any reference video sent with it
  • A faster tier trades a higher per-second rate for latency, at the same quality

Generation is asynchronous. POST answers `202` with a `requestId` and a `pollUrl`; the result arrives by polling that URL or through an HMAC-signed webhook when you pass `webhookUrl`. Signed output URLs stay valid for 23 hours.

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/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "A lighthouse on a cliff at golden hour, waves breaking below, camera slowly craning up to reveal the horizon",
  "duration": 8
}'

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.

Example: "xW3.0sPro"

promptstringno—

What the video should contain and how it should move. Optional on this model: a request that supplies a keyframe or reference media may omit it. Refer to reference assets positionally — "Image 1", "Video 2", "Audio 1" — numbering each kind separately in the order you listed them.

Example: "Image 1 walks through the doorway in Image 2, camera slowly pushing in"

first_framestring (https URL)no—

Image pinned as the exact FIRST frame of the output. Keyframe mode — cannot be combined with any `reference_*` field.

Example: "https://example.com/opening.png"

last_framestring (https URL)no—

Image pinned as the exact LAST frame of the output. Pair it with `first_frame` to have the model invent the transition between two fixed states. Keyframe mode.

Example: "https://example.com/closing.png"

reference_imagesarray of https URLsno—

Reference images the model draws on. Numbered "Image 1", "Image 2" … in array order for use in the prompt. Reference mode — cannot be combined with `first_frame`/`last_frame`.

Example: ["https://example.com/character.png"]

reference_videosarray of https URLsno—

Reference video clips, numbered "Video 1", "Video 2" … in array order. Reference mode. Billed: the combined length of the clips is added to the output length, and the total is charged at this request’s per-second rate.

Example: ["https://example.com/motion.mp4"]

reference_audiosarray of https URLsno—

Reference audio clips, numbered "Audio 1", "Audio 2" … in array order. Reference mode.

Example: ["https://example.com/voice.mp3"]

resolution"1080p" | "2k" | "4k"no"1080p"

Output video resolution. Determines the per-second rate.

Example: "1080p"

ratio"adaptive" | "16:9" | "4:3" | "1:1" | "3:4" | "9:16"no"adaptive"

Aspect ratio of the output. `adaptive` lets the model pick one that suits the input material and the prompt — usually the right choice when you pass frames or references of a known shape.

Example: "16:9"

durationintegerno5

Seconds of output video, billed per second. When the request carries reference video, this plus the combined reference length may not exceed the combined ceiling — see Limits.

Example: 10

audiobooleannotrue

Whether the output carries an audio track. The model generates dialogue, effects and ambience described in the prompt. Turning it off does not change what you are charged.

Example: false

fastbooleannofalse

Run on the faster tier. The model and the output quality are identical — only latency differs, and substantially: a long clip finishes in roughly a quarter of the time. It costs more per second, so it is a deliberate trade rather than a default. Both rates are published by `client.models.list()`.

Example: true

seedinteger | nullnonull (auto)

Determinism seed (0–2147483647). Pass null or omit for an auto-generated seed. Same seed with the same prompt, model and parameters reproduces the same video.

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

The POST answers 202 Accepted with this shape — the job is queued, not finished. Read the result from pollUrl, which returns the same record with the fields below filled in. Output URLs are signed and valid for 23 hours.

JSON
{
  "requestId": "req_4hK9pQ2mXvR7tLbN",
  "model": "xW3.0sPro",
  "status": "queued",
  "prompt": "Image 1 walks through the doorway in Image 2, camera slowly pushing in",
  "endUserEmail": "alice@your-product.com",
  "createdAt": "2026-08-24T10:12:44.301Z",
  "pollUrl": "https://api.xmode.ai/v1/videos/req_4hK9pQ2mXvR7tLbN"
}
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 it. If every video of the request is dropped there is nothing to deliver, so the request comes back `failed` and refunded instead. The URL is re-signed on every read, so re-reading this record replaces a link that went stale on your side — but that never moves `expiresAt`, which is fixed when the generation completed. Once it passes, the record returns status `expired` with no URL and the bytes are gone. Download inside the window 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.

Text to video

No input material at all — just describe the shot. Motion, camera and mood belong in the prompt.

curl
curl -X POST https://api.xmode.ai/v1/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "A lighthouse on a cliff at golden hour, waves breaking below, camera slowly craning up to reveal the horizon",
  "duration": 8
}'

Animate a still image

Pin the opening frame and describe only what moves. The subject and setting already come from the image.

curl
curl -X POST https://api.xmode.ai/v1/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "She turns toward the camera and smiles, hair moving in the breeze",
  "first_frame": "https://example.com/portrait.jpg",
  "resolution": "1080p",
  "duration": 5
}'

Fill the motion between two frames

Give both ends and let the model invent the transition. Useful for product turnarounds and before/after shots where both states are fixed.

curl
curl -X POST https://api.xmode.ai/v1/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "The product rotates smoothly from the first pose to the second",
  "first_frame": "https://example.com/product-front.jpg",
  "last_frame": "https://example.com/product-side.jpg",
  "ratio": "1:1",
  "duration": 4
}'

Compose from reference material

Reference assets are numbered per kind, in the order you list them, and you direct them from the prompt. Here Image 1 is a character and Image 2 a location.

curl
curl -X POST https://api.xmode.ai/v1/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "Image 1 walks into the room from Image 2, sits down at the table and looks out of the window",
  "reference_images": [
    "https://example.com/character.png",
    "https://example.com/room.png"
  ],
  "ratio": "16:9",
  "duration": 10
}'

Get it back sooner

Pass `fast` for the quicker tier. Identical model and identical output — a long clip simply finishes in about a quarter of the time, at a higher per-second rate.

curl
curl -X POST https://api.xmode.ai/v1/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "Confetti bursts over a stadium crowd in slow motion",
  "resolution": "720p",
  "duration": 15,
  "fast": true
}'

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/videos \
  -H "Authorization: Bearer xm_live_<your-key>" \
  -H "Content-Type: application/json" \
  -d '{
  "endUserEmail": "alice@your-product.com",
  "model": "xW3.0sPro",
  "prompt": "Slow dolly through an empty art gallery at night",
  "webhookUrl": "https://your-app.example.com/hooks/xmode"
}'

Limits

  • Resolutions: 1080p / 2k / 4k
  • Aspect ratios: adaptive / 16:9 / 4:3 / 1:1 / 3:4 / 9:16
  • Output duration: 2–30 seconds
  • Keyframes: 1 first_frame + 1 last_frame; cannot be combined with reference media
  • Reference images: up to 10; JPEG, PNG (no transparency), BMP or WEBP; 240–8000 px per side; aspect ratio up to 8:1; 20 MB each
  • Reference video: up to 5 clips (refused here); each 1–15s and 15s combined, mp4 or mov, 100 MB per clip — checked by the model
  • Reference audio: up to 5 clips (refused here); each 1–15s and 15s combined, wav or mp3, 15 MB each — checked by the model
  • Prompt max length: 8000 characters
Errors follow our standard format — see all error codes →