Webhooks overview
Waiting calls answer a question you ask. Webhooks tell you about things you did not ask about: a number’s status
changed, a mailbox needs to be authorized again, the balance is low. You subscribe a URL of yours to events and we
send a signed POST to it for each one.
Webhook endpoints belong to a project and receive that project’s events. balance.low is a team event and is sent to
the endpoints of all of the team’s projects.
Create an endpoint
Section titled “Create an endpoint”Create an endpoint in the console (Webhooks), or with the API:
curl -X POST https://api.clearance.rest/webhooks/endpoints \ -H "X-API-Key: $CLEARANCE_REST_API_KEY" \ -H "content-type: application/json" \ -d '{ "url": "https://app.example.com/hooks/clearance", "event_types": ["number.*", "balance.low"], "description": "production" }'urlmust behttps(plainhttpis accepted only forlocalhost), at most 2048 characters, without embedded credentials, and not on aclearance.resthost.event_typesis a list of up to 32 patterns: an exact name (number.renewal_failed), a family (number.*,email_account.*,balance.*) or*for everything. Opt-in events are delivered only when named exactly.secret(16 to 128 characters) is optional; one is generated if you omit it.- A project can have 20 endpoints.
The response contains the endpoint’s signing secret, a whsec_... string. It is returned only here and by
rotate-secret; store it. You need it to verify signatures.
What a delivery looks like
Section titled “What a delivery looks like”Each delivery is a POST with a JSON body, the event:
{ "id": "evt_0190...", "type": "number.status_changed", "created_at": "2026-10-25T10:00:00.000Z", "data": { }}and these headers:
| Header | |
|---|---|
X-Webhook-Id |
The delivery’s id. |
X-Webhook-Event-Id |
The event’s id. It does not change across retries. |
X-Webhook-Event |
The event type. |
X-Webhook-Timestamp |
Unix time in seconds, used in the signature. Renewed on every attempt. |
X-Webhook-Attempt |
The attempt number, from 1. |
X-Webhook-Signature |
v1= and the hex HMAC-SHA256 signature. |
Delivery guarantees
Section titled “Delivery guarantees”- At least once, unordered. Deduplicate on
event.id; do not rely on the order events arrive in. - Acknowledge with any
2xx. Anything else is a failure: other statuses (redirects are not followed), connection errors, and a response that takes longer than 10 seconds. - Retries. After a failure we retry after about 30 seconds, 2 minutes, 10 minutes, 30 minutes, 1 hour,
3 hours, 6 hours and 12 hours (each varied by up to 20%). Then the delivery is marked
failed. - Auto-disable. An endpoint with 50 failed deliveries in a row is disabled (
disabled_reason: "failing"). Fix the receiver and setenabled: trueto turn it back on. - Respond quickly and process the event afterwards.
Manage endpoints and deliveries
Section titled “Manage endpoints and deliveries”| Request | |
|---|---|
GET /webhooks/event-types |
The event types you can subscribe to, and which are opt-in. |
GET, POST /webhooks/endpoints |
List and create endpoints. |
GET, PATCH, DELETE /webhooks/endpoints/{id} |
Read, change and remove one. |
POST /webhooks/endpoints/{id}/rotate-secret |
Issue a new secret. The old one stops working at once. |
POST /webhooks/endpoints/{id}/test |
Queue a webhook.test event to this endpoint. |
GET /webhooks/endpoints/{id}/deliveries |
Delivery history, newest first. Filter by status: pending, succeeded, failed. |
GET /webhooks/deliveries/{id} |
One delivery, with the event that was sent. |
POST /webhooks/deliveries/{id}/retry |
Queue a failed delivery again. |
Delivery records are kept, so you can always see what was sent to you and how your server answered.