Skip to main content

Replay Mechanics

Replay lets you re-deliver a webhook event to your endpoint after the original delivery failed, after you fixed a bug, or after you stood up a new endpoint. It is the primary recovery tool when something downstream of mailbot breaks.

When to use replay

Replay is the right tool when:

  • your webhook endpoint was down and missed events
  • a deploy broke event handling and you need to backfill
  • you stood up a new analytics consumer and want history
  • you want to re-test handler logic against real production payloads
  • audit shows that an event fired but state did not change in your system

Replay is not the right tool when:

  • you want to re-trigger an action (re-send the actual email). Replay re-delivers the event to your endpoint, not the underlying message.
  • the original event never fired. Replay only acts on events that were emitted at least once.

How replay works

When you call POST /v1/events/:eventId/replay, mailbot:

  1. fetches the original event payload from durable storage
  2. signs the payload exactly the same way as the original delivery
  3. POSTs it to the destination URL
  4. records the replay attempt in the deliveries log alongside the original

The payload your endpoint receives is byte-for-byte identical to the original, including event_id, created_at, and signature. This is intentional, so your idempotency check still works (your handler should already be idempotent — see Event delivery model).

Retention window

mailbot retains every event for replay for 90 days from the original created_at. After 90 days, the event payload is removed from active replay storage. Audit metadata (the fact that the event existed) remains in the audit log for longer, but the body is no longer replayable.

Plan your recovery windows accordingly. If you need replay for compliance or legal reasons beyond 90 days, mirror events to your own storage on receipt.

Overriding the target URL

By default, replay POSTs to the same URL the original delivery targeted. You can override this:

curl -X POST https://getmail.bot/v1/events/$EVENT_ID/replay \
-H "Authorization: Bearer $MAILBOT_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"target_url": "https://staging.example.com/webhooks/mailbot"
}'

When target_url is set, mailbot signs the payload with the same secret as the original webhook, but POSTs to the override URL. This is the standard pattern for:

  • replaying production events into a staging endpoint for debugging
  • routing historic events to a new consumer that did not exist when the events were emitted
  • one-shot tests of a new endpoint before you switch the live webhook to it

Bulk replay

For replaying a range, list the events first and replay each. There is no single bulk-replay endpoint; this is intentional, so you can decide which events to skip.

const events = await mailbot.events.list({
inbox_id: 'inb_xxx',
event_type: 'message.received',
since: '2026-04-15T00:00:00Z',
until: '2026-04-15T23:59:59Z',
});

for (const event of events) {
await mailbot.events.replay(event.event_id, {
target_url: 'https://example.com/recovery',
});
}

Pace replays if your endpoint has rate limits. There is no enforced delay on the mailbot side, but flooding your own endpoint will trigger your own rate limit.

Audit trail

Every replay attempt is recorded:

  • the original event_id
  • the timestamp of the replay
  • the destination URL (original or override)
  • the response status from your endpoint
  • the operator (API key) that triggered the replay

This appears in the audit log, scoped to the inbox. See List audit log.