What it is
A webhook is a way for one system to notify yours by sending an HTTP request, usually a POST with a JSON body, to a URL you registered. Instead of you polling "any new orders?" every minute, the provider calls you when an order appears. GitHub, payment providers, chat platforms and many model vendors use this pattern. The request is still just HTTP. Nothing about the word webhook makes the body true.
It is the reverse of the usual API call. Normally your server is the client. With a webhook, your server is the receiver and must be reachable from the internet, or from a tunnel during development.
Why and when it is used
Use a webhook when you need to react to an event in another system and polling would be slow or wasteful: a payment succeeded, a pull request opened, a file finished processing. Use polling when the provider has no webhook, when you are behind a firewall you cannot open, or when a short delay is fine and simpler.
Do not point a webhook at a URL that runs arbitrary actions without checking who sent it. Anyone who learns the URL can POST. Security through an unguessable path is weak once the URL leaks into logs. Prefer a signature.
How it works
You register a URL and a secret in the provider's settings. When an event happens, the provider POSTs the payload and a signature header, typically an HMAC of the raw body with the secret. Your handler reads the raw bytes, computes the HMAC, and compares in constant time. If it matches, you enqueue the work and return 2xx quickly. If it does not, you return 401 and do nothing. Providers retry on failure, so your handler must be idempotent: the same event id delivered twice must not charge twice or create two records. Store the event id you have already processed.
Timeouts are tight. Do not call a slow model or a slow third party before you acknowledge. Acknowledge, then process on a queue. If you process first and the process crashes after the side effect but before you answer, the retry will do the side effect again unless you recorded the event id.
Technologies and dependencies
A public HTTPS endpoint (Express or any framework), the provider's signing secret in Environment Variables or a secret manager, and a store of seen event ids. API Keys are a related secret but a signature is tied to the body, which a bare bearer key on a webhook is not always. Authentication versus Authorization applies: the signature authenticates the sender; your code still decides what the event is allowed to change. CI and CD should not log the secret when you set it.
How to get started
- Read the provider's signing documentation. Note the header name and whether the signed payload includes a timestamp.
- Expose a local server through their recommended tunnel or a test event in staging. Do not use production data on day one.
- Log the event id and type only. Verify the signature and reject a tampered body in a test.
- Record the event id and return 200. Process the work after that, or in a background worker.
- Send the same event twice and prove you do not duplicate the side effect.
- Rotate the signing secret once so you know how.
Reject requests with an old timestamp if the provider signs one. That limits replay of a captured body.
Cautions and trade-offs
Parsing JSON before you verify, then verifying a re-serialised body, breaks signatures because key order and spacing changed. Verify the raw bytes. Returning 200 on a signature failure to "stop retries" hides attacks. Return a client error for bad signatures and 200 only when the event is accepted or safely ignored.
Webhooks fan out. A bug that creates a document per retry will create many. A handler that assumes the event's account id is yours, without checking, will apply another tenant's event if the provider ever misroutes or if you share an endpoint unwisely. Bind events to the tenant that installed the integration. Finally, a webhook is an availability dependency in the other direction: if your endpoint is down, the provider's retries eventually stop. Know the retry window and have a way to backfill, or you will silently miss a payment or a permission change.