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

# Wait for a webhook to arrive

> Block until a matching webhook arrives with expect, or capture a bounded live stream with tail, instead of polling search.

When an agent needs to confirm that a webhook arrived — after deploying a fix, or while validating an integration — wait for it directly. `expect` and `tail` use the live observe stream and return when the condition is met, which is cheaper and more reliable than polling `events search` in a loop.

<Note>
  Both commands are [envelope exceptions](/agents/output-and-errors#know-the-envelope-exceptions): they always emit JSON (even without `--json`) and do **not** use the `{schema, data}` wrapper. `expect` returns one bare object; `tail` emits NDJSON.
</Note>

## Wait for one match

Use `expect` to block until a single matching webhook arrives.

```bash theme={null}
repost expect \
  --bucket stripe-prod \
  --filter 'method:POST AND path:/stripe/*' \
  --timeout 45s
```

On a match it prints a bare object and exits `0`:

```json theme={null}
{
  "event_id": "evt_01JZ8Y1",
  "bucket_id": "bkt_01HV9S",
  "method": "POST",
  "path": "/stripe/webhook",
  "matched_at": "2026-06-19T08:45:10Z",
  "received_at": "2026-06-19T08:45:09Z"
}
```

<Check>
  `expect` exits `0` on a match and `7` (`timeout`) if nothing matches before `--timeout` (default `30s`). Branch on the exit code, then read the object for the matched `event_id`.
</Check>

<Warning>
  The observe stream has **no backfill**. Open `expect` *before* you trigger the action you're waiting on — a stream you open afterward will never replay the event you missed. See [Consistency model](/agents/consistency-model).
</Warning>

## Stream a bounded set

Use `tail` to capture several live events as NDJSON — one object per line.

```bash theme={null}
repost tail \
  --bucket stripe-prod \
  --filter 'method:POST' \
  --count 5 \
  --max-wait 2m
```

```json theme={null}
{"event_id":"evt_01JZ8Y1","bucket_id":"bkt_01HV9S","method":"POST","path":"/stripe/webhook","received_at":"2026-06-19T08:45:09Z"}
{"event_id":"evt_01JZ8Y2","bucket_id":"bkt_01HV9S","method":"POST","path":"/stripe/webhook","received_at":"2026-06-19T08:45:12Z"}
```

`--count` stops after N events (`0` = unlimited); `--max-wait` stops at a deadline (`0` = no limit), both exiting `0`. Set at least one bound so an agent never streams forever, and parse line by line — don't wait for a closing array. The filter fields are the live-stream subset documented in [Search & filters](/agents/search-and-filters#filter-the-live-stream).

## Why not poll

| Goal                        | Prefer                         | Avoid                                    |
| --------------------------- | ------------------------------ | ---------------------------------------- |
| Wait for one event          | `expect --timeout 45s`         | Re-running `events search` every second. |
| Capture several live events | `tail --count 5 --max-wait 2m` | An unbounded live stream.                |
| Confirm delivery health     | `health --fail-on …`           | Scraping dashboard state.                |

Polling burns rate limit and adds latency. When no wait command fits, poll deliberately — exponential backoff and a deadline, detailed in [Caching & performance](/agents/caching-performance#when-you-must-poll).

## Continue

<Columns cols={3} className="gap-y-4">
  <Card title="Diagnose a webhook" icon="search-check" href="/agents/diagnose-webhooks" cta="Investigate" arrow="true">
    Once an event arrives, inspect it and its delivery chain.
  </Card>

  <Card title="Consistency model" icon="layers" href="/agents/consistency-model" cta="Stream vs store" arrow="true">
    Why the stream has no backfill, and which plane answers which question.
  </Card>

  <Card title="Caching & performance" icon="gauge" href="/agents/caching-performance" cta="Stay fast" arrow="true">
    When polling is unavoidable, do it intentionally.
  </Card>
</Columns>
