Replay Any Webhook Without the Provider — On Your Schedule, With Your Control
Your webhook handler was broken for two hours. Forty-seven events arrived during that window and failed. Your handler returned 500s. Some of those events are Stripe payment confirmations. Some are Twilio call status updates. Some are GitHub deployment notifications that were supposed to trigger a deployment pipeline.
You fixed the handler. Now you need to recover.
What are your options?
Option A: Ask your providers to resend. Stripe supports manual event resending via the dashboard, one at a time, for events within the last 30 days. Twilio does not have a standard event resend mechanism for voice events. GitHub does not resend deployment webhooks. You have 47 events across three providers. Some providers support resending, some do not. The ones that do support it require you to find each event individually in each provider's dashboard and click resend. This process takes about 2 minutes per event, so 90 minutes for 47 events — if every provider supports it.
Option B: Write a script. You write a script that reads your database, finds the affected operations, and re-runs the business logic for each one. This takes 30-45 minutes to write, and you need to be careful not to create duplicates for operations that partially succeeded before the handler went down.
Option C: Use HookTunnel replay. Open the replay view. Filter to the 2-hour outage window. Preview the batch. Execute. Done in 8 minutes. Full audit log of every replay. No provider involvement. No script to write.
Option C requires one thing that options A and B do not: that you were capturing webhooks in HookTunnel before the outage started.
What replay does
Webhook replay in HookTunnel re-sends a captured event to its configured target URL. The replay:
- Uses the exact stored payload — the bytes that arrived from the provider, unchanged
- Uses the exact original headers — including provider signature headers like
Stripe-Signature,X-Twilio-Signature, or custom authentication headers - Sends to the current target URL for the hook (which may have changed since the original capture)
- Records the replay outcome: timestamp, response status, response latency, response body
The replay is not a re-triggering of the original provider action. Stripe does not process a new payment. Twilio does not initiate a new call. GitHub does not create a new deployment. The replay is a direct HTTP POST to your handler with the stored payload. Your handler processes it exactly as it would have processed the original.
This distinction matters for two reasons:
- It is safe to replay payment events without worrying about double-charging customers
- Your handler's idempotency implementation matters — if your handler does not handle duplicate event IDs gracefully, replaying an event that partially succeeded the first time may create duplicates at the application layer
HookTunnel's guardrailed replay builds on this primitive to add receipt-aware safety. But basic replay is useful on its own, particularly for events that never reached your handler at all (where there is no risk of duplication).
Single event replay
From the event detail modal, a Replay button sends the event to your handler immediately. The button shows a spinner during the request and then reports the outcome: the HTTP status your handler returned and the response latency. The replay is recorded in the event's history — you can see every time an event has been replayed, by whom, and what the outcome was.
Single event replay is the right tool when:
- You are debugging a specific event and want to see how your fixed handler processes it
- A customer has reported a specific order or operation that did not process correctly and you have identified the event ID
- You want to test your handler against a real production payload before deploying a fix
Batch replay
From the event list, you can select a set of events for batch replay. The selection tools let you filter by:
- Time range (events from a specific window)
- Delivery status (failed events only, or all events in the window)
- Event type (only
payment_intent.succeeded, for example) - Provider
After selecting events, you run a dry-run preview before executing. The dry run shows:
- Count of events selected
- Estimated duration based on your handler's average response latency
- Risk assessment (are any events already confirmed applied via receipts?)
- Breakdown of event types in the batch
If the risk assessment shows events that are already confirmed applied — events that received receipts indicating the operation was committed by your application — those events are highlighted. You can choose to exclude them from the batch before executing.
After reviewing the dry run, you execute the batch. The replay dashboard shows progress in real time: events sent, responses received, running success rate, errors. You can pause or cancel the batch at any time.
The outage recovery workflow
A two-hour outage arrived 47 events. You want to replay the ones that failed — the ones where your handler returned 500.
Filter to the outage window. Filter to failed deliveries. You see 47 events. You run the dry run. The dry run shows: 47 events, estimated 3 minutes at current handler throughput, Low risk (no confirmed receipts in the set).
You execute. The batch runs. 44 events succeed on replay. 3 events fail again — same error code as before. Different bug that your first fix did not address.
You now have precise information: your fix resolved 44 of the 47 affected events, and there are 3 specific events with a different error that need a different fix. You know exactly which events they are. You know exactly which customers are still affected. You can fix the second bug and replay the 3 remaining events.
Compare that to the manual recovery process: you would not easily know which 3 events were still failing after the fix without running a separate database query to check. With batch replay, the outcome is visible in the replay dashboard.
What makes HookTunnel replay different from ngrok
ngrok has a replay feature. It is useful and it works. But it has a fundamental constraint: replay only works during a live tunnel session.
When your ngrok tunnel session ends — when you close the terminal, when your laptop sleeps, when the session times out — your captured events are gone. You cannot replay an event from last Tuesday in ngrok because last Tuesday's events no longer exist.
HookTunnel capture is persistent. Events are stored with full retention (24 hours on Free, 30 days on Pro, 90 days on Team, 1 year on Enterprise). You can replay an event from last Tuesday from HookTunnel. You can replay an event from last month. Any event in your retention history is available for replay.
This changes the use case fundamentally. ngrok replay is a development tool — useful for testing your handler against a real payload while you are actively building. HookTunnel replay is an operations tool — useful for recovering from outages, debugging intermittent failures, and running compliance re-processing workflows.
| Capability | HookTunnel | ngrok | |---|---|---| | Replay after session ends | Yes | No | | Batch replay | Yes | No | | Dry-run preview before execution | Yes | No | | Replay from 30-day history | Yes (Pro+) | No | | Receipt-aware guardrails | Yes (guardrailed replay) | No | | Audit log of every replay | Yes | No | | Replay in real-time dashboard | Yes | No |
The audit trail
Every replay is logged permanently. The audit log for each replay records:
- Who triggered the replay (account user)
- When the replay was triggered
- The original event ID and capture timestamp
- The target URL used for replay
- The HTTP response from your handler
- The response latency
- For batch replays: the batch ID and the dry-run parameters
The audit log is accessible from the event detail view (for single-event replays) and from the replay history view (for batch replays). If a compliance auditor asks "did anyone replay this payment event, and what was the outcome?" the answer is in the audit log.
Developer scenario: the one event that broke an order
Carlos is an engineer at an e-commerce company. A customer contacts support: their order confirmation email never arrived. The order was placed 4 days ago. The order exists in the database — payment was taken — but the post-purchase webhook that triggers the order confirmation email apparently failed.
Carlos filters his HookTunnel event list to order.created events from 4 days ago. He finds the event for this customer's order. The event detail shows: HTTP 500, handler latency 12,000ms (timeout), no response body.
The handler timed out. The order was created, the payment succeeded, but the webhook handler for the confirmation email hit a timeout — probably the email service was having a slow day.
Carlos checks the current handler: it has a retry and timeout fix that was deployed 2 days ago. He clicks Replay on the 4-day-old event. The handler processes it: HTTP 200, 340ms. The audit log records the replay.
The customer gets their order confirmation email 4 days late, but they get it. Carlos closes the support ticket with a note explaining the 4-day delay and the fix. He creates a monitoring alert for handler timeouts so this does not go undetected again.
The entire recovery took 11 minutes. The event was accessible because HookTunnel was capturing it when the original failure happened. The fix was deployable without provider involvement because replay does not require Stripe, Twilio, or GitHub.
Replay and idempotency
Replay assumes your handler is idempotent — that processing the same event twice produces the same result as processing it once. If your handler is not idempotent and you replay an event that partially succeeded, you may create a duplicate.
For events that failed completely (your handler returned 500 or did not respond), replay is safe regardless of idempotency: the event was never processed. For events that succeeded (your handler returned 200), replay without idempotency checks is risky — you may process the same operation twice.
HookTunnel's guardrailed replay addresses this risk explicitly: it uses receipt state to identify which events were actually applied by your application and prevents replaying them without an override and an audit note. If you are replaying events that your handler returned 200 for — because you suspect the business logic ran but a side-effect did not commit — guardrailed replay is the right tool.
Basic replay is the right tool when you are certain the events you are replaying never reached your handler (because your handler was down, not returning 500).
Frequently asked questions
Does replay use the original provider signature headers?
Yes. The stored event includes all original headers, including Stripe-Signature, X-Twilio-Signature, and similar provider headers. When replayed, these headers are included in the request. Your handler's signature verification will use these headers.
Note: Stripe signatures include a timestamp component. If your handler validates that the Stripe signature timestamp is within a freshness window (for example, within 5 minutes of the current time), replaying old events will fail signature validation because the timestamp will be stale. You need to either disable signature timestamp validation for replay, or use HookTunnel's signature bypass option (which strips the provider signature header and injects a HookTunnel-signed header instead for verification purposes).
Can I replay to a different URL than the original target?
Yes. The replay dialog lets you specify an override target URL. By default it uses the hook's current configured target. If you want to replay to a staging environment or a different endpoint, you can specify that URL at replay time.
How many events can I batch replay at once?
Up to 500 events per batch. For larger recovery operations, HookTunnel splits the batch into sequential groups of 500 automatically, with a re-evaluation of receipt state between groups.
What happens if my handler is down during a batch replay?
The batch replay continues attempting delivery according to your handler's retry policy. If your handler returns 5xx errors, the replay engine retries with exponential backoff. If all retries for an event fail, that event is marked as replay-failed in the batch report and remains available for manual replay.
Is replay available on the Free plan?
Single event replay is available on all plans. Batch replay (multiple events at once) is available on Pro and above. Dry-run preview is available on Pro and above.
Recover from outages without calling your provider
Replay any event — individually or in bulk — directly from your webhook history.
Get started free →