Skip to main content
When you deploy the service behind a forwarder, in-flight webhooks hit a target that is restarting — they fail, retry, and may land in the DLQ. Pausing the forwarder first turns that failure window into a queue window: inbound events are held, the deploy proceeds, and a resume drains the backlog into the healthy target. The agent’s job is to bracket the deploy and then prove recovery.
forwarder pause and forwarder resume drop into an interactive picker when run without selectors. An agent must always pass both --bucket (-b) and --forwarder (-f) so the command runs non-interactively. Omitting either fails fast with “both --bucket (-b) and --forwarder (-f) flags are required”.

The deploy window

Pause before deploying

Pausing is a write mutation. Webhooks received while the forwarder is paused are queued, not discarded, and deliver when you resume.
repost forwarder pause \
  --bucket stripe-prod \
  --forwarder prod-api \
  --json
{
  "schema": "repost.forwarder.action/v1",
  "data": {
    "outcome": "PAUSED",
    "results": [
      { "name": "prod-api", "target": "https://api.example.com/webhooks", "type": "EXTERNAL", "success": true }
    ]
  }
}
Confirm every entry in results has success: true before deploying. --forwarder is repeatable — pass it once per forwarder that points at the service you are deploying, and verify each one paused.

Deploy, then resume

Run your deployment out of band. When the target is healthy again, resume — queued deliveries begin draining immediately.
repost forwarder resume \
  --bucket stripe-prod \
  --forwarder prod-api \
  --json
{
  "schema": "repost.forwarder.action/v1",
  "data": {
    "outcome": "RESUMED",
    "results": [
      { "name": "prod-api", "target": "https://api.example.com/webhooks", "type": "EXTERNAL", "success": true }
    ]
  }
}
Resuming releases the entire queued backlog at once. If the target is sensitive to bursts, cap delivery with the forwarder’s --rate-limit-per-second (set at creation) before the deploy, not after the flood starts.

Confirm recovery

Do not call a deploy healthy because resume returned success: true — that only confirms the forwarder is unpaused. Confirm a real delivery succeeded.
repost expect \
  --bucket stripe-prod \
  --filter 'method:POST AND path:/stripe/*' \
  --timeout 60s
expect exits 0 when a matching event arrives, 7 if none does before the timeout. health --fail-on exits 8 (partial_failure) when the threshold is breached. Treat a clean expect and a clean health as the recovery signal; either non-zero exit means roll forward into diagnosis.

Pause versus disable

Stops delivery but keeps queuing inbound webhooks. Reversible with resume, which drains the backlog. This is the deploy-window primitive — use it whenever you intend to bring the target back.
forwarder disable -b <slug> -f <name> marks the forwarder inactive so it no longer takes deliveries. Use it to retire a target, not to bracket a deploy. Re-enable it from the dashboard or by recreating the route.

If recovery fails

A failed recovery check is recoverable — nothing was lost.
1

Keep serving

The backlog already drained or is draining. New events keep flowing; you are diagnosing, not firefighting data loss.
2

Find the failures

Run forwards search --failed and inspect forwards chain for the failing events. See Diagnose webhooks.
3

Replay what failed

Replay the DLQ or the failed event IDs behind a dry-run. See Replay deliveries.

Continue

Wait for events

The expect and tail commands that confirm recovery.

Replay deliveries

Re-deliver anything that failed during the window.

Provision targets

Create forwarders and set the rate limits that tame a drain.