Register HTTP endpoints to receive workflow events when intake is submitted. This is the primary integration path for CRM sync, database writes, email triggers, and internal queues.
Use the same shell variables as the first onboarding tutorial: BASE=https://willowriverautomation.com/relay, API_KEY, and FLOW_ID.
curl -X POST "$BASE/v1/flows/$FLOW_ID/webhooks" \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/intake",
"events": ["intake.submitted"]
}'
The response includes a secret for signature verification. Store it securely.
{
"event": "intake.submitted",
"flow_id": "550e8400-e29b-41d4-a716-446655440000",
"flow_version": 1,
"intake_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8",
"data": {
"email": "dev@acme.com",
"company": "Acme",
"plan": "pro"
},
"metadata": {
"ip": "203.0.113.1",
"user_agent": "Mozilla/5.0 ..."
},
"created_at": "2026-05-21T12:00:00Z"
}
Each delivery includes:
| Header | Value |
|---|---|
X-Intake-Signature |
HMAC-SHA256 hex digest of raw body |
X-Intake-Event |
Event name |
X-Intake-Delivery-Id |
Delivery UUID for idempotent processing |
import hmac, hashlib
def verify(secret: str, body: bytes, signature: str) -> bool:
expected = hmac.new(secret.encode(), body, hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, signature)
Failed deliveries (non-2xx or timeout) are retried with exponential backoff. Available on all plans (Free, Starter, Growth, Scale).
| Attempt | Delay |
|---|---|
| 1 | immediate |
| 2 | 30s |
| 3 | 2m |
| 4 | 10m |
| 5 | 1h |
After 5 attempts, status is failed. Inspect via:
curl "$BASE/v1/flows/$FLOW_ID/webhooks/deliveries?submission_id=$INTAKE_ID" \
-H "Authorization: Bearer $API_KEY"
Use intake_id + X-Intake-Delivery-Id to deduplicate. Your handler should return 2xx only after successfully processing.
User completes intake embed
↓
intake.submitted webhook
↓
Your handler:
1. Create CRM contact
2. Provision tenant
3. Send welcome email
4. Update user record
This replaces custom webhook form system code in your backend.