Interaction overview
You can interact with a running story in four ways:
A common interaction looks like this:
A client does not need to use every control. Most experiences can start with
instruction.create, add state when the product has numbers or rules to display, and add references only when a new character or object appears.
Connect once and start playback
Create a session first, then open the returned control URL with the session-specific secret:session.ready means the opening media is ready to play. Its playback.url is an HLS address; pass it to an HLS-capable player instead of constructing a URL yourself.
The second WebSocket subprotocol value is the session secret. Do not send your general API key over this channel.
Send the next instruction
instruction.create is the primary interaction. Use it whenever the user chooses an action, asks a question that should become part of the story, or wants to change the direction of the next scene.
Request
Describe one coherent piece of what should happen next. Include the important action, characters, tone, and visual result in the text. You do not need to split it into shots or dialogue turns.Response events
The normal lifecycle is:instruction.scheduled as the current timeline estimate. A later scheduled event can revise its position. Treat instruction.started and instruction.completed as playback-time milestones, not as a guarantee that every viewer has rendered the same frame at the same wall-clock instant.
If the instruction cannot be prepared or the session is ending, the server may emit:
instruction.cancelled. Use a new client_request_id for a genuinely new instruction. Do not resend the same text with a new id just because the acknowledgement is delayed.
Manage world state
State is for structured values your product needs to show or enforce: health points, score, location, inventory, clue count, weather, or quest progress. It is separate from the natural-language instruction, but an instruction can carry state changes that should happen with that scene. A battle might start with:Change a value immediately
Usestate.update when the application has already decided that a value should change now:
state.updated event containing the complete state, not just the two changed fields:
Tie a value to a scene
Usestate_ops on instruction.create when the value should become effective with that instruction:
instruction_start for a fact that becomes true when the scene begins, and instruction_end for a change that takes effect when the scene ends.
For a previously accepted instruction, state.update can target it explicitly:
set, delete, append, and remove. The service accepts or rejects the whole batch; it does not partially apply an invalid batch.
Read the current state
Usestate.get when the UI needs a fresh snapshot:
state object from state.updated or state.snapshot. Do not infer a separate hidden state schema.
Add a reference when the story needs one
Add a reference when a new character, object, location, or voice becomes relevant. Register the file with the public upload API first, then send itsfile_id over the control channel.
Response events
Success:assets.added before sending an instruction that depends on the new reference:
Stop the session
Stop immediately when the user leaves or the application must end the experience now:session.ending while the closing is being prepared and session.ended after the session reaches its terminal state. Once session.ending arrives, stop sending new story instructions.
Reconnect and event ordering
Every historical server event has a monotonically increasingid. Save the latest id after processing each event. If the connection drops, reconnect with:
state.snapshot.last_event_id is the cursor included in that state read.
Process events by id. A later instruction.scheduled can revise an earlier timeline estimate. If a session has already ended, use GET /v1/streaming-world/sessions/{session_id} for the final status and timeline.
Handle control errors
Use the publicerror.code to decide what the client should do:
Use Client messages for the complete request fields and Server events for every response schema.