Webhooks
Let customers subscribe to events in your product and receive HTTP POSTs when those events occur.
Options
Delivery Guarantees*
Payload Security*
Customer Visibility
Decision Points
Do any of your events drive financial or provisioning actions on the consumer side?
If yes
Choose at-least-once delivery, document a stable event ID for deduplication, and expose a delivery log.
If no
At-most-once may be acceptable but is rarely worth the simplification.
Does event order matter to downstream consumers?
If yes
Use ordered delivery with per-resource partitioning. Accept head-of-line blocking.
If no
Unordered at-least-once is simpler and faster under load.
Should you also offer pull/polling as an alternative to push?
If yes
Expose an events API with cursor pagination alongside webhooks. Handy for consumers behind firewalls or ones that want to catch up after downtime.
If no
Push-only keeps surface area small; customers recover via the replay button.
Are webhook payloads HMAC-signed with a per-endpoint secret?
If yes
Follow the Stripe pattern — HMAC-SHA256 over timestamp + body, with the signature in a dedicated header. Publish sample verification code in 3+ languages.
If no
Unsigned webhooks are a security bug — always sign, even on internal endpoints.
Do signed payloads include replay protection (nonce or timestamp tolerance)?
If yes
Include a timestamp in the signed bytes; reject on the consumer side if skew exceeds 5 minutes. Document the tolerance window.
If no
Without timestamp enforcement, any captured webhook can be replayed forever — not acceptable.
Can customers filter which events a given endpoint receives?
If yes
Let them subscribe per event type (order.created, invoice.paid). Reduces their noise and your outbound volume.
If no
Fire every event to every endpoint — simpler but wasteful at scale.
Do customers need a dead-letter / failed-delivery view they can inspect and replay?
If yes
Build a parked-events queue per endpoint with a "replay" action. Cuts support load dramatically.
If no
Without it, every failed delivery becomes a support ticket.
Should customers see the last N delivery attempts with response bodies?
If yes
Retain 30–90 days per endpoint with status, response code, and latency. Absolute table stakes for any B2B webhook product.
If no
Customers will open tickets asking "did you send it?" — just build the log.
Do you need per-endpoint rate limiting / concurrency caps?
If yes
Cap in-flight deliveries per endpoint (e.g. 4 concurrent) to prevent one slow consumer from starving workers. Critical for multi-tenant fairness.
If no
Unbounded concurrency invites a DoS from your own system when a consumer slows down.
Can customers register multiple endpoints per event type?
If yes
Fan out to every active subscription. Useful for dev/staging/prod mirrors and third-party integrations.
If no
One endpoint per event type is simpler but frustrates customers with multiple consumers.
Do you validate endpoint URLs with a challenge/response before activating?
If yes
POST a challenge to the URL and require echoing a signed token — prevents typos and unauthorized URLs. Standard pattern (Slack Events API).
If no
Mis-entered URLs become silent delivery failures the customer can't diagnose.
Do any enterprise customers require mTLS on outbound deliveries?
If yes
Plan per-endpoint client-cert management and renewal; offload to a proxy (Envoy) that handles cert lifecycle.
If no
HMAC signatures + IP allowlist cover 99% of enterprise security review.
Do you ship SDK helpers to verify signatures in customer languages?
If yes
Publish verifyWebhook(body, header, secret) in Node, Python, Ruby, Go, PHP. Reduces integration bugs dramatically.
If no
Customers will implement signature verification wrong — expect security tickets.
Do webhook payload schemas need explicit versioning?
If yes
Either subscribe-per-version (Stripe style) or additive-only schemas. Retrofitting versioning after launch is painful.
If no
Lock the schema early and commit to additive-only changes — no renames, no removals.
Tradeoffs
One slow consumer blocks subsequent events for the same resource
High write volume to log storage — plan for hot shards if a customer has thousands of endpoints
Slight CPU cost per delivery; negligible compared to network I/O
Go Deeper
Failure isolation between tenants
One slow or broken consumer must not starve everyone else.
Event schema versioning
You will want to change payload shapes, and consumers you don't control will break.