Replay events from the ledger to webhooks
Re-reads a slice of the event ledger and re-delivers it to your webhook subscriptions, reconstructing each event body byte-identically — same eventId, type, and data — and signing it with a fresh X-Dairo-Timestamp like any delivery attempt, so it passes the consumer's verification and timestamp window while consumer-side dedupe on the event ID stays exact.
Re-reads a slice of the event ledger and re-delivers it to your webhook subscriptions, reconstructing each event body byte-identically — same eventId, type, and data — and signing it with a fresh X-Dairo-Timestamp like any delivery attempt, so it passes the consumer's verification and timestamp window while consumer-side dedupe on the event ID stays exact. Select the slice with exactly one lower bound: since (an opaque cursor from a GET /v1/events pagination.nextCursor), sinceSeq together with inboxId (replay one inbox partition from that seq, inclusive), or sinceTimestamp (RFC3339, events created at or after). Optionally cap the top with until (RFC3339), filter with types (e.g. ["email.bounced"]; each a plain type name of letters, digits, ., _, and -, else 400), and target one subscription with webhookId — otherwise every active matching subscription receives the slice. Delivery is synchronous and ordered by (partitionKey, seq); maxEvents bounds the slice at 1–5000 (default 1000), and a slice larger than the cap is rejected with 400 so you page it with until/maxEvents. The response returns replayed (events sent to at least one matching subscription), skipped (events with no matching active subscription), and the from/to bounds of the slice; each re-delivery lands as a terminal delivery record on your webhook subscriptions. Requires the events:write scope.
Scope: events:write. Send the API key as a bearer token; Scopes lists what each one reaches.
Request
Body
Required, application/json: EventReplayRequest.
Selects a ledger slice to re-deliver. Provide exactly one lower bound: since (an opaque cursor from GET /v1/events), sinceSeq (+inboxId, replay one partition from a seq), or sinceTimestamp (RFC3339).
| Field | Type | Required | Description |
|---|---|---|---|
since | string | no | Opaque keyset cursor (from GET /v1/events) to replay forward from. |
sinceSeq | integer (int64) | no | Replay one partition starting at this seq (inclusive). Requires inboxId. |
inboxId | string (uuid) | no | Scope the replay to one inbox partition (required with sinceSeq; an optional filter otherwise). |
sinceTimestamp | string (date-time) | no | Replay events created at or after this RFC3339 timestamp. |
until | string (date-time) | no | Optional upper bound (events created at or before this RFC3339 timestamp). |
types | array of string | no | Optional event-type filter, e.g. ["email.bounced"]. |
webhookId | string | no | Optional: replay only to this one webhook subscription; otherwise to every matching active subscription. |
maxEvents | integer | no | Hard cap on the slice size. A slice that exceeds the cap is rejected with 400 asking the caller to page with until/maxEvents. (minimum 1, maximum 5000, default 1000) |
Response
200 Success. Body: application/json, EventReplayResult.
| Field | Type | Required | Description |
|---|---|---|---|
replayed | integer | yes | Number of events re-delivered to at least one matching subscription. |
skipped | integer | yes | Number of events in the slice with no matching active subscription. |
from | EventReplayBound or null | no | |
to | EventReplayBound or null | no |
Errors
Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.
| Status | Meaning |
|---|---|
400 | The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch). |
401 | The API key is missing or invalid. |
403 | The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted). |
404 | No such resource in this account (resource_not_found). |
422 | The request is well-formed but a field failed validation (validation_failed). |
429 | Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached). |
500 | An unexpected error; retry with backoff, then contact support (internal_error). |