A webhook is an API call in reverse: their server calls ours when something happens. We now depend on someone else's reliability, and they depend on ours.
Three questions decide whether it works.
Is it really them? Anyone who learns the URL can post to it, so the sender signs the payload with a shared secret and we verify before trusting a byte of it — with a constant-time comparison, because the obvious one leaks the signature a character at a time.
What if we are down? Good senders retry with backoff: minutes, then hours, then a day or more. A deploy window stops being data loss and becomes duplicate delivery instead.
What if it arrives twice? It will — network retries, timeouts, or plain uncertainty on their side. The answer is an event ID and a handler that can run twice without harm, with the ID stored under a unique constraint.
Then acknowledge immediately and do the work in the background. Real processing before responding turns their timeout into our duplicates.
An integration we do not control will fail in ways we cannot prevent. All we choose is whether those failures are survivable.
