Skip to content
Back to site

Replay and Time Machine

Resending a delivery puts the same delivery back on its retry ladder. A replay builds new deliveries from stored events. The dashboard calls replay the Time Machine.

Resend a delivery Replay (Time Machine)
Works on One existing delivery Stored events in a time range
Delivery id Kept New
Sequence number Kept New, so it queues behind live traffic
Idempotency-Key Kept <event id>-<endpoint id>
The original delivery Moved again Left untouched
Use it when One delivery failed and the receiver is fixed A receiver lost data, or a new endpoint needs history

POST /api/v1/deliveries/{id}/replay puts the delivery back to PENDING and gives it 3 more attempts, the first sent straight away. It answers 202. The attempt count and history are kept, so new attempts are numbered after the old ones and wait at the ladder step the delivery already reached. A delivery that already succeeded is refused, and one with an attempt under way is refused with 409 until that attempt finishes.

Query parameters:

Parameter Effect
dryRun=true Sends nothing. Returns the target URL, the event type, the payload, the Idempotency-Key that would go out, the previous attempts, and a plan: WILL_SEND, SKIP when the delivery already succeeded, or BLOCKED when the endpoint is disabled.
fromAttempt=N Gives the delivery the attempts it had left from attempt N instead of 3: its maximum attempts minus N-1. N must be between 1 and the number of attempts already made.

Use fromAttempt when 3 attempts are not enough, for example after a receiver was down for hours: fromAttempt=1 gives back the whole ladder.

To resend many deliveries at once, use POST /api/v1/deliveries/bulk-replay with up to 1000 deliveryIds, or with a projectId plus status and endpointId filters and a limit of up to 5000. Without status, only deliveries that failed or were moved to Failed Messages are resent. A delivery that succeeded or has an attempt under way is always skipped. The response says how many were replayed, how many were skipped, and whether more matched.

Abandoned deliveries can also be retried from Failed Messages: see Retries and failed messages.

  1. Estimate first. POST /api/v1/projects/{projectId}/replay/estimate takes the same body as the replay and creates nothing. It returns the matching events, the matching active subscriptions (patterns included), the deliveries that would be created, and a warning when the range is too large. The estimate does not apply rules, so a DROP or ROUTE rule makes the real number differ.

    Terminal window
    curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/replay/estimate" \
    -H "X-API-Key: $API_KEY" \
    -H "Content-Type: application/json" \
    -d '{"fromDate":"2026-09-01T00:00:00Z","toDate":"2026-09-02T00:00:00Z","eventType":"order.completed"}'
  2. Start the replay with POST /api/v1/projects/{projectId}/replay and the same body. fromDate and toDate are required; eventType, endpointId and sourceStatus narrow it down. It answers 201 with a session.

  3. Follow the session with GET /api/v1/projects/{projectId}/replay/{sessionId}, or stop it with POST /api/v1/projects/{projectId}/replay/{sessionId}/cancel.

A replay routes each stored event like a newly sent one: the active subscriptions matching its type (patterns such as order.* included) and the project’s rules as they are now. A DROP rule replays nothing for that event, a ROUTE action adds its endpoint, and a TRANSFORM action replaces the subscription’s transformation. An event that would exceed the fan-out limit is not replayed to any endpoint and counts as an error on the session. With endpointId, only the deliveries to that endpoint are created.

Ordered endpoints get fresh sequence numbers, so replayed deliveries wait behind live ones instead of colliding with them.

Limit Value
Replay sessions running at once, per project 2
Events in one session REPLAY_MAX_EVENTS_PER_SESSION, default 500000

Incoming events can be replayed to every destination of their source:

  • One event: POST /api/v1/projects/{projectId}/incoming-events/{id}/replay.
  • Many events: POST /api/v1/projects/{projectId}/incoming-events/bulk-replay with a required sourceId, and either a list of eventIds or a from and to range, optionally filtered by verified and capped by maxEvents.

Each replay creates new forwards that start again from attempt 1.