> ## Documentation Index
> Fetch the complete documentation index at: https://docs.repost.sh/llms.txt
> Use this file to discover all available pages before exploring further.

# Guard a deployment

> Pause a forwarder before a deploy so webhooks queue instead of failing, then resume and confirm recovery with expect and health.

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.

<Warning>
  `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".
</Warning>

## The deploy window

```mermaid theme={null}
sequenceDiagram
    participant A as Agent
    participant R as Repost
    participant T as Target service
    A->>R: forwarder pause -f prod-api
    Note over R,T: inbound webhooks queue — not dropped
    A->>T: deploy new version
    A->>R: forwarder resume -f prod-api
    R->>T: drain queued deliveries
    A->>R: expect / health --fail-on
    R-->>A: recovery confirmed
```

## Pause before deploying

Pausing is a `write` [mutation](/agents/safe-mutations). Webhooks received while the forwarder is paused are **queued, not discarded**, and deliver when you resume.

```bash theme={null}
repost forwarder pause \
  --bucket stripe-prod \
  --forwarder prod-api \
  --json
```

```json theme={null}
{
  "schema": "repost.forwarder.action/v1",
  "data": {
    "outcome": "PAUSED",
    "results": [
      { "name": "prod-api", "target": "https://api.example.com/webhooks", "type": "EXTERNAL", "success": true }
    ]
  }
}
```

<Check>
  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.
</Check>

## Deploy, then resume

Run your deployment out of band. When the target is healthy again, resume — queued deliveries begin draining immediately.

```bash theme={null}
repost forwarder resume \
  --bucket stripe-prod \
  --forwarder prod-api \
  --json
```

```json theme={null}
{
  "schema": "repost.forwarder.action/v1",
  "data": {
    "outcome": "RESUMED",
    "results": [
      { "name": "prod-api", "target": "https://api.example.com/webhooks", "type": "EXTERNAL", "success": true }
    ]
  }
}
```

<Warning>
  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](/agents/provision-targets)) before the deploy, not after the flood starts.
</Warning>

## 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.

<CodeGroup>
  ```bash Wait for the next live delivery theme={null}
  repost expect \
    --bucket stripe-prod \
    --filter 'method:POST AND path:/stripe/*' \
    --timeout 60s
  ```

  ```bash Assert the window is healthy theme={null}
  repost health \
    --bucket stripe-prod \
    --forwarder prod-api \
    --window 5m \
    --fail-on 'success_rate < 0.99 || dlq_depth > 0' \
    --json
  ```
</CodeGroup>

<Check>
  `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](/agents/diagnose-webhooks).
</Check>

## Pause versus disable

<AccordionGroup>
  <Accordion title="forwarder pause — temporary, queued" icon="circle-pause">
    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.
  </Accordion>

  <Accordion title="forwarder disable — durable stop" icon="circle-stop">
    `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.
  </Accordion>
</AccordionGroup>

## If recovery fails

A failed recovery check is recoverable — nothing was lost.

<Steps>
  <Step title="Keep serving">
    The backlog already drained or is draining. New events keep flowing; you are diagnosing, not firefighting data loss.
  </Step>

  <Step title="Find the failures">
    Run `forwards search --failed` and inspect `forwards chain` for the failing events. See [Diagnose webhooks](/agents/diagnose-webhooks).
  </Step>

  <Step title="Replay what failed">
    Replay the DLQ or the failed event IDs behind a dry-run. See [Replay deliveries](/agents/replay-deliveries).
  </Step>
</Steps>

**Deploy-guard procedure**

1. Require `write` scope (`auth status` → `scopes` contains `write`).
2. `forwarder pause -b <slug> -f <name> --json` for every target forwarder → assert all `data.results[].success == true`. Never omit `-b`/`-f` (interactive otherwise).
3. Run the deploy out of band; block on its success.
4. `forwarder resume -b <slug> -f <name> --json` → assert all `data.results[].success == true`.
5. Verify: `expect … --timeout 60s` (exit `0` required) AND `health --fail-on '…' --json` (exit `0` required).
6. On any non-zero verify exit: `forwards search --failed` → `forwards chain` → `replay` the failures.

## Continue

<Columns cols={3} className="gap-y-4">
  <Card title="Wait for events" icon="timer" href="/agents/wait-for-events" cta="Verify live" arrow="true">
    The `expect` and `tail` commands that confirm recovery.
  </Card>

  <Card title="Replay deliveries" icon="rotate-ccw" href="/agents/replay-deliveries" cta="Recover" arrow="true">
    Re-deliver anything that failed during the window.
  </Card>

  <Card title="Provision targets" icon="circle-plus" href="/agents/provision-targets" cta="Create routes" arrow="true">
    Create forwarders and set the rate limits that tame a drain.
  </Card>
</Columns>
