Retries & Replay
Retry policy, dead-letter semantics, and manual replay — per-delivery and replay-since-history — for recovering from receiver outages.
Retries & Replay
Emofy gives your receiver multiple chances to accept a delivery, and gives you tools to catch up after a longer outage.
Retry schedule
| Attempt | Delay from previous |
|---|---|
| 1 | immediate |
| 2 | ~1s |
| 3 | ~3s |
| 4 | ~9s |
| 5 | ~27s |
Retries trigger on 5xx responses or request timeouts (not 4xx — those indicate receiver misconfiguration, not unavailability).
After attempt 5 fails, the delivery is marked dead_lettered and
stops retrying automatically. It remains visible in the delivery log
viewer and can be manually replayed.
Per-delivery manual replay
From the developer portal delivery log, any failed or dead_lettered
delivery shows a Replay button (gated by webhooks:replay
permission). A new delivery row is created with is_manual_retry=true,
and the original row's error message is annotated with the new delivery
id for traceability.
API:
POST /api/developer/apps/:appId/webhooks/:id/deliveries/:deliveryId/replayReplay-since-history
If your receiver was down for hours, replaying each delivery individually is tedious. Use replay-since to re-fire every event from the outbox matching your webhook's subscribed events since a given timestamp.
POST /api/developer/apps/:appId/webhooks/:id/replay-since
Content-Type: application/json
{
"fromTimestamp": "2026-04-17T00:00:00Z",
"dryRun": true
}With dryRun: true (default), Emofy returns:
{
"matchedCount": 147,
"earliestEventId": "wob_...",
"latestEventId": "wob_..."
}Call again with "dryRun": false to actually enqueue the matched events.
The response returns a replayBatchId (rbt_*) which stamps every
resulting delivery row for correlation in the log viewer.
Rate limit: 1 replay-batch per webhook per 5 minutes. Subsequent
calls return 429 REPLAY_RATE_LIMITED with a retryAfter field.
Retention horizon: 30 days. Events older than 30 days have been swept from the outbox and are not replayable.
Tips
- Test with dryRun first. A single replay-since can re-fire thousands of events — verify the match count before committing.
- Make replay idempotent on your side. Receivers MUST dedupe on
X-Emofy-Delivery-Id; manual replays produce new delivery ids, so the timestamp + payload may appear to repeat. - Don't replay
successdeliveries. The API rejects these — if your system lost the result after acknowledging a successful delivery, you need your own replay mechanism, not Emofy's.
Dead-letter clean-up
Dead-lettered deliveries remain in the log indefinitely (30-day
outbox retention applies only to the replay eligibility window — the
delivery row itself is kept). You can filter the log viewer by
status=dead_lettered to triage what needs replay after a long outage.
Signature Verification
Emofy signs every webhook with HMAC-SHA256. Verify the Emofy-Signature header before trusting any payload.
Event Reference
The curated 10-event catalog that developer apps can subscribe to. Org-scoped webhooks may subscribe to any registry entry; developer app webhooks are restricted to this subset.