Skip to content

build_workflow

build_workflow is where you compose a workflow and check that it holds together. You pass the steps you have so far; it tells you where the next step can go, what it can read there, and what’s wrong. Nothing is saved — hand the same steps to save_workflow when they’re ready.

Steps are a list, in order. Each is {"use": "<block type>", "with": {…}} (the parameters and inputs), and rows flow from each step into the next.

  • Branch with {"if": …, "then": [...], "else": [...]}, {"switch": …}, or "on": {"<port>": [...] | "stop"}.
  • Reference an earlier step’s field as "$<step>.<field>", where a step’s name is its type’s last part (match_company) or its as.

Give every step a name — the few words a person reads for it on the workflows page (the trigger, each block, every if and switch), each one distinct. Where rows end, write a named stop step, e.g. [{"use": "logic.stop", "name": "No company found"}], rather than a bare "stop", which can’t carry a name. The check warns for each unnamed step.

Beside each piece of SQL, write one or two plain sentences saying what happens to the rows — “Keeps only the companies based in the United States.” Describe only the story of what happens to the rows; never a table, a field as written, an SQL keyword, or a data source. Changed SQL needs a fresh description.

To the person, a block is its display name, a setting is its label, a field is its label in words. Never show a block type, a field or port name, raw JSON, a $ reference, or a variable placeholder — those are for tool calls only.

  1. Send [] on the first call.
  2. Add a step at a place the answer’s open lists, choosing from that place’s could_come_next and reading only the fields it says are available there.
  3. Send all the steps back.
  4. Repeat until open is empty and activatable is true.

Each available field carries a tag (the kind of value it holds). An input with a tag reads only a field with that same tag — never a LinkedIn URL for a website input. Set what a trigger’s own field is only when the user has confirmed it. When the builder can’t tell, it returns the question in ask_person with the choices; answer only with the one the user picks.

Steps that read nothing of each other run side by side. Write them one after the other — when a step reads nothing the steps before it produced, the builder places it beside them, and a step that reads several of them waits for all. The answer reports this as side_by_side (each group, in words) and, if your steps were rearranged, rearranged — send the returned steps back, and tell the user which steps run at the same time.

ask_person lists what only the user can settle, each with a question and numbered choices — when the workflow should run, a CRM field their CRM doesn’t have, what one of their own fields is, a variable they need to add, what should happen to rows a step turns away. Ask in plain words and wait for the answer before building on it.

Pass preview_rows (1–10) to dry-run the steps on real rows: reads run for real, while actions and the data lookups a preview stands in for are mocked — nothing is written. A step that acts once for all its rows (a file, an emailed list) reports what it would do in did, so no row looks lost.

Steps that hold an SQL step are previewed on 3 real rows even without preview_rows (previewed_automatically says so) — read each SQL step’s status, errors and rows and fix the SQL before saving. Set preview_rows: 0 to turn preview off.

If the workflow emails, the answer includes emails: who each one goes to and why. Tell the user.

ParameterTypeRequiredDescription
stepsobject[]YesEvery step written so far ([] on the first call).
answersobjectNoAnswers to the builder’s questions — {question id: choice index} or {question id: {op, value}}.
preview_rowsintegerNoAlso dry-run on up to this many real rows (1–10). Omit to preview SQL-holding steps on 3; 0 previews nothing.
webhook_payloadobjectNoA sample body for previewing a webhook-triggered workflow.
target_tenant_idstringNoSuper-tenant administrators only.

The main fields of the answer:

  • steps — your steps, with any fix the builder was sure of written in and independent steps placed side by side. Send these back next time.
  • valid, activatable — whether the steps are sound, and whether they’re complete enough to activate.
  • open, optional, fields_here, blocks — where the next step can go, what’s optional, the fields available, and the blocks offered there.
  • problems — errors, warnings, and questions (each with an id and choices, answered via answers).
  • ask_person — what only the user can decide.
  • preview — the dry-run result, when requested.