Skip to main content
Updated Aug 4, 2026

Workflow Steps

What you'll learn
  • What steps are and how they form the body of a workflow
  • How to add, configure, and manage steps using the Steps section
  • How to debug steps individually or all at once
  • How step execution order works

Steps are the actions your workflow performs after the trigger fires. Each step represents a single operation -- such as sending a message, updating a record, or calling an external service. Steps execute in sequence from top to bottom, meaning each step completes before the next one begins.

For a detailed field-by-field guide to each available step type, see the Actions Reference.

Adding steps

To add a step to your workflow:

  1. Open the workflow creation or editing form.
  2. Scroll down to the Steps section.
  3. Click the Add step button.
  4. A new step will be added to the list. Configure it by selecting the step type and filling in its parameters.
  5. Repeat to add as many steps as your workflow requires.

Each step you add appears in the list in the order it will execute.

Configuring a step

When you add a step, you will need to configure it based on what action you want it to perform. Each step type has its own set of fields and options. For example:

  • A "send message" step may require you to specify the message text and the recipient
  • An "update record" step may require you to select which field to change and what value to set
  • A "call webhook" step may require you to provide an external URL and the data payload

CEL-enabled step fields take a value in the {expr: "..."} object form, where the expression is evaluated against the current execution context when the workflow runs. For example, {"expr": "contact.name"} in a message field resolves to the contact's name. For string-heavy fields you can also use the tpl() function, which fills single-brace {key} placeholders: tpl('Hello {name}', {name: contact.name}). The {{ }} double-brace syntax does not apply here — it only exists in WhatsApp message templates. See Workflow inputs for the variables each trigger exposes.

Debugging steps

The Steps section provides built-in debugging tools to help you test your workflow before activating it:

  • Start Debug -- Click this button to run all steps through the debug panel. It runs the real action loop -- the same one the live executor uses -- so each step's action actually executes: live HTTP requests, data writes, and outbound messages all fire. It is not a dry run or sandbox; the only differences from a production run are that it is invoked manually, uses a synthetic debug contact, returns each step's CEL arena and logs for inspection, and is not recorded in the execution history (the history clock icon) -- review its results in the debug panel instead. Treat its side effects as real.
  • To isolate a problem in one part of the workflow, open a step's menu and choose Debug to run that step on its own.

Debugging is especially useful when your workflow includes multiple steps that depend on each other, since you can inspect the output of each step and confirm that data is flowing correctly.

When you inspect step output, AutoTalk may also show a nested executionContext object with runner metadata such as status, timestamps, and sanitized safeError or safeResult values. Use step(N).executionContext when you want to branch on how a previous step ran, instead of relying on action-specific fields like step(N).status.

Clearing all steps

If you want to start over with a clean slate, click the Clear all items button. This removes all steps from the workflow at once. Use this with caution, as it cannot be undone.

Step execution order

Steps execute from top to bottom in the exact order they appear in the Steps section. Key points to keep in mind:

  • Sequential execution: Each step must complete before the next step begins.
  • Data flow: The output of one step can be referenced by subsequent steps. Action-specific fields stay on step(N), while shared runner metadata lives under step(N).executionContext.
  • Failure handling: A failing step does not stop the workflow -- subsequent steps still run. The engine marks the failed step (its executionContext.status becomes "failed" with a sanitized executionContext.safeError) but does not abort the run, so any later step that depends on it must guard itself, e.g. condition = {"expr": "get(step(N), 'executionContext.status') == 'failed'"} or use step_error(N) / step_ok(N). (Only the per-run action-call cap hard-stops a run; a malformed condition expression causes that step to be skipped with reason cel_eval_error, and execution continues.) The execution log still records sanitized step metadata, including executionContext.safeError, so you can see which step failed and why without exposing raw internals in the UI.
tip

Build your workflow incrementally. Add one step at a time, use Start Debug to test after each addition, and confirm it works before adding the next step.

Next steps