2:14 a.m. — three Slack messages, not one
It is 2:14 a.m. and the invoice routing workflow on FlowForge just paged on-call — except the "page" is three Slack messages arriving in the next ninety seconds, not a PagerDuty alert. The first tells the channel the downstream billing API returned a 502 on the last hop. The second fires ninety seconds later and lets the team know the recovery rule kicked in, retrying the same run with exponential backoff set for three attempts. The third, when it lands, confirms the customer ledger has a row for the same invoice — the retry succeeded and an idempotent row was written without anyone getting out of bed.
What "multi-step orchestration" means on FlowForge
Most workflows on FlowForge start as a single chain — a trigger, a fan-out, a fan-in, and a single downstream the run lands on. Multi-step orchestration is what happens when that chain fans out across more than one tool — a billing API here, a Slack thread there, a ledger write downstream — and the success of every step depends on the workflow keeping an idempotent view of the same business process. The runtime’s job is to keep the upstream and downstream coherent even when one of the tools is failing or rate-limiting, so the run only ends when every signal has either completed or fallen back to a known terminal state. That is the work the on-call watcher is paying attention to at 2:14 a.m. — and that is the work that arrives as three Slack messages, not one, when the recovery rule does its job correctly.
A worked example — the invoice routing kit
The starter kit ships with a single recovery rule that fans out three signals the moment a downstream fails. In our example render we use a ### Example subhead followed by one bullet per signal, each value wrapped in inline backticks because the blog renderer (see lib/markdown.js) does not support fenced code blocks.
Example
- trigger:
downstream_502 on /invoices/ingest - retry:
exponential, base 500ms, max 3 attempts - alert_1:
post a Slack message into #ops-alerts with the failed run id - alert_2:
post a follow-up Slack message once the retry succeeds - alert_3:
write an idempotent row to the customer ledger keyed by invoice_id
Read together, this says: when the billing API returns a bad gateway at the /invoices/ingest endpoint, retry three times with progressively longer waits, post a Slack alert when the run first fails, post a follow-up alert when the retry succeeds, and write a single ledger row the moment the response lands. The same three-signal shape is the default on the lead enrichment starter and the customer support kits — copy a kit, copy a rule, copy the whole workflow.
Closing the loop
Without the rule, the on-call would have flipped a switch by hand at 2:14 a.m., the customer success team would have noticed three thousand missing invoices before anyone did, and the ledger row would have ended up written twice for the same payment. With the rule in place, three Slack messages land in the channel and the ledger has a single row — and the human only looks at the run if the thread is still stuck after the third message. That is the entire point of multi-step orchestration: the workflow reasons across the tools it touches, and the human only sees the result.
Wire it into your stack
- Open the operations hub to see the three starter kits (lead enrichment, invoice routing, customer support) that ship with three-signal recovery rules preconfigured.
- Open the invoice routing starter kit directly to copy the rule — or the whole workflow — into your own pipeline.