Designing a Webhook Replay Strategy
When a provider sends a webhook, it makes an HTTP request to notify your service about an event, such as a changed…
When one service needs to notify another about an event, it can send an HTTP request to a URL the receiving service has configured. That notification is a webhook. The receiving service returns an HTTP response to acknowledge the request, and the provider’s documentation defines what happens when that response is late, unsuccessful, or missing.
Compare what each provider’s numbers measure and what happens after a failed delivery. A timeout might measure connection setup, response time, or a full delivery attempt. A retry window might cover the provider’s automatic attempts, the period when an operator can request another attempt for an earlier delivery (manual redelivery), or both. Reading those terms in context helps you determine what your endpoint must acknowledge, which failures the provider will retry, and how you can recover an event.
A timeout value only makes sense when you know which part of delivery it covers. A connection timeout limits how long the provider waits to connect to your endpoint. A response timeout limits how long it waits for your endpoint’s reply. A total delivery budget can include more than one attempt.
The documented examples illustrate why a direct comparison of seconds can mislead:
| Provider and documented mechanism | Timeout behavior |
|---|---|
| GitHub webhooks | GitHub records a delivery as failed if the server is down or takes longer than 10 seconds to respond, according to its failed-delivery documentation. |
| Twilio legacy URL connection overrides | Twilio separates connection, read, and total time. The documented defaults are 5 seconds for connection and 15 seconds for read and total time; the total includes retries. The settings apply to the legacy override mechanism, and Twilio documents a 15-second cap for voice-call requests in its connection override documentation. |
| Adyen webhooks | Adyen marks a webhook as failing and queues it for retry if it does not receive a successful response within 10 seconds, as described in its event handling documentation. |
Check whether each number is a fixed deadline or a setting you can change. The cited GitHub page states a 10-second response deadline but does not describe a setting for changing it. Twilio’s figures belong to a specific legacy configuration mechanism, so confirm that the mechanism and product apply before comparing those values with another provider’s deadline.
When an endpoint performs slow business work, separate acknowledging the webhook from completing that work. Adyen recommends accepting and storing the event before handling business logic. The response confirms receipt, but the service can still be doing the business work afterward.
“Retry policy” can refer to which failures trigger another attempt, how many attempts the provider makes, or how long it keeps trying. Compare those details separately.
Twilio’s legacy connection settings let an operator configure a retry count from 0 to 5, with a documented default of 1, and choose which conditions trigger retries. Twilio lists HTTP 4xx and 5xx responses as retry conditions. It also lists connection or TLS failures and read timeouts. A status code alone therefore does not tell you whether Twilio will retry; the selected policy matters.
GitHub documents no automatic redelivery of failed webhook deliveries. Adyen instead places failed messages in a retry queue and retries for up to 30 days. Its troubleshooting documentation describes retry intervals ranging from 30 seconds to as long as 8 hours. Compare the attempt count and retry window separately. An attempt count limits how many times the provider tries; a retry window limits how long it keeps trying.
Also check what the provider calls a failure. A timeout, a connection error, and an HTTP error may have different consequences under the same provider’s rules. Adyen’s troubleshooting page lists response codes such as 401, 404, and 422 as diagnostic clues. It also lists 429 and 500. Read those codes as part of that provider’s guidance rather than assuming every vendor treats them the same way.
A webhook’s destination is the URL that receives the event. Routing rules can also determine which delivery settings apply to that destination, so find out both where the event goes and how the provider selects its configuration.
Twilio’s Webhooks configuration API matches a destination URL to a Rule, then applies the Setting selected by that Rule. An exact URL match takes priority over a prefix Rule, which matches URLs that start with its path. The default Rule comes last. Paths are case-sensitive, and a prefix Rule must end in a slash. Twilio also documents a propagation period for changes. During that interval, a recently edited rule might not yet govern deliveries. The configuration FAQ explains these matching and timing rules.
Check how the selected settings interact with older URL-level configuration. Twilio says a Rule-based Setting replaces the URL connection overrides. The provider does not combine the two configurations. If a delivery behaves differently than expected, inspect which Rule matched and whether the provider has propagated the change. The configuration API documentation describes the Rule-and-Setting model. The GitHub and Adyen pages cited here focus on delivery and recovery; they do not establish an equivalent URL-rule precedence model.
Providers use different recovery mechanisms, and those mechanisms do different jobs. Automatic retry repeats a queued delivery under provider rules. Manual redelivery lets an operator or API request another attempt for a specific past delivery. A fallback URL sends a request to an alternate destination under specified conditions; it does not, by itself, replay a stored historical event.
GitHub supports redelivery through its interface or REST API for deliveries from the past three days. That three-day period is a recovery lookback, not an automatic retry window. The redelivery documentation also notes that permissions depend on the webhook type.
Adyen’s Customer Area lets an operator retry a failed message after addressing the cause or ignore it to remove it permanently. Its automatic queue retries continue for up to 30 days. Twilio’s connection documentation discusses fallback behavior, but fallback is distinct from replaying a past delivery; check the provider’s fallback and connection guidance for the behavior relevant to your configuration.
For each provider, record whether recovery is automatic or operator-triggered, whether an API is available, how far back recovery reaches, and whether an action discards the event. If the documentation does not specify one of those details, treat it as an open question rather than assuming the feature exists.
A useful comparison records what an endpoint must do and what an operator can inspect. For each provider and webhook product, note when the timer starts and which response or network conditions count as failure. Record which conditions trigger retries, then whether the limit is an attempt count or a time window. Also record the visible failure state, routing precedence, and configuration interactions. Note the recovery method and period, along with permissions.
An endpoint that takes longer than GitHub’s stated response deadline produces a failed delivery record. Under Adyen’s guidance, an endpoint can acknowledge receipt before finishing its business work, then rely on separate processing. The providers attach different outcomes to the same 10-second response deadline.
Treat documented values as provider- and mechanism-specific. Confirm the applicable product, configuration method, and current documentation before using a number as an implementation requirement.
Give Vroni a GitHub issue, bug report, spec, or rough idea. It reads the repo, plans the change, writes code, runs checks, and works toward a review-ready pull request.
Take a look at vroni.com