Skip to content

Replay an endpoint's events from a time range​

POST
/v1/endpoints/{id}/replay

Re-deliver the events this endpoint received between since and until (inclusive) to the destinations its routes target NOW: its current routes and current route filters. A destination added after the events arrived (e.g. a new SQS queue) receives the backlog, and one that lost events gets them again. Already-delivered events ARE re-sent. Each delivery keeps the event's webhook-id (HTTPS deliveries also carry webhook-replayed: true), so a receiver that dedupes still can.

What is re-sent is the event as stored: the body the endpoint's transform produced when it arrived, with its original verification verdict. Nothing is re-verified, so an old request past its provider's signature tolerance replays fine. quarantined (failed signature) and parked (paused endpoint, or a failed fail-closed transform) events are never replayed; they are counted in excluded. Route filters see the event exactly as they did at ingest, so a body too large to keep inline (over 128 KB) is not visible to JSON-path filters, then or now. A paused or disabled endpoint is refused (409): resume it first.

A real replay is a BACKGROUND JOB: this returns 202 with the job, and a worker drains the whole window at full speed. Poll getReplay for progress, and stop it with stopReplay. Nothing about it depends on the caller staying connected — a 330k-event window is one request here, not 330. An endpoint may have only one live replay at a time (409 otherwise): two would double-send every event in the overlap. cursor is rejected on a real replay — paging is the job's business now.

Within the job, events are enqueued oldest-first; across pages, later pages carry OLDER events, so a FIFO endpoint's strict order holds only for a window of up to 1,000 events.

A dry_run counts instead and answers inline (200). With no route filter (the common case) the counts are EXACT for the whole window, whatever its size, and next_cursor is always null — one call is the whole answer. When any route carries a filter, each event has to be matched individually: the dry run then looks at up to 5,000 events per call and pages through next_cursor. scanned is what the call accounted for either way.

Authorizations​

apiKey

Scoped API key. Scopes are read ⊂ write ⊂ admin. A call needing more scope than the key holds returns 403 insufficient_scope.

Type
HTTP (bearer)

Parameters​

Path Parameters

id*

The endpoint id.

Type
string
Required

Request Body​

application/json
JSON
{
  
"since": "string",
  
"until": "string",
  
"status": "string",
  
"destinations": [
  
  
"string"
  
],
  
"dry_run": false,
  
"cursor": "string"
}

Responses​

Dry run. The counts of what WOULD be replayed; nothing was enqueued.

application/json
JSON
{
  
"replay_id": "rpl_4f0c2d9e8b7a4c1d9e0f1a2b3c4d5e6f",
  
"dry_run": true,
  
"scanned": 0,
  
"replayed": 0,
  
"enqueued": 0,
  
"skipped": 0,
  
"excluded": 0,
  
"destinations": [
  
  
"string"
  
],
  
"next_cursor": "string"
}

Playground​

Authorization
Variables
Key
Value
Body

Samples​

Powered by VitePress OpenAPI

Emithook · a Finnoto product