Skip to main content

Webhook Dispatcher — Service Overview

Status: populated Owner: Platform Engineering Last updated: 2026-04-18 Companion: DOMAIN_MODEL · API_CONTRACTS · EVENT_SCHEMAS

1. Purpose

The Webhook Dispatcher delivers signed HTTP POST notifications to customer-registered webhook endpoints whenever a delivery receipt (DLR) event is processed. It consumes webhook.dispatch events from NATS JetStream, resolves the target URL(s) for the event's accountId, signs the payload with HMAC-SHA256, and delivers the notification with configurable retry and exponential backoff.

After all retry attempts are exhausted, the delivery is routed to a dead-letter NATS subject and the hook.delivery_attempts record is marked DEAD_LETTER.

2. Responsibilities

ResponsibilityDescription
Webhook CRUDREST API for customers to register, update, and delete webhook endpoints
Event consumptionDurable NATS JetStream consumer on webhook.dispatch
Signature generationHMAC-SHA256 signing of each request body with per-webhook secret
HTTP deliveryPOST to customer URL; 5 s timeout; no redirect follow; 2xx = success
Retry with backoff5 attempts: 30 s → 5 min → 30 min → 2 h → 8 h
Retry state in DBAll attempt state stored in hook.delivery_attempts (no Redis)
Dead-letter routingAfter 5 failed attempts: publish webhook.dispatch.deadletter; mark DEAD_LETTER
ObservabilityPrometheus /metrics, structured JSON logs, OTLP traces

3. Position in the Platform

dlr-processor ──► webhook.dispatch ──► webhook-dispatcher ──► customer HTTPS endpoint

├──► hook.webhook_configs (PG) — URL lookup
├──► hook.delivery_attempts (PG) — retry state
└──► webhook.dispatch.deadletter (NATS, on exhaustion)

Customer API (via Kong) ──► webhook-dispatcher REST API ──► hook.webhook_configs (PG)

4. Technology Stack

ConcernTechnology
RuntimeNode.js 20 LTS
FrameworkNestJS 10
LanguageTypeScript 5
Message brokerNATS JetStream
DatabasePostgreSQL 15 (schema: hook)
HTTP clientundici (Node.js native, 5 s timeout, no redirect)
SigningNode.js built-in crypto.createHmac (HMAC-SHA256)
MigrationsFlyway
API GatewayKong (REST API routes)
ContainerisationDocker / Kubernetes
ObservabilityPino (logs), OpenTelemetry (traces), Prometheus (metrics)

5. Non-Goals

  • Does not own the DLR processing pipeline (delegated to dlr-processor).
  • Does not store message content or phone numbers persistently.
  • Does not use Redis for retry state (all retry tracking in PostgreSQL).
  • Does not support protocols other than HTTPS POST.
  • Does not support webhook fanout to > 10 endpoints per account (platform limit).

6. SLOs

MetricTarget
First delivery attempt latency (p99)< 2 s from event receipt
Delivery success rate (at least one attempt)≥ 99% of correlated DLRs
Retry exhaustion rate< 1% of dispatched events
REST API latency (p99)< 200 ms
REST API availability≥ 99.9%