Skip to main content
A workflow has a contract with the code that calls it. Your code sends inputs. The workflow returns an outcome label and a result, along with execution metadata. Nothing else crosses the boundary. The graph behind the contract can change freely. The contract itself is what your integration depends on.

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.
The workflow’s deploy page lists the exact set of inputs, at https://platform.asteroid.ai/agents/<agent-id>/deploy. Read the names there rather than guessing them from the instructions.

Inputs reach the instructions as variables

An input named patient_name appears in the instructions as {{.patient_name}}.
Nested JSON reads with a dot path, as {{.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 is success 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, not done.
  • 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.
Outcome labels are the contract. Treat a new label as a breaking change to your callers, and ship it as a new version.

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 properties map.
  • Every object type includes "additionalProperties": false.
  • List every property in the required array.
  • Use description on each property. The workflow reads it to decide what to put there.
  • oneOf, allOf and $ref are rejected. anyOf and enum are allowed.
  • The schema is at most 15,000 characters when serialized as JSON.
Check a schema with 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.

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