Episode Lifecycle
Creating an Episode
To create an episode, POST to/api/v1/episodes with a collection and scenario ID. See the Quickstart for full code examples.
Response
Starting from a Recorded Conversation
An episode can continue a conversation your organization already recorded on the platform (a capture session) from a chosen point. Passfrom_capture_session instead of scenario_slug:
at_message_id must be a client message of that session. The episode starts with every message up to and including it, and the simulated person starts in the state it had at that point: the facts it had already disclosed, read from the recording’s turn-by-turn discovery history, and the conclusions the simulated person had reached, read from the saved persona state. initial_observation is that client message, so your next operator message answers it, and current_turn counts the operator messages before it.
The recording itself is never changed. Each episode gets its own copy of the person’s state, so several candidate replies can be tried from the same point without affecting each other or the recording.
The response carries checkpoint_sha256: the SHA-256 of the restored checkpoint (the seeded history, the rebuilt persona state, the scenario, the collection, the source session and the boundary message). Two episodes restored from the same point share it, so a verifier can confirm that a reward was produced from the state it expected.
No reward is ever produced for a request that fails: a failure before the episode exists writes nothing, and a failure after it marks the episode
abandoned with the reason in its config.
Only the latest client message of a recording has the person’s conclusions saved. An earlier point is restorable when the person had reached no conclusions by the end of the recording; otherwise the API answers
409 rather than guess which conclusions existed then.Store and reuse fact readings
The evaluate endpoint can store readings for an exact recorded prefix. Send itsstore block to receive a run_id.
To store ordinary episode turns, create the episode with both score_turns: true and persist_turns: true. Storage defaults to off.
To grade replies from a stored prefix, add that run as baseline_run_id when restoring the episode. The start response returns its raw overall and its reward on the 0 to 1 scale. The recording text, boundary, scoring settings and judge must still match.
Each continuation keeps the original baseline reference. A fact is settled when it fired at or above 0.9 in all but one of at least three reads, or in both of two reads. One read never settles a fact. Settled facts retain their stored observations. Default detectors read each open fact once against the full conversation. Calibrated detectors keep their own repeat recipe.
Use the turn’s raw_reward minus the start response’s baseline.reward to calculate the reply’s signed delta. Full score access also returns per-fact observations, which the verifier can save locally. Production storage of attempts stays off unless the turn sends store_attempt_run: true.
Submitting Turns
Each turn represents one exchange in the conversation. POST to/api/v1/episodes/{episode_id}/turns with your messages. See the Quickstart for full code examples.
To include tool calls, attach them to the assistant message. See Tool Calls for details.
Response
The
scores field is optional and provides a breakdown of individual scoring dimensions. Dimension names vary by scenario.Episode Termination
Episodes end for one of these reasons:Episode State
Each episode tracks internal state including:- Which objectives have been discovered
- Which goals have been achieved
- The scenario’s scoring criteria
Limits
Best Practices
One episode per training sample
One episode per training sample
Create a fresh episode for each training trajectory. Don’t reuse episode IDs.
Track conversation history locally
Track conversation history locally
The API returns only one message per turn: the simulated persona’s response. Your client is responsible for maintaining the full conversation history and passing all messages with each turn submission.
Handle rate limits gracefully
Handle rate limits gracefully
Check
X-RateLimit-Remaining headers and implement exponential backoff.