Skip to main content
Workflows can run synchronously (the caller waits for completion) or asynchronously (the caller gets an execution_id immediately and the workflow runs in the background).

At a glance

When to use sync

  • The caller needs the result immediately (agent tool during a live call)
  • Total expected duration is well under 30 seconds
  • No Wait steps
  • Low-latency response matters

When to use async

  • The workflow has Wait steps longer than a few seconds
  • The workflow has a Loop step over more than a handful of items — iterations run one after another, so the time adds up
  • The workflow has a Parallel step over more than 10 items — that is the sync ceiling; async allows 200
  • Total duration could exceed 30 seconds
  • Retry on failure matters
  • The caller doesn’t need the result synchronously
  • High-concurrency batch processing

Sync execution

Success response:
Failure response:

Keeping input out of the run record

A run stores its input with the rest of its record, where anyone who can view the workflow’s runs can read it. When the caller has to pass something that should not stay there, such as a session token or a signature, list where it sits in redact_input, next to input_data in the request body:
The steps get the real values, and so does the caller: the response returns the run’s results as they are, with only credential values replaced, as always. redact_input changes what the run keeps and what it reports:
  • In the stored run, the input shows «redacted» at each path, whatever the value, and so does every copy of the whole input: the first step’s output, which is the input as the run received it, and any step that outputs or sends the whole input, such as a Transform returning {{ trigger }} or an HTTP step sending it as its JSON body.
  • A value copied anywhere else in the stored run, whether into a step’s output, a request, an error message, a string such as a raw body, or another field of the input, is replaced the way credential values are: by exact match, and only if it is a string of six or more characters. A shorter string, a number or a boolean copied like that stays, and so does a transformed copy (hashed, encoded, sliced). Exact match cannot tell where a value came from either, so an equal value from somewhere else is replaced too: a CRM record the run fetched shows «redacted» in the stored run if it holds the email the caller hid. A key that happens to equal a hidden value is left as it is.
  • Logs and error reports lose every redacted value, however short, and error reports for these runs carry no request body or local variables.
  • A run that fails outright answers with an error message that has the redacted values taken out.
A path is keys joined by dots, up to 50 paths. A path with an empty or blank key is rejected with the rest of the request, as a validation error (422). A path that names nothing is skipped, and its name is logged. A path that runs into a list, a string, a number or null before its end hides that whole value, and is logged too: nothing asked for leaks, at the cost of whatever sits beside it. redact_input works on sync runs only. /async rejects a non-empty redact_input with a 400, because an async run reads its input back from the stored record.

Async execution

Immediate response:
Poll for the result: