Generate a video from a prompt or a first frame, paid with x402
Generates a video from a text prompt, or animates an image_url from its first frame. The paid response waits about as long as the chosen model usually takes to render and returns the video URL when it is ready, otherwise a statusUrl to poll. Pay via the x402 protocol (HTTP 402): call without payment to receive a 402 challenge carrying the price and networks, sign the payment with an x402-capable wallet, and retry with the payment-signature header. The challenge lists two ways to pay the same amount: USDC on Base (eip155:8453) first, then USDC on Solana mainnet (solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp); a client pays the first one it has a wallet for, and neither needs gas money in the paying wallet. No account, API key, or signup is involved, so the payment is the only credential. A payment presented again after it was redeemed is refused with a 409 (code PAYMENT_ALREADY_REDEEMED) rather than rendered twice. Price is quoted per request and depends on the model and clip length you pick, so send the model and seconds you want and read the amount off the challenge rather than assuming a fixed figure; GET this path with no parameters for every model and price. Only the documented fields are read; a request carrying any other field is refused with a 400 before any payment moves, so nothing you send can be silently ignored and paid for. An image_url with no model renders on the cheapest model that takes an image at the length you ask for (wan-2.7 for 5 or 10 seconds, kling-3.0 for 15, veo-3.1-lite for 4, 6 or 8 or when you name no length), and the 402 quotes that model's price. The image is fetched and checked before the payment settles, so an image that cannot be used is refused (400, or 413 when it is too large, with a code) with nothing charged.
The paid call answers 200 at once, with the statusUrl in the X-Status-Url header, then sends a whitespace byte every 2 seconds while it waits (JSON parsers ignore it), and ends with one complete JSON object. By default it waits about as long as that model and length usually take to render (at least 45 seconds, about two and a half minutes for 5 seconds on minimax-h3, up to about ten for 15 seconds on seedance-2.5), so a caller that does not poll still gets its video; a client with a fixed timeout, such as the 60 seconds MCP tool calls allow, should send Prefer: wait=N or respond-async, and has the statusUrl in the X-Status-Url header either way. Read status in that body: success carries the video URL; error or partial means the render failed, nothing was charged for it, and retryUrl renders again on the wallet balance the payment left, without paying twice; running means the render is still going, so poll statusUrl. Send Prefer: wait=N to wait up to N seconds instead (at most 720). To get the statusUrl at once, send "async": true in the body or the header Prefer: respond-async, and the call answers at once, still 200, with status running, a runId and a statusUrl to poll. Preference-Applied echoes the preference that was honoured. Lost the statusUrl? GET /api/x402/purchases and sign its challenge with the paying wallet (Sign-In-With-X, free) to list every purchase with its file and a fresh statusUrl. And the same request sent again from the same wallet, once the first render has finished and its file never reached you, is answered with that file (alreadyPaid, paidUsd 0) and the new payment is not taken.
Request
- Base URL: https://www.trezalabs.com
- URL: https://www.trezalabs.com/api/x402/video
- Auth: HTTP bearer
Headers
Optional. respond-async answers at once (200, status running) with a statusUrl to poll, like "async": true. wait=N sets how long the call waits for the render, in seconds (at most 720), before it ends with status running and the statusUrl. Without it, the call waits about as long as that model and length usually take to render: at least 45 seconds, about two and a half minutes for 5 seconds on minimax-h3, up to about ten minutes for 15 seconds on seedance-2.5. A client with a fixed timeout, such as the 60 seconds MCP tool calls allow, should send wait=N under it or respond-async. Echoed in Preference-Applied.
Request body
Response
Payment settled and the response waited for the render, by default about as long as that model usually takes (at least 45 seconds), or the Prefer: wait=N asked for. Streamed: the status and headers are sent at once (X-Status-Url carries the statusUrl), then a whitespace byte every 2 seconds, which JSON parsers ignore, then one complete JSON object. The HTTP status is 200 whatever happened to the render, so read status in the body: success carries video; error or partial carries the failure fields and a retryUrl, and nothing was charged for the render; running means the render is still going (it outlasted the wait, or is being collected from the provider, see note), so poll statusUrl.
Example response
{
"status": "success"
}Changes
No recorded changes to this operation across all 1 revision of this API.