1Drive a workflow
Pick an inbound event, then press Run demo to watch one work item move through the state machine while the audit ledger fills.
POST /webhooks
Idempotency-Key: payment-42
{ "event_type": "payment.requested", "payload": {"amount": 2500} } → routes to human_review (amount ≥ 1000)
{ "event_type": "payment.requested", "payload": {"amount": 2500} } → routes to human_review (amount ≥ 1000)
2State machine
Deterministic routing splits intake three ways. Only high-risk / ambiguous work waits for a human; approved work that keeps failing is bounded and parked, never looped forever.
-
Webhook received
-
Completed status 201 branch · route: rules
-
Pending approval
-
Rejected branch · reject
-
Approved
-
Retry pending attempt –/3
-
Dead letter
Legend
Active now
Completed / approved
Retry pending
Rejected / dead letter
3Idempotent intake
The same Idempotency-Key creates at most one workflow. The first
delivery is 201 Created; a replay is 200 OK carrying the original workflow and
duplicate: true, because the retry created nothing.
—First delivery
Awaiting send…
—Replay (same key)
Awaiting send…
4Audit ledger
Append-only history. Every creation, duplicate, decision, failed attempt, and dead letter is recorded — in the real build, into SQLite.
| Time (UTC) | Event | State |
|---|---|---|
| No events yet — run a scenario or send a duplicate webhook. | ||