HIL Continuation
How to build node executors that pause a workflow, deliver a human-review payload to any messaging channel, and resume execution after the human responds — all without touching the execution engine.
What Is HIL Continuation?
Human-in-the-Loop (HIL) continuation is the pattern where a workflow durably suspends mid-execution, presents data to a human via some channel, waits for their response (approve / reject / edit values), and then resumes exactly where it left off — incorporating whatever the human provided.
The BizFirst execution engine handles the suspension and resumption mechanics. As a node developer, your job is to:
- Read the
NodeFieldManifestto know which fields the human should see and how. - Format and deliver those fields to the target channel (Slack, WhatsApp, email, etc.).
- Return the
"waiting"port key to trigger suspension. - Implement a webhook handler that calls
ContinueAsyncwhen the human responds.
The Core Insight
Every HIL channel — regardless of how different the delivery mechanism is — funnels into a single, universal resume gate:
IWorkflowContinuationOrchestrator.ContinueAsync(executionResId, responseData)
That call is all the engine needs to resume. It doesn't know or care whether the human
clicked a Slack button, replied to a WhatsApp message, or submitted a web form.
The ExecutionResId is the key that ties the external response back to the
correct suspended workflow.
Channels Covered in This Guide
Slack
Block Kit interactive messages with button and input actions
Business API interactive messages, template messages, reply webhooks
Facebook Messenger
Send API with button templates and quick replies
Instagram Messaging API — same foundation as Messenger
Telegram
Bot API with InlineKeyboardMarkup and callback queries
Microsoft Teams
Adaptive Cards via Bot Framework — enterprise approval flows
HTML email with signed resume-URL buttons — no bot required
SMS / Twilio
Reply-keyword approach with phone-number session correlation
Discord
Message components with button interactions and interaction webhooks
LINE
LINE Messaging API with Quick Reply and Confirm template messages
What Stays the Same Across Every Channel
| Concern | Who handles it | Stays the same? |
|---|---|---|
| Suspending execution | Engine — return "waiting" port | Yes — identical for all channels |
| Serializing state to SQL | Engine — ISuspendedExecutionRegistry | Yes |
| Which fields to show | NodeFieldManifest.HilPolicy | Yes — declared on the node type |
| Field visibility / edit rules | HilPolicy.DisplayMode / InputMode | Yes — same policy, rendered differently per channel |
| Resume gate | ContinueAsync(resId, data) | Yes — identical for all channels |
| Message formatting | Your channel node executor | No — each channel has its own format |
| Delivery mechanism | Channel API (Slack, WA, etc.) | No — each channel API is different |
| Correlation key embedding | Your webhook handler pattern | Mostly — strategy varies by channel |