Wait for events

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.

Both commands are 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.

Wait for one match

Use expect to block until a single matching webhook arrives.

repost expect \
  --bucket stripe-prod \
  --filter 'method:POST AND path:/stripe/*' \
  --timeout 45s

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

{
  "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"
}

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.

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.

Stream a bounded set

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

repost tail \
  --bucket stripe-prod \
  --filter 'method:POST' \
  --count 5 \
  --max-wait 2m
{"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.

Why not poll

GoalPreferAvoid
Wait for one eventexpect --timeout 45sRe-running events search every second.
Capture several live eventstail --count 5 --max-wait 2mAn unbounded live stream.
Confirm delivery healthhealth --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.

Continue