Inbound and outbound, both signed
Every webhook is HMAC-signed, replay-protected, retried with backoff, and dead-lettered on persistent failure.
Inbound
External service → public edge route → signature verify → workflow.
Inbound contract
| Endpoint | /api/public/webhook/:id (auth bypass, signature required) |
| Verification | timingSafeEqual on HMAC-SHA256(rawBody, secret) |
| Idempotency | Reject duplicate event.id within 24h window |
| Replay window | Reject if |now - timestamp| > 5 min |
| Failure | 401 → caller retries · invalid sig → DLQ |
Sample event
{
"id": "evt_01HZX...",
"type": "invoice.paid",
"occurred_at": "2026-05-12T09:00:00Z",
"payload": { "amount": 1299, "currency": "usd", "customer": "cus_…" }
}Outbound
Workflow emits → signed → POSTed with retries → customer endpoint.
Outbound contract
| Headers | X-Assistant-Signature, X-Assistant-Timestamp, X-Assistant-Event-Id |
| Retry | Exponential backoff: 1s, 5s, 30s, 2m, 10m, 1h |
| Cutoff | Give up after 24h or 8 attempts → DLQ + Slack alert |
| Concurrency | Per-endpoint rate limit, ordered delivery optional |
| Audit | Every attempt logged with status, latency, response snippet |