Skip to main content
POST
Create automation
This endpoint creates an automation from its definition (a trigger and its chained steps), activates it, executes a real test run with your sample payload, and reports the result step by step. The test run is the gate: an automation whose test fails is left disabled, and an assistant-event automation is only attached to the assistant after its test passes. When a ready-made template matches what you need, applying it is simpler than writing a definition from scratch.
The test run executes the automation for real. Definitions containing steps that send messages or emails, or start calls, are refused unless you explicitly pass confirm_side_effects: true — and when you do, those steps really send during the test. Point them at recipients you own.

The definition format

The flow object is the automation’s definition. The preferred shape is a flat list:
The steps are chained onto the trigger in the order given. The only nesting you write yourself is inside a step that needs it — a BRANCH step’s conditional steps go under its onSuccessAction / onFailureAction. (A hand-nested tree, where each step sits under the previous one’s nextAction, is also accepted.) A definition always replaces the whole automation — it is never merged. A trigger with no steps is rejected (no_steps): an automation that does nothing cannot be activated. Supported triggers (trigger.settings): Steps reference earlier output by step name — {{step_1['body']['field']}} for HTTP steps (their JSON nests under body). Common step shapes: HTTP requests, code transforms, branches, delays, respond steps, and platform actions (send SMS/WhatsApp, start a call, re-queue a lead). The easiest way to learn a step’s exact shape is to read an existing automation with Get automation or apply a template and inspect what it built.

Request body

string
required
A short human name for the automation (max 255 characters)
object
required
The automation definition — {"trigger": {...}, "steps": [...]} as described above. Max 1 MB.
object
A realistically-shaped sample payload for the test run (what the trigger will receive). For assistant events, a canonical sample built from the assistant’s own variables is used when omitted. Max 256 KB.
integer
Required for assistant-event automations (phoneCallEnded, inboundCall, newConversation, and bind_webhook): the assistant this automation attaches to. It starts receiving that assistant’s real events after the test passes. (For the platform triggers, selecting the assistant inside the trigger’s settings.input.assistant also works — the explicit parameter wins.)
string
For a webhook-triggered definition only: attach it to the assistant’s conversation-ended event. The only supported value is conversation_ended. Requires assistant_id.
boolean
Required (true) when the definition contains steps that send messages or emails, start calls, or make non-GET HTTP requests — the test run executes them for real.

Response

Returns 201 when the automation is active (active / active_untested), 200 when it was built but its test run failed (test_failed), and 422 for a definition that never reached the test run (see error codes below).
string
The ID of the created automation
string | null
For webhook-triggered automations (including conversation-ended ones): the URL external systems call to fire it. null for assistant-event and schedule automations.
string
  • active — the test run passed; the automation is live (and attached, for assistant events).
  • active_untested — the trigger cannot be fired on demand (schedules, external integrations); the automation is live and armed, and the first real event is the proof.
  • test_failed — the test run failed; the automation was left disabled. Read test.steps for the per-step classification.
object
The test run result
object | string | null
For synchronously-tested automations (webhook and inbound triggers): what the automation responded during the test run
object | null
For assistant-event automations: {"type": "post_call" | "inbound" | "conversation" | "conversation_ended", "assistant_id": <id>, "bound": <bool>}. bound is true only after a green test.

Error codes (422)

Hard failures return {"message": "...", "error": "<code>"} and nothing is activated. Notable codes: