Five flow recipes
Five working flow definitions you can paste into the Flows API today: a welcome series, an appointment reminder, support triage, survey collection, and order updates. Each recipe covers the trigger to pick, the fulldefinition JSON, and what a run does.
Every sample below is a <CodeGroup> with three tabs: the raw cURL call, the typed Node.js SDK route (orbit.flows.create / orbit.flows.execute), and Python as plain requests (the same convention the generated tabs use, so it runs without installing the SDK). Each recipe also ends with the response envelope to assert against — GET /flows/{id} returns the same shape the create call answered with, so you can verify the persisted flow without leaving the page.
The Flows overview covers trigger types, node semantics, and edge handles; this page assumes those concepts and goes straight to definitions. Build your first automation flow walks one flow design end to end — this page gives you the other five.
1. Choose the trigger
Every flow starts from exactly one trigger, declared top-level astrigger_type.
Two rules before the recipes:
- Gate business-event triggers.
contact.createdfires on API imports and CSV uploads too, not just your signup form. Put a Condition first, or a 50,000-row import tags along behind your welcome SMS. - Variables are flat. Write
{{first_name}}, never{{contact.first_name}}. A placeholder for a missing key renders as an empty string — so a webhook flow referencing a key the caller didn’t post sends an empty body. Validate with Test mode before publishing.
POST /flows/:id/execute accepts an optional trigger_data object and answers with the persisted execution_id — assert on that before subscribing to webhooks.
2. Recipe 1 — welcome series
Shape: contact created → gate → welcome SMS → wait 24h → follow-up email. New contacts get an SMS immediately and an email the next day. The condition gate keeps imports and API batches from entering the series.GET /flows/{id} returns (the create call answered with 201 and this same shape; re-reading it confirms what persisted before you publish):
contact.created event starts one run. Runs where source is not signup_form exit at the gate (no has no target, so the run ends cleanly). The 24-hour delay parks the run in waiting status and resumes automatically — long waits never send early. The same series is available in the dashboard’s New Flow template list under Welcome SMS; the API route above adds the import gate and the email step.
3. Recipe 2 — appointment reminder
Shape: booking webhook → confirm-or-reschedule at T-24h → final ping at T-1h. Your booking system POSTs when an appointment is scheduled; the flow fires the webhook intowait_24h (a T-24 reminder, booked appointments get a confirmation request) and then the T-1 ping. Booking-time context carries appointment_at — the delay offsets are scheduled against it.
The two wait nodes are date-relative, so a booking made Monday for Wednesday lands the confirmation message Tuesday, not two days after booking.
GET /flows/{id} returns the persisted flow (create answers 201 with the same envelope; the webhook URL the caller posts to lives in the flow detail and webhook surface):
{ "appointment_at", "appointment_time", "first_name", "phone", "location", "reschedule_link", "sms_opt_in": "true", ... } to the flow’s webhook URL. Contacts without opt-in exit at the gate. The T-24 message carries the confirm/reschedule call-to-action; the T-1 message is a bare logistics ping on the channel the tenant’s inbox monitors. The dashboard template Appointment Reminder (24h + 1h) is the same skeleton — clone it from New Flow if you’d rather click than write the definition yourself.
4. Recipe 3 — support triage
Shape: inbound message → classify intent → AI agent answers → complaints escalate to a human. Inbound SMS (or WhatsApp) hits an inbound-routing rule that starts the flow. An AI Classify node routes by intent; the agent handles routine questions; complaints fan out to your team’s escalation webhook; anything unrecognized ends for manual pickup.201 with the persisted flow (assert on data.id before wiring the inbound-routing rule), and a manual one-off run via POST /flows/{id}/execute answers 202:
execution_id and status; a synchronous single-run execution that finishes inline returns status: "completed", while a waiting run resumes later under the scheduler.
Expected behavior. The classifier routes on the matching intent edge; yes/no handles exist as fallbacks — other and unrecognized classifications end the run when no edge carries them. The webhook node’s body carries execution_id and the sanitized run context, so your helpdesk gets the message text and intent. Webhook URLs must be public; private or internal addresses are rejected. Provision the two agents first — agent_id pointing at a non-existent agent fails the run at that node (with an entry in the step trace), not a graceful fallback.
Routing start: wire the inbound-routing rule to this flow (see Where Flows Fire).
5. Recipe 4 — survey collection
Shape: post-call event → wait → send the survey → responses arrive at your webhook. After a call completes, wait a day, then send the NPS or CSAT survey over SMS. Recipients answer on the hosted page via the single-use token link in the message; each response fires a webhook event you capture at your endpoint.GET /flows/{id} returns the persisted flow (create answers 201 with the same shape; the sendSurvey node only renders when the referenced survey exists):
survey_id references a survey you created in the Surveys API; channel accepts sms, whatsapp, email, viber, rcs, or push. A missing or unsupported value skips the node with a skipped output in the step trace — check it in Test mode, because a typo’d channel does not fail the run. Recipients receive the single-use survey link; responses land as survey.nps.response_recorded and survey.csat.response_recorded webhook events, and a low score additionally fires survey.response.detractor. Subscribe to those events (see Webhook Events) to close the loop — page a CSM on a detractor, for example.
6. Recipe 5 — order updates
Shape: commerce webhook → SMS + email fan-out. Your commerce layer (Shopify, a custom storefront, an OMS) POSTs order events — confirmation, shipped, delivered, exception. The flow fans out on both channels. Draw a branch per event stage by chaining a condition on theevent key, or run one flow per stage with its own trigger filter.
GET /flows/{id} returns the persisted flow (create answers 201 with the same shape; the has_email gate keeps phone-only contacts out of the email step):
order_id, first_name, phone, email, tracking_url, review_link); both messages render those values inline. Every contact gets the SMS; the has_email gate skips the email step for phone-only contacts (an empty email resolves to an empty string, so the test is email != ""). When one flow covers several stages, chain conditions on the event key the storefront posts — order.confirmed, order.shipped, order.delivered.
7. Validate before launch
Three tools, in the order to use them. The same cURL + SDK pattern applies to each:GET /flows/:id/validate checks the definition parses and stays structurally sound:
valid: false with a populated errors array when the graph has a problem.
2. Test mode and the simulator. Click Test in the builder toolbar to walk the flow with sample data and watch the exact branch each node takes. Then, before any schedule or event trigger touches real traffic, dry-run the flow against your real audience size — no contact is enrolled, nothing is sent:
POST /flows/:id/simulate projects the per-step funnel, the channel mix, the projected send cost at your live rates, and a predicted conversion; the numbers land under data alongside the same meta.request_id envelope every route returns:
GET /flows/:id/analytics returns entered / completed / converted counts and the per-node drop-off funnel; GET /flows/:id/ab-results rolls up any abTest node variants with the leading variant. The simulator’s assumed drop-off converges on this history as runs accumulate, so forecasts get sharper over time:
flow.execution.failed pages you instead of a silent drop-off.
Next steps
- Flows overview — trigger catalog, node taxonomy, edge semantics
- Build your first automation flow — the design walkthrough for recipe-style flows
- Flow Builder — canvas reference and the template library (New Flow dialog)
- Flow Executions — the step-trace reference for debugging runs
- Webhook Events — every event you can subscribe to