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:
- fetches the original event payload from durable storage
- signs the payload exactly the same way as the original delivery
- POSTs it to the destination URL
- 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.