Webhook delivery when an endpoint fails
SET API, SET Merchant API and SET Direct Deposit API · Live since 2026-11-09
The problem
Every business on SET shares one webhook sender. Before 9 November 2026, a business whose endpoint hung could hold up other businesses' events: each delivery waited for its timeout before the next was tried. An endpoint that had been gone for weeks was also retried forever.
How delivery works now
Each delivery pass:
- takes due events round-robin by endpoint: at most 5 per endpoint and 50 in all, each endpoint's oldest first;
- sends to up to 10 endpoints at once, and each endpoint's own events in order, one after the other;
- stops an endpoint for the pass at its first failure. A hanging endpoint costs one timeout per pass, and its other events wait for the next pass, untouched.
A slow or failing endpoint now delays only its own events, never another business's.
The retry schedule for each event is unchanged: after 1 minute, doubling, at most a day apart, 15 tries. Delivery is still at least once, so deduplicate on the event id.
When SET pauses an endpoint
SET pauses an endpoint that has failed every delivery for at least 24 hours and at least 20 times in a row. Both must hold:
- a short outage with many events never pauses an endpoint;
- one event, which is tried at most 15 times, never does.
When it pauses one:
- You get one
webhook_endpoint.disabledevent, with counts and times only: ``{ "object": "webhook_endpoint", "id": "primary", "url": "https://example.com/set-webhooks", "status": "disabled", "disabledAt": "…", "failures": 23, "failingSince": "…", "reason": "failing", "message": "…" }`` It is listed, and sent to your other endpoints if you have any. - The endpoint shows
status: "disabled"anddisabledAt(GET /v1/webhook_endpoints,GET /api/partner/webhook_endpoints). - Every event stays listed at
GET /v1/eventsorGET /api/partner/events. Nothing is lost; poll while you fix the endpoint.
Resuming
Set the URL again:
| Endpoint | Call |
|---|---|
Your first endpoint (primary), SET API | POST /v1/webhook_endpoint {url} |
Your first endpoint (primary), Direct Deposit | POST /api/partner/webhook_endpoint {url} |
| A further endpoint | POST /v1/webhook_endpoints/{id} or POST /api/partner/webhook_endpoints/{id}, with any change |
On a first endpoint, changing only the event filter does not resume it. Events missed while the endpoint was paused are sent once it resumes.
Your checklist
- Answer
2xxquickly, and do the work after you answer. - Deduplicate on
id. - Subscribe a second endpoint (for example your alerting) to
webhook_endpoint.disabled, so you hear about a pause even when your main endpoint is down.