Retry Policy
Talonic retries failed webhook deliveries with up to 4 attempts, exponential backoff of roughly 2s, 4s, and 8s, and a 30-second timeout on every attempt.
The webhook retry policy determines what happens when your endpoint fails to acknowledge a delivery. Talonic makes up to 4 delivery attempts per webhook: one immediate attempt plus up to 3 retries with exponential backoff of roughly 2, 4, and 8 seconds. An attempt succeeds when your endpoint returns a 2xx status code within the 30-second per-attempt timeout.
- Attempt 1: immediate
- Attempt 2: after ~2 seconds
- Attempt 3: after ~4 seconds
- Attempt 4 (final): after ~8 seconds
Non-2xx responses and timeouts trigger a retry. Redirects (3xx) are deliberately not followed: the delivery treats them as failures, because following a redirect would send the signed payload to a URL that was never validated. Point your webhook configuration directly at the final endpoint URL.
After the final failed attempt, the delivery is marked as failed and logged. You can inspect delivery outcomes, HTTP status codes, and error messages in the dashboard delivery log. The X-Talonic-Delivery header carries the same delivery ID across every retry of a delivery, so use it as an idempotency key to deduplicate on your end.
Because the whole retry window spans a couple of minutes at most, treat webhooks as a trigger rather than the source of truth: acknowledge fast with a 2xx, enqueue the work, and fetch authoritative state from the API (for example GET /v1/extractions/:id). If your endpoint was down during an event, re-fetch the affected resources via the REST API rather than waiting for a redelivery.
Fast-ack handler with delivery deduplication
const processed = new Set(); // use a persistent store in production
app.post('/webhooks/talonic', express.raw({ type: 'application/json' }), (req, res) => {
const deliveryId = req.headers['x-talonic-delivery'];
// 1. Deduplicate: the delivery ID is stable across every retry attempt.
if (processed.has(deliveryId)) return res.status(200).send('duplicate');
processed.add(deliveryId);
// 2. Acknowledge immediately — never do heavy work before responding.
res.status(200).send('ok');
// 3. Process asynchronously after the response is sent.
const event = JSON.parse(req.body);
queue.enqueue({ deliveryId, event });
});If your endpoint consistently fails, check for firewall rules blocking outbound Talonic traffic, TLS certificate issues, redirect responses from your framework (for example a trailing-slash redirect), or handler latency above 30 seconds. Pair retry handling with [Signature Verification](webhook-security) to reject spoofed payloads early and cheaply.
Recovering missed deliveries
When an endpoint outage outlasts the retry window, the events themselves are not lost — only the deliveries are. The [Event Feed](events-feed) at GET /v1/events reads the same rows webhooks fan out from, so a periodic sweep of the feed closes any gap left by downtime. Store the numeric id of the last event you processed and page forward from there.
Sweep the event feed after downtime
curl -s "https://api.talonic.com/v1/events?limit=50" \
-H "Authorization: Bearer tlnc_your_api_key"
# Compare data[].id against the last ID your handler processed —
# event IDs are monotonically increasing, so any higher ID is a missed event.