Retries & Delivery Logs
How BeeL. retries failed deliveries and how to inspect the delivery history.
BeeL. automatically retries webhook deliveries that fail due to network errors or non-2xx HTTP responses. You can also inspect the delivery history and trigger manual retries from the dashboard or the API.
Retry Policy
| Parameter | Value |
|---|---|
| Max attempts | 5 (1 original + 4 automatic retries) |
| Retry strategy | Exponential backoff |
| Initial delay | 5 seconds |
| Max delay | 6 hours |
| Timeout per attempt | 10 seconds |
Backoff Schedule
| Attempt | Approximate delay after previous attempt |
|---|---|
| 1st (original) | — |
| 2nd | ~5 seconds |
| 3rd | ~10 seconds |
| 4th | ~20 seconds |
| 5th | ~40 seconds |
If all 5 attempts fail, no further automatic retries occur. You can still trigger a manual retry from the dashboard or API at any time.
What Triggers a Retry
| Scenario | Retried? |
|---|---|
Your server returns 5xx | ✅ Yes |
| Connection refused / DNS failure / timeout | ✅ Yes |
Your server returns 4xx | ❌ No — treated as a client error |
Your server returns 2xx | ❌ No — delivery successful |
If your endpoint returns 4xx, BeeL. assumes the payload is invalid and will not retry. Return 5xx if you need BeeL. to retry (e.g. your database is temporarily unavailable).
Delivery Logs
BeeL. keeps a log of the last 50 delivery attempts per subscription. Each log entry records:
- Delivery timestamp and duration
- HTTP status code and response body
- All request headers sent (including
BeeL-Signature,BeeL-Event-Id,BeeL-Delivery-Id,BeeL-Event) - The full JSON payload that was sent
- The attempt number
- Error description (for failed deliveries)
View delivery logs
GET /v1/accounts/{account_id}/webhooks/{webhook_id}/deliveries — webhooks:read. Newest first,
paginated. Query params: page, limit, event_type (only deliveries of one event
type) and event_id (only deliveries of one event — use it to follow every attempt on
a single event without paging through the whole history).
curl "https://app.beel.es/api/v1/accounts/{account_id}/webhooks/3f7a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c/deliveries?event_type=verifactu.status.updated" \
-H "Authorization: Bearer beel_sk_live_xxx"{
"success": true,
"data": {
"deliveries": [
{
"id": "8ee6b023-c4e5-482e-93ca-dc66da2f9cb5",
"subscription_id": "3f7a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c",
"webhook_event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"event_type": "verifactu.status.updated",
"attempt_number": 1,
"http_status": 200,
"success": true,
"duration_ms": 142,
"response_body": "OK",
"error_message": null,
"request_headers": {
"BeeL-Signature": "t=1741362026,v1=3c4f7a2e...",
"BeeL-Event": "verifactu.status.updated",
"BeeL-Event-Id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"BeeL-Delivery-Id": "8ee6b023-c4e5-482e-93ca-dc66da2f9cb5",
"Idempotency-Key": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
},
"payload": "{\"id\":\"a1b2c3d4...\",\"type\":\"verifactu.status.updated\",...}",
"delivered_at": "2026-03-07T16:20:26Z"
}
],
"pagination": { "page": 1, "limit": 20, "total": 1, "total_pages": 1 }
}
}Reading a log entry
Every field of the entry is described in List webhook delivery logs. What the schema cannot tell you is which of them answer which question:
- "Is this the same event I already saw?" —
webhook_event_idgroups every attempt at one logical event and matches theBeeL-Event-Idheader;ididentifies this attempt and matchesBeeL-Delivery-Id. Deduplicate on the former, correlate your server logs with the latter. - "Did my endpoint refuse it, or never see it?" —
http_statusisnullwhen the connection itself failed (DNS, timeout, TLS), anderror_messagesays which. A populatedhttp_statusmeans your server answered and the payload reached it. - "Can I replay it myself?" —
request_headersandpayloadhold the exact bytes and signature that were sent, so you can re-run your verification offline against a delivery that failed, without waiting for the next one.
Manual Retry
POST /v1/accounts/{account_id}/webhooks/{webhook_id}/deliveries/{delivery_id}/retry —
webhooks:write. Triggers a retry for any delivery, successful or not:
curl -X POST \
"https://app.beel.es/api/v1/accounts/{account_id}/webhooks/3f7a1b2c-4d5e-6f7a-8b9c-0d1e2f3a4b5c/deliveries/8ee6b023-c4e5-482e-93ca-dc66da2f9cb5/retry" \
-H "Authorization: Bearer beel_sk_live_xxx" \
-H "Idempotency-Key: $(uuidgen)"This uses the original payload and generates a new signature with a fresh timestamp. A new delivery log entry is created with the result.
Endpoint Requirements
To ensure reliable delivery, your endpoint should:
- Respond within 10 seconds — BeeL. does not wait longer
- Return
2xximmediately and process the event asynchronously if needed - Return
5xxif you are temporarily unable to process (triggers a retry) - Not return
4xxunless the payload itself is the problem
// ✅ Good: acknowledge immediately, process async
app.post('/webhooks/beel', async (req, res) => {
res.status(200).send('OK'); // respond first
await queue.push(req.body); // process later
});
// ❌ Bad: synchronous processing blocks the response
app.post('/webhooks/beel', async (req, res) => {
await processEventSynchronously(req.body); // may exceed 10s timeout
res.status(200).send('OK');
});