e-bon
e-bon.ro
Troubleshooting

Webhook delivery failures and auto-disable

How to interpret `lastError`, the 5-attempt backoff schedule, the 20-failure auto-disable, and how to re-enable a webhook safely.

When your endpoint stops receiving webhook events, the question is always: did e-bon stop sending, or did it keep sending but your endpoint started failing? This recipe walks the full failure-and-disable lifecycle so you can tell the difference and recover.

A webhook auto-disabled by the platform sets enabled: false on the subscription. Until you re-enable it via PATCH /api/v1/org/webhooks/{id}, no new events are dispatched at all — not even webhook.test. Existing in-flight retries continue until they exhaust their attempts.

How delivery and retry work

  • Per-attempt timeout — each delivery attempt has 10 seconds to return a 2xx response. After that, the request is aborted and counted as a failure.
  • Retry backoff — failed attempts are retried on a fixed schedule: 1 min → 5 min → 30 min → 2 h → 12 h.
  • Max attempts — 5 attempts total. After the 5th failure the delivery moves to failed and is never retried again.
  • Auto-disable threshold — after 20 consecutive failed deliveries on the same webhook, the subscription is automatically set to enabled: false.
  • Response capture — up to 500 characters of your endpoint's response body are stored on each delivery record so you can debug what your server returned.
  • Retry sweep — pending retries are picked up every 30 seconds, so a scheduled retry will fire within ~30 s of its nextRetryAt.

Likely causes

  • Endpoint returns non-2xx — anything other than 200299 counts as a failure. 301/302 redirects are not followed.
  • Endpoint exceeds 10 s — the per-attempt AbortController cuts the request even if your handler eventually responds.
  • Hostname / TLS / DNS errors — the fetch rejects before the response arrives; the error message lands in delivery.error.
  • Subscription auto-disabledfailureCount hit 20 and the sweeper stopped dispatching new events to this subscription.

How to verify

Browse delivery history for the affected webhook:

curl https://api.e-bon.ro/api/v1/org/webhooks/{webhookId}/deliveries \
  -H "Authorization: Bearer <jwt>"

A failed delivery looks like this:

{
  "id": "del_abc123",
  "status": "failed",
  "attempt": 5,
  "httpStatus": 502,
  "responseBody": "Bad Gateway",
  "error": "http 502",
  "attemptedAt": "2026-04-23T20:09:55.000Z"
}

Check the parent webhook to see whether it was auto-disabled:

curl https://api.e-bon.ro/api/v1/org/webhooks/{webhookId} \
  -H "Authorization: Bearer <jwt>"

Look for "enabled": false and a high failureCount (≥ 20).

Fix

Fix the underlying endpoint

Make sure your endpoint returns a 2xx within 10 seconds for any payload e-bon will throw at it. Acknowledge first, then queue the heavy work — the body has been captured in responseBody (up to 500 chars), so you can reproduce locally.

Send a test delivery

Once the endpoint is healthy, fire a test event with the webhook still in its current state:

curl -X POST https://api.e-bon.ro/api/v1/org/webhooks/{webhookId}/test \
  -H "Authorization: Bearer <jwt>"

You will receive a webhook.test event. Confirm it lands and your endpoint returns 2xx. (If the webhook is already auto-disabled, the test endpoint will reject with 409 CONFLICT until you re-enable it — see next step.)

Re-enable the subscription

If the webhook was auto-disabled, flip it back on. This also resets failureCount server-side on the next successful delivery:

curl -X PATCH https://api.e-bon.ro/api/v1/org/webhooks/{webhookId} \
  -H "Authorization: Bearer <jwt>" \
  -H "Content-Type: application/json" \
  -d '{ "enabled": true }'

Replay the missed window only if you need to

e-bon does not automatically replay events that were dispatched while your endpoint was down — they stayed pending and were retried up to the 12-hour mark, then went failed. If you need to backfill, query the relevant resource (e.g. GET /api/v1/receipts?since=…) and reconcile against your own state.

Full per-event payload reference: Webhook events. Subscription CRUD, secret rotation and delivery history endpoints: Webhooks API.

Still stuck?

Open a support case at support@e-bon.ro or e-bon.ro/contact with the webhookId, a recent failed deliveryId, the captured responseBody, and your endpoint's hostname so support can correlate dispatch logs.