Skip to main content
Use these commands to start editing your camera, change the reference image or edit type, and end the edit.

Tracks

There is no audio in either direction. Both tracks exist from connect, so you can attach a player and publish your camera before start_edit. See Tracks for how to publish camera from each SDK.
Keep your camera track flowing. The model never repeats a frame to fill a gap, so a stalled camera means a stalled edit.

Session lifecycle

One session holds at most one active edit. An edit that ends does not end the session, and start_edit works again. session_state.phase is one of these values: The first edited frame can arrive after the phase becomes live. Draw your UI from camera_forwarding and video_receiving, not from phase: "live" alone. Each edit has a time limit, edit_max_seconds, reported on the snapshot once the edit starts. Reaching it ends the edit with end_reason: "max_duration".

Commands

Commands report results in two ways. sendCommand() returns a direct reply when the command has one. The model also sends session_state updates and command_error messages to connected clients. start_edit has no direct reply, so watch session_state to see when the edit becomes live. If a command is refused, it has no effect and sends command_error instead of a direct reply.
Omit an optional field you do not set. Do not send it as null. A command that carries an explicit null is dropped whole, without a command_error, so send { editing_type: "virtual_tryon" }, not { editing_type: "virtual_tryon", reference_image_url: null }.

Edit types

Choose editing_type based on what you want the image to change:

start_edit

Start editing your camera track with one reference image and an edit type. Give exactly one of reference_image or reference_image_url. Rotate phone photos before uploading them. The model uses an uploaded image as is and does not apply its EXIF orientation. start_edit begins setup. It does not wait for the camera or the first edited frame. Publish camera and watch session_state move through starting, warming_up, and live. If an edit is already active, the model sends BUSY. If the image is missing or invalid, or you send both image fields, it sends INVALID_INPUT. If setup fails after the command is accepted, phase becomes failed and last_error explains why. See command_error for error codes.

switch_reference

Change the reference image, the edit type, or both, without restarting the edit. What you omit stays as it is. Give at least one field. The reference_switched reply confirms that the model sent the switch. It does not mean the new look is visible yet. Its editing_type echoes the requested edit type, and reference_changed is true if you supplied a new image. If the switch fails later, you receive command_error for switch_reference. The previous image and edit type stay in effect, and the edit keeps running. session_state.editing_type returns to its previous value. The error code explains the failure. See command_error.
Each call switches exactly once. Do not resend a switch just because the new look has not appeared yet.
Outside a live edit, the command returns NOT_LIVE. If you omit every field or send an invalid image, it returns INVALID_INPUT. The image checks are the same as in start_edit.

end_edit

Send {} to end the edit. The phase moves through ending to ended. The command replies edit_ended once the edit is released. You can then call start_edit again. If no edit is active, the command returns NOT_LIVE. The reply’s end_reason matches the value in session_state. duration_seconds is the time the edit was live, or 0 if it never became live.

get_state

Send {} at any time. Replies session_state, the same snapshot the model broadcasts on every change. It never fails.

Messages

Every message is broadcast to all connected clients, except command replies, which go only to the client that sent the command. Register your message listener before connecting so it receives the first session_state. JavaScript uses sendCommand() and Python uses send_command() for the same operation. When a command has a direct reply, both methods return it. Handle state updates and errors with a message listener:

session_state

This is the authoritative snapshot. Drive your UI from it. A client that reconnects during an edit gets the full snapshot on connect. phase is always present. Other fields are null or false when they do not apply. end_reason is one of: content_policy, upstream_quota, media_lost, and a failed start also leave a last_error that explains the reason.

command_error

Emitted when a command is refused, a switch fails, or the edit fails. A refused command has no effect. If a switch fails later, the previous look stays in effect. The payload is broadcast and stored as session_state.last_error. request means the input was invalid. state means this phase does not allow the command. upstream means the generation service refused or failed. platform means Reactor failed. The generation service can also return codes not listed here. These pass through unchanged. Log code and trace_id when reporting an unknown error.

Upload reference

reference_image takes a reference returned by the Reactor upload protocol. All fields are required.

Multiple clients

Several clients can join the same session. session_state and command_error go to all of them. A command reply goes only to the client that sent the command. A session has one edit, and it edits the session’s camera track. A client that disconnects does not end the edit. Every new session starts in idle.