Skip to main content

1. React fast, trust the resource

The pattern that makes single-attempt delivery safe: treat the event as a signal to look, never as the fact itself.
Two rules in there:
  • Financial events carry a ledger transaction. The thing you care about is usually in relatedOperation, and you should fetch the real resource before acting on money.
  • Resource events carry the object itself, identical to a GET. Acting on the payload directly is fine for cheap decisions.

2. Reconcile what never arrived

Delivery is one attempt. Design as if some events simply never arrive, because some will not.
Sweep against the resource lists, not against your own record of what you expect — the point is to find what you do not know about. Anything that happened while your endpoint was disabled is not recoverable by resend: those events were never staged. Only reconciliation finds them.

3. Route one endpoint across seven services

You get every event on one URL. Route on prefix, not on an exhaustive list.
Note the ordering: card.transaction.* must be tested before card.*, or card payments will be routed to the card lifecycle handler. The final return ok() matters. New event types are added over time, and a receiver that throws on an unrecognised type turns a harmless addition into an outage.

4. Survive a secret rotation

There is no overlap window — the moment a new secret is issued, deliveries are signed with it. Deploy first, rotate second.
Changing the endpoint URL does not rotate the secret, so a host migration needs no key handling at all.

5. Make deduplication real

The id is a header, and deduplication has to be atomic with recording receipt — not a check followed by an insert.
Store the body hash too. A resend reuses the id and payload, so a differing hash under the same id is worth an alert.

What to watch for