Unified.to
All articles

How virtual webhook retry and recovery works


September 16, 2026

[Virtual webhooks](/blog/unlock_real_time_data_with_virtual_webhooks) give you a consistent event stream even when an integration does not support native push. Behind that experience is a recovery system that treats reading from the integration and delivering to your endpoint as two separate concerns — so a temporary problem on one side does not burn the retry budget of the other.

This guide explains how that recovery works at a high level, what you can expect when something fails, and how health monitoring fits in.

If you are new to virtual webhooks, start with Understanding virtual webhooks. For diagnosing an unhealthy webhook, see How to troubleshoot unhealthy webhooks.

Two sides of every virtual webhook

Every virtual webhook cycle has two stages:

  1. Read — Unified checks the connected integration for new or updated data (according to your subscription and interval).
  2. Dispatch — When there is something to send, Unified POSTs that data to your hook_url.

Failures can happen in either stage: the integration may be slow, rate-limited, or briefly unavailable; your endpoint may time out, return an error, or be down for a deploy. Unified recovers each stage independently so integration instability and your endpoint's availability do not share a single retry budget.

When your endpoint is unavailable (dispatch recovery)

Delivery only succeeds when your server acknowledges the POST — typically with a 2xx response.

If your endpoint is unreachable or returns an error:

  1. Short immediate retries — Unified retries the same delivery a few times right away, with a brief pause between attempts, to ride out blips (cold starts, brief network glitches).
  2. Progressive backoff — If those attempts still fail, Unified spaces later retries further apart, starting around one minute and increasing over time.
  3. Sustained recovery window — For consecutive failures, that schedule can continue for an extended recovery window — currently up to roughly two weeks — so longer outages (maintenance windows, weekend incidents) still have a chance to recover automatically. A successful delivery resets the retry schedule; the next failure starts recovery from the beginning again.
  4. Health signal — If delivery cannot succeed across that consecutive-failure window, the webhook is marked unhealthy (is_healthy: false) and delivery stops until you fix the endpoint and re-enable or recreate the subscription as needed.

You do not need to implement your own delivery retry loop for virtual webhooks. Respond quickly with success when you have accepted the payload; Unified handles delivery retries.

When the integration is unavailable or rate-limited (read recovery)

Reading from the integration can also fail: transient API errors, auth refresh races, or rate limits.

In those cases Unified:

  • Backs off with the same progressive delay pattern used for delivery recovery, instead of hammering the integration. As with dispatch, consecutive failures escalate the wait; a successful read resets the schedule.
  • Honors rate-limit guidance from the integration when it is present (for example a suggested wait), and still escalates delays if pressure continues — so a short 'try again soon' hint cannot pin the system into a tight retry loop.
  • Keeps your delivery budget intact — read-side failures do not consume the dispatch retry budget for data that has already been fetched, and vice versa. A flaky endpoint does not stop Unified from continuing to read when it is healthy again. This independence applies while the webhook remains in recovery. If the subscription eventually transitions to is_healthy: false, further reading and dispatch stop until you intervene.

When the integration recovers, normal polling resumes on your configured interval and new events are dispatched as usual.

Not every read failure enters that long recovery window. Some problems — typically broken authorization or missing permissions on the connection — are treated as non-retryable: Unified marks the webhook unhealthy right away instead of backing off for days. That usually means fixing or recreating the connection (and then the webhook), not waiting for automatic recovery. See How to troubleshoot unhealthy webhooks for those cases.

Why separate read and dispatch recovery matters

Without separate recovery:

  • A long integration outage could exhaust retries and mark the webhook unhealthy even though your endpoint was fine the whole time.
  • A short customer outage could stop Unified from reading new data once the integration came back.

By isolating the two stages, Unified can keep making progress where progress is possible, then resume the other side when conditions improve. That isolation lets virtual webhooks recover from transient failures without coupling integration availability to endpoint availability.

What 'healthy' means in practice

SignalMeaning
is_healthy: trueThe subscription can continue operating or recovering. This does not necessarily mean the most recent read or dispatch succeeded; transient failures may still be retrying.
is_healthy: falseRetries were exhausted, or Unified hit a terminal / non-retryable failure (for example broken connection auth). Reading and dispatch stop until you intervene. See How to troubleshoot unhealthy webhooks.
is_paused: trueThe webhook or connection is paused by Unified's billing/plan controls. While paused, Unified does not read or dispatch.
Use the dashboard and the webhook's recent runs to see whether recent attempts succeeded. Details are covered in How to troubleshoot unhealthy webhooks.

Quiet periods

Virtual webhooks only POST when there is something to send. Between events, Unified continues to check on your interval.

What you should do on your side

  1. Acknowledge after you've accepted the payload — Return a success status (2xx) once you've safely accepted the work, and do heavy processing asynchronously when possible. After Unified receives that acknowledgment, it does not redeliver that same attempt. Retries only happen when Unified does not receive a successful acknowledgment (for example a timeout or non-success status). If your handler processes the body and then fails or times out before responding, you may see the same delivery again — design for that edge case.
  2. Keep your URL stable and reachable — TLS, DNS, and firewall rules that reject Unified's POSTs look like delivery failures and enter the same retry path.
  3. Watch health — Alert on is_healthy flipping to false so you can fix the endpoint before customers notice stale data.

Summary

Virtual webhooks are not 'just polling.' They include a recovery layer that:

  • Retries dispatch to your endpoint with immediate retries, then progressive backoff for consecutive failures (currently up to about two weeks), resetting on the first success.
  • Retries reads from the integration with the same progressive backoff (also resetting on success), while respecting rate limits — except for non-retryable connection problems (for example broken auth), which mark the webhook unhealthy immediately.
  • Keeps those two retry paths independent, so one side's instability does not silently consume the other's chances.
  • Surfaces lasting or non-retryable failure through is_healthy. Once a webhook becomes unhealthy, Unified stops reading and dispatching until you intervene — there is no automatic resume from that state.

You get a single webhook API; Unified owns the hard parts of staying reliable when either side of the pipe has a bad day.

All articles