Declared inputs
A workflow declares the inputs it accepts. Each one has four parts.
Your code sends the values in the
inputs object on the execute call.
Rules
- A name matches
[a-zA-Z_][a-zA-Z0-9_]*and is unique within the workflow. - Values are validated against the declared schema when the execution starts.
- A required input with no value fails the execution immediately. It does not fail halfway through.
- An omitted optional input falls back to its default. With no default, it falls back to nothing.
Inputs reach the instructions as variables
An input namedpatient_name appears in the instructions as {{.patient_name}}.
{{.user.name}}. See Nodes.
Outcome labels
An outcome label answers one question: how did this execution finish? Every output node lists the labels it can produce. The label the execution lands on comes back to your code, and your code branches on it. The default pair issuccess and failure. Replace it with labels that name your real end states.
Rules
- A label matches
^[a-z0-9_]{1,30}$. Lowercase letters, digits, and underscores only, 1 to 30 characters. - Spaces, hyphens, and capitals are rejected when you save the node.
- Each output node declares at least 1 label and at most 20.
- Labels are unique within a node.
Choosing labels
- Name the end state, not the feeling. Write
payment_completed, notdone. - Declare every realistic end state, including the ones you would rather not meet.
- Keep the same names across workflows that do similar work.
- Test that an execution can actually reach each label.
Result schema
Alongside the label, an output node can return structured data. You define the shape as a JSON Schema, and the workflow fills it in. The format follows OpenAI Structured Outputs, a subset of JSON Schema.Rules
- The root is an object with a
propertiesmap. - Every object type includes
"additionalProperties": false. - List every property in the
requiredarray. - Use
descriptionon each property. The workflow reads it to decide what to put there. oneOf,allOfand$refare rejected.anyOfandenumare allowed.- The schema is at most 15,000 characters when serialized as JSON.
schemaValidate before you put it on an output node. See
Build from your coding agent.
Add a schema when downstream systems expect defined fields, or when the execution extracts several values. Start with labels alone, and add a schema once you know what you need back.
A result schema is not a transition schema.The output node’s schema defines the execution’s final result. A transition’s schema defines the payload handed to the next node, which reads it as
{{.output}}. A transition payload never reaches your code.What comes back
GET /executions/{executionId} returns the execution. The contract lives under executionResult.
executionResult is absent when an execution ends before it reaches an output node. Check that it exists before you read it.Branch on outcome, not on status
The status tells you the execution finished. The outcome tells you what happened.completed means the workflow reached an output node. It does not mean the work succeeded. An execution that correctly reports “this patient has no coverage” is completed. So is an execution that booked the appointment. The outcome label is what separates them.
JSON and the TypeScript SDK use camelCase, as in
executionResult. The Python SDK exposes the same field as execution.execution_result.Related
Call a workflow from your code
Send inputs, wait for the execution, read the result
Executions and statuses
Every status an execution passes through, and which ones are terminal
Nodes
Where labels and result schemas are configured
Versions and publishing
Ship a contract change without breaking callers

