Workflow sequence
- 01Receive intent signal
- 02Score and route lead
- 03Send first message
- 04Wait for reply or behavior signal
- 05Stop or schedule follow-up
- 06Assign human owner
Sequence definition
Use this sequence definition as a starting point. Set tenant_id to your tenant and use a fresh UUID for id before publishing. Implement the named business handlers in your workers; the JSON does not include provider integrations. Keep credentials in the credential store.
{
"id": "e32825f5-41f8-510f-9d0e-8413b946079f",
"tenant_id": "demo",
"namespace": "default",
"name": "event_driven_outreach_v1",
"version": 1,
"deprecated": false,
"blocks": [
{
"type": "step",
"id": "score",
"handler": "score_intent",
"params": {}
},
{
"type": "step",
"id": "send",
"handler": "send_message",
"params": {
"idempotency_key": "{{context.data.lead_id}}:first"
},
"rate_limit_key": "sender:{{context.data.sender_id}}"
},
{
"type": "step",
"id": "wait",
"handler": "human_review",
"params": {},
"wait_for_input": {
"prompt": "Record verified lead activity",
"timeout": 259200000,
"store_as": "lead_activity",
"choices": [
{
"label": "Reply",
"value": "reply"
},
{
"label": "High intent",
"value": "high_intent"
},
{
"label": "Follow-up due",
"value": "followup"
}
]
}
},
{
"type": "router",
"id": "route",
"routes": [
{
"condition": "context.data.lead_activity == "reply"",
"blocks": [
{
"type": "step",
"id": "handoff",
"handler": "assign_owner",
"params": {}
}
]
},
{
"condition": "context.data.lead_activity == "high_intent"",
"blocks": [
{
"type": "step",
"id": "priority",
"handler": "notify_sales",
"params": {}
}
]
}
],
"default": [
{
"type": "step",
"id": "followup",
"handler": "send_followup",
"params": {
"idempotency_key": "{{context.data.lead_id}}:followup"
}
}
]
}
],
"created_at": "2026-09-05T00:00:00Z"
}Handlers must validate required inputs and outputs. Quote extraction returns confidence; document validation returns needs_review; source archiving returns sha256. Guards read these values through outputs, and approval decisions through context.data.
Idempotency keys in params are a contract for your worker to enforce at the provider. They do not make an external write exactly-once automatically.
Steps with wait_for_input resume through an authorized human_input:{block_id} signal carrying a declared choice. A CRM or scheduling integration may supply a verified choice. Timeouts fail the wait; they do not select a follow-up or escalation branch automatically. Configure alerts and recovery for timed-out runs before production.
Review rejection skips the guarded publish or spreadsheet write. No write is authorized merely because the review step finished.
Production controls to keep
✓ Stable idempotency keys around external writes
✓ Explicit validation before the success state
✓ Bounded retries with provider-aware backoff
✓ Searchable source and destination identifiers
✓ A named owner for exhausted retries
✓ A replay test using duplicate input