Skip to main content
This page documents the complete X2 wire surface: the media tracks it consumes and produces, the session lifecycle, every command you can send, and the messages the model emits back. For what X2 is and a quick start, see the overview.

Tracks

Unlike the generation-only models, X2 takes an inbound track: the client publishes the video to be edited on source, and the model streams the transformed result back on main_video. The model’s native source pacing is 24 fps, and the output plays at 24 fps with no frame interpolation and no upscaling. The model chooses the output resolution (a bucket around 832p) once at the first generation, from the source stream’s aspect ratio. It holds for the whole session and arrives in generation_started and in every state_update.
A still image works as a source too: draw it to a canvas and capture it with canvas.captureStream(24), repainting at the stream rate so the capturer keeps emitting frames. From the model’s side that is indistinguishable from a video of a motionless scene, which is the drag-to-animate setup. The tutorial shows the pattern.

Session lifecycle

There is no start command and no staged or started state machine to drive. Generation begins on its own once two things are true: a non-empty prompt is set, and source frames are arriving. It runs until the session ends, a new reference image forces an automatic restart, or you call reset. Reset stops generation and clears the prompt, reference image, and pointer. See Sessions for the connection-level lifecycle (disconnected → connecting → waiting → ready) the session passes through first. Every control follows block semantics: the model generates one block at a time, a prompt change applies from the next block, it samples the pointer once per block, and the backlog policy switches at the next block.

Commands

Send commands with reactor.sendCommand() on the base SDK, or the typed methods on the generated model client / useX2() hook. Below are all available commands:

set_prompt

Set the editing instruction that guides the re-render (for example a character swap or insertion). Generation needs a non-empty prompt before it begins; setting one while generating applies from the next block. Emits prompt_accepted, then state_update. Parameters:

set_reference_image

Provide a reference image of a character or object to insert or swap into the video. Upload the file first with uploadFile(), then pass the returned FileRef. Emits reference_image_accepted and state_update on success, or command_error if the file cannot be decoded as an image. The reference can be set before generation or replaced while generating. A mid-run replacement restarts the stream on its own (generation_stopped with reason reference_image_changed, then a fresh generation_started) and the new image conditions the edit from its first block. The prompt stays set across the swap, so the edit resumes without a re-arm; no reset is needed. Parameters:

set_pointer

Update the drag pointer that steers the edited subject’s motion, setting its position and press state together. Valid at any time; the model samples the pointer once per generated block, and it only has an effect while active is true. Coordinates map to the output frame, so account for any letterboxing your player introduces when you map pointer events. Emits pointer_changed, then state_update. Parameters:
Because the model samples the pointer once per block, sending positions faster than about 30 Hz buys nothing. Throttle pointer-move events, and use a trailing send so the final position of a fast gesture still lands. Always send active: false on release (and on unmount) so the model does not keep steering toward a stale point.

set_pointer_x, set_pointer_y, set_pointer_active

Single-field variants of set_pointer, for updating one pointer field at a time. Same semantics: sampled once per block, effective only while the pointer is active. Prefer set_pointer when you have all three values; the position and press state then change in one step. Parameters (one per command):

set_keep_backlog

Pick the source-frame consumption policy, applied from the next block:
  • false (default): newest frames. The model always reads the most recent source frames and drops any backlog, keeping latency bounded when inference runs slower than the source. Right for live sources like a webcam, where the edit should track “now”.
  • true: every frame. The model consumes every source frame in order, for smoother motion at the cost of a growing delay. Right for pre-recorded clips and for drag-to-animate, where smoothness matters more than latency.
Emits state_update. reset does not clear this setting, unlike the prompt, reference image, and pointer: it persists until the session ends, so re-sync any UI toggle to the default on disconnect rather than on reset. Parameters:

reset

Stop generation and clear the prompt, reference image, and pointer, returning the session to waiting for new conditions. Valid at any time. Emits generation_stopped with reason reset if a run was active, and state_update. Takes no arguments. Note two things reset leaves alone: the output resolution (chosen once per session, at the first generation) and the keep_backlog policy (persists until the session ends).

Messages

X2 emits the following messages, each arriving as JSON { "type": "<name>", "data": { … } }. A generation_stopped with reason reference_image_changed is an automatic restart: a fresh generation_started follows at once, so treat it as a hiccup rather than an end state. Only reason reset means the session is back to waiting for conditions; drive any “clear the drafts” UI off that reason, not off every stop.

state_update payload

state_update is the single source of truth for driving UI. It arrives on connect and after every observable state change, always carrying the full state. Subscribe once and reduce it into your app state; the only fact it does not carry is the decoded reference image’s dimensions, which come from the discrete reference_image_accepted ack. Example handler:

Complete example

Publish a webcam source, set a reference image and prompt, then steer the subject with a short drag.