Endpoint health & suspension

Ask whether an endpoint is healthy, and what happens when it is not.

Ask the API

GET /api/v1/webhooks/{endpoint_id}/health (needs webhooks:read) returns a windowed rollup for one endpoint:

curl -sS https://api.drazill.com/api/v1/webhooks/$ID/health -H "X-API-Key: $KEY"
{
"endpoint_id": "…", "status": "ACTIVE",
"succeeded_24h": 412, "dead_letter_24h": 3, "success_rate_24h": 0.9928,
"succeeded_7d": 2860, "dead_letter_7d": 11, "success_rate_7d": 0.9962,
"consecutive_failures": 0, "dlq_count": 11,
"last_success_at": "…", "last_failure_at": "…", "last_error": "HTTP 502",
"replays_24h": 0, "suspended_at": null, "suspension_reason": null
}

The endpoints list (GET /api/v1/webhooks) carries a compact health summary on every endpoint — success_rate_24h, consecutive_failures, dlq_count, replays_24h — so a dashboard can badge every endpoint without a request per row.

Two things about these numbers are worth knowing, because they change how you read them:

  • success_rate_24h is null, not 1.0, when the window holds no terminal delivery. A quiet endpoint has unknown health, not perfect health.
  • Replays are excluded from the rates and from consecutive_failures, and reported separately as replays_24h. Recovering a backlog does not move your success rate in either direction — it is not new evidence about your receiver.

consecutive_failures counts dead-lettered original deliveries newer than your endpoint’s most recent success. Any success ends the streak, including a successful replay.

Automatic suspension

An endpoint that keeps failing is eventually suspended: Drazill stops attempting delivery to it. Both conditions must hold:

  • it has dead-lettered 20 consecutive deliveries (replays never count), and
  • it has had no successful delivery in 24 hours.

The second condition is why a brief outage on a busy endpoint does not suspend it.

Suspension does not drop events. Deliveries queued for a suspended endpoint stay queued — they are simply not attempted — and resume from exactly where they stopped when you reactivate. This is the difference between suspension and deletion, and it is deliberate: an at-least-once system must not destroy accepted deliveries.

When an endpoint is suspended, its owner gets an in-app notification and an email. Neither contains the full endpoint URL (it can carry a token in its query string) or the signing secret — only the scheme, host, and a truncated path.

Reactivating

Fix the receiver, then:

curl -sS -X POST https://api.drazill.com/api/v1/webhooks/$ID/reactivate -H "X-API-Key: $KEY"

Reactivation clears the suspension, resets the failure-streak baseline (so the backlog that caused the suspension cannot immediately re-suspend the endpoint), and resumes delivery of the held queue on the next drain.

Reactivate applies to suspended endpoints only. Deleting an endpoint (DELETE /webhooks/{id}) sets it to DISABLED, which is terminal: it cancels the endpoint’s queued deliveries, and re-enabling it does not bring them back.

StateSet byQueued deliveriesRecoverable
ACTIVEyoudelivered—
SUSPENDEDDrazill, automaticallyheldyes — POST /webhooks/{id}/reactivate
DISABLEDyoucancelledno

How many endpoints you can have

Endpoints are capped per user by the highest tier among your active API keys. The cap bounds fan-out at its source: every event is delivered once per subscribed endpoint.

TierEndpoints
Free3
Pro10
Enterprise25

ACTIVE and SUSPENDED endpoints both count toward the cap; DISABLED ones do not. Creating one past your cap returns 422 with the code WEBHOOK_ENDPOINT_CAP_REACHED and the cap, your current count, and your tier. If a cap is ever lowered below what you already have, your existing endpoints keep delivering — you simply cannot add another until you are back under it.