client.graph) replaces that list with a graph of steps, so the interview can branch on answers, capture structured values, pull in outside data and notify your systems as it goes.
Step types
Each type has its own config fields. Get the full schema before you author a flow:
Start from your question list
The easiest way in is to convert the existing linear questions into a straight-line flow, then edit it. Each question captures its answer asq1, q2, and so on.
Write a whole flow
Flows can be plain dicts in the API’s JSON shape, or the typedFlowDocument, FlowNode and FlowEdge models. from and class are Python keywords, so on the models they’re from_ and class_.
This flow is illustrative: the exact config each step needs, including how a question names the variable it captures, comes from
describe_node_types(). Run check() first and it will tell you anything that’s missing.Branching rules
- A
conditionis a single test:{"var": ..., "op": ..., "value": ...}. Operators areeq,neq,in,contains,gt,gte,lt,lte,is_setandnot_set. For compound logic, chain two decision steps. - On an
llm_classifierdecision, each outgoing edge setsclass(class_on the model) to the label it handles. - A decision with several paths needs exactly one
defaultpath, unless its conditions cover every possible answer of a choices or scale question. prioritysets the evaluation order of paths out of the same decision; lowest first.- Every step inside a loop needs
max_revisits. Once a step has run that many times, the interview takes the default path out. extract,webhookandcontext_fetchsteps never appear inedges. Attach them withafterorbefore.
Edit with patches
patch applies targeted edits instead of rewriting the whole flow. Operations run in order and the end state is validated as a whole.
Safe concurrent edits
Every successful save incrementsgraph_version. Pass the version you last read as expected_graph_version to set or patch. If someone else has saved in the meantime, the write is refused with ConflictError rather than overwriting their change.
set and patch never save an invalid flow. An invalid result raises ValidationError, and the stored flow is untouched.
Activate the flow
Saving a flow doesn’t change what interviews run. Switch modes explicitly:has_compiled_ir on graph.get) before you can activate it. An open study’s flow is locked, so pause it to edit.
Signals
Awebhook step sends a signed POST to your endpoint mid-interview. Get each step’s signing secret with get_signals, then verify deliveries with deutero.webhooks.unwrap:
deliver_signals=True to simulations.run.