Webhook
An HTTP callback that a provider sends to a URL you own when an event occurs, so you receive changes as they happen instead of polling for them.
Polling asks “has anything changed?” on a timer, and wastes most of its calls hearing “no”. A webhook inverts that: you register a URL, the provider posts to it when something happens, and you find out within seconds.
The convenience hides a set of obligations that a receiver has to meet.
Verify the sender. Your endpoint is public. Most providers sign the request body with a shared secret and put the signature in a header. Verify it before parsing anything, and compare using a constant-time function. An unverified webhook endpoint is an open write path into your system.
Respond fast, work later. Providers time out, often in five or ten seconds, and count a slow response as a failure. Acknowledge with a 200 as soon as the payload is stored, then process asynchronously. Doing the work inline is the most common cause of duplicate deliveries.
Expect duplicates and reordering. At-least-once delivery is the norm, so the same event can arrive twice, and event 2 can arrive before event 1. Store the provider’s event id and skip ids you have already handled. This is idempotency applied at the receiving end.
Notice when they stop. A webhook that stops arriving generates no error, because nothing happened on your side. Registrations get lost during a redeploy, endpoints get disabled after too many failures, and secrets get rotated on one side only. Track the timestamp of the last received event per source and alert when it exceeds the normal gap. Without that check, this is a textbook silent failure.
A concrete example. A payment provider posts invoice.paid to your endpoint. You verify the signature, write the raw body and event id to a table, return 200 in under 100ms, and a separate worker reconciles the invoice. The provider retries after a transient network fault, your handler sees the duplicate event id, and skips it.