Retries & Dead Letters
Parseo retry schedule, exponential backoff, and how to replay dead-lettered events.
Retries and Dead Letters
Parseo delivers webhooks at least once. If your endpoint is unavailable, Parseo retries using exponential backoff.
Retry Schedule
| Attempt | Delay after previous failure |
|---|---|
| 1 (initial) | Immediate |
| 2 | 1 second |
| 3 | 5 seconds |
| 4 | 30 seconds |
| 5 | 5 minutes |
| 6 | 30 minutes |
| 7 | 2 hours |
| 8 | 6 hours |
| 9 | 24 hours |
After the final attempt, the event is dead-lettered.
Ordering and delivery guarantees
- At-least-once delivery. A successful event may be delivered more than once (e.g., if your endpoint responds 2xx but the network drops our receipt). Dedupe on the event ID (
evt_…) — treat any event whose ID you've already processed as a no-op. - No ordering guarantee. Two events produced seconds apart may arrive in reverse order because of retry timing. Reconcile state by the event's
occurredAttimestamp, not by arrival order. - Dead letter. After 8 attempts across ~36 hours, an event is abandoned. Fetch it via
GET /webhooks/{id}/deliverieswithstatus=failed.
What Triggers a Retry
- Your endpoint returns a non-2xx HTTP status code
- Your endpoint does not respond within 30 seconds
- A network error prevents the connection
Dead-Lettered Events
A dead-lettered event is stored for 30 days in your webhook delivery history. You can replay it from the Parseo dashboard (Settings → Webhooks → Delivery History → Replay) or by calling POST /webhooks/:id/test with the event payload.
Idempotency on Your Side
Because Parseo retries, your webhook handler must be idempotent. The same event may arrive more than once. Use the id field (e.g. evt_4D3c2B...) as a deduplication key:
// Express example
app.post('/parseo-webhook', async (req, res) => {
const eventId = req.body.id;
if (await db.webhookEvents.exists(eventId)) {
// Already processed — acknowledge without re-processing
return res.sendStatus(200);
}
await db.webhookEvents.insert(eventId);
await processEvent(req.body);
res.sendStatus(200);
});Fixing a Broken Endpoint
If your endpoint was down and events piled up in the dead-letter queue:
- Fix the endpoint (ensure it returns 2xx for valid payloads)
- Go to Settings → Webhooks → select the endpoint → Delivery History
- Click Replay All Failed to re-queue all dead-lettered events
Replayed events use the original payload (frozen at dispatch time) — not the current invoice state.
Delivery Log Retention
Full delivery logs (payload, response, latency) are kept for 30 days. After that, only daily aggregate counts (delivered, failed, retried) are retained for analytics. If you need long-term audit trails of webhook events, store them on your side when they arrive.
