Webhook retries and disabled endpoints
Use this page when a delivery did not arrive, when an endpoint stopped receiving, or when you need to replace a signing secret. Sealcord retries a failed delivery on a fixed schedule, keeps a log of every attempt, and lets you send a delivery again.
Retries
Section titled “Retries”Any answer outside 2xx, a 3xx included, or no answer at all, is retried. The one exception is
410 Gone, which fails the delivery and turns the endpoint off.
An event over 64 KB is never sent, so it is never retried.
| Attempt | After the previous one | After the first |
|---|---|---|
| 1 | within seconds | |
| 2 | 30 seconds | 30 s |
| 3 | 2 minutes | 2 min 30 s |
| 4 | 10 minutes | 12 min 30 s |
| 5 | 1 hour | 1 h 12 min 30 s |
| 6 | 6 hours | 7 h 12 min 30 s |
| 7 | 24 hours | 31 h 12 min 30 s |
| 8 | 24 hours | 55 h 12 min 30 s |
Each wait is counted from the end of the attempt before, and Sealcord looks for due deliveries
every 5 seconds, so the times are approximate. After the eighth attempt the delivery is failed.
Each attempt is signed afresh, so a retry passes the 5-minute timestamp check. An attempt that fails on Sealcord’s side before anything is sent uses up no attempt and is tried again every 10 minutes.
See what was sent
Section titled “See what was sent”The deliveries log shows each delivery’s status, attempts, next try and your last status code.
When there was no usable answer, it shows an error code instead. Open it in the Console under
Webhooks, on an endpoint’s Deliveries tab, or
list the deliveries with the Admin API.
A delivery’s status is pending, succeeded or failed. Deliveries are kept 30 days.
Sealcord keeps only your status code and an error code. It never keeps the body of your answer.
Error codes
Section titled “Error codes”| Code | What happened |
|---|---|
timeout |
No answer within 5 seconds, the host lookup included |
dns_failed |
The host does not exist or has no address |
dns_error |
Sealcord’s resolver failed, or no address came within 5 seconds |
address_refused |
The host resolved to an address that is not public |
url_refused |
The URL no longer passes the URL rules |
connection_refused |
Your server refused the connection |
connection_reset |
The connection was reset |
host_unreachable |
No route to the host |
tls_error |
The TLS handshake failed |
connection_failed |
The connection failed for another reason |
bad_response |
The answer was not a usable HTTP response |
secret_unreadable |
Sealcord could not open the endpoint’s secret |
payload_too_large |
The event is over 64 KB: the delivery failed and was never sent |
internal_error |
A fault on Sealcord’s side |
An answer outside 2xx shows its status code and no error code. Sealcord’s own faults
(secret_unreadable, internal_error and dns_error) never turn an endpoint off.
Send a delivery again
Section titled “Send a delivery again”Retry queues a delivery again, due now, with its attempts back to 0 and a fresh schedule,
whatever its status. Use it with the Admin API
(retry a delivery) or with the MCP
tool sealcord_retry_webhook_delivery. The Console offers Retry delivery on a retrying or failed
delivery, while its endpoint is on. A delivery that was already delivered is sent again under
the same webhook-id, so your receiver must skip a repeat. See
answer quickly and de-duplicate.
When an endpoint is turned off
Section titled “When an endpoint is turned off”An endpoint can be turned off in three ways:
- A
410 Goneanswer turns it off at once, withdisabled_reasongone. Answer410when you take a URL down for good. - Repeated failures turn it off, with
disabled_reasonfailing: a delivery fails after its eighth attempt and none of the endpoint’s deliveries succeeded in the 72 hours before. Sealcord’s own faults never count. - You turn it off, with
disabled_reasonmanual, and on again in the Console (Turn off endpoint, Turn on endpoint) or with the Admin API (change an endpoint).
When Sealcord turns an endpoint off, it emails your organization’s owners and admins.
A turned-off endpoint gets no new deliveries. Changes made while it is off are never sent to it, so after you turn it back on, read what changed from the API. Deliveries already queued for it wait, and are sent as they come due once it is on again. Turning it on clears whatever turned it off.
Replace the signing secret
Section titled “Replace the signing secret”Replace the secret in the Console, on the endpoint’s Settings tab with Replace secret, or with the Admin API (rotate the secret). The answer shows the new secret once.
For the next 24 hours, every request carries two signatures: the new secret’s and the old one’s. Your receiver accepts it with either, so you can deploy the new secret at any moment in those 24 hours without missing a delivery. After that only the new secret signs.
After a leak, replace the secret, deploy the new one, and stop accepting the leaked one at once. Your receiver decides which secret it trusts, whatever Sealcord signs with. Replacing it again within the 24 hours stops the oldest secret signing at once. The one in between signs for 24 hours from that second replacement.
Questions
Section titled “Questions”How long does Sealcord keep retrying?
Section titled “How long does Sealcord keep retrying?”Eight attempts over about 55 hours. After the eighth, the delivery is failed, and you can retry
it by hand while its event exists, 30 days after it happened.
Why did my endpoint stop receiving events?
Section titled “Why did my endpoint stop receiving events?”Look at its status in the Console. If it is off, disabled_reason says why: gone after a 410
answer, failing after repeated failures, or manual. Fix the receiver, turn the endpoint on, and
read missed changes from the API.
Will I get the events from while the endpoint was off?
Section titled “Will I get the events from while the endpoint was off?”No. Only deliveries queued before it was turned off are sent. Read the changes from the API, for example with the licences list.
Can I get the same event twice?
Section titled “Can I get the same event twice?”Yes. Delivery is at least once, and a manual retry sends the same event again with the same
webhook-id. Skip an id you already handled.