Retiring a webhook endpoint: Sume runs already carrying it still POST

Any run created with a webhook_url can POST when it ends, even after you decommission the endpoint. Retries run 10 times, and the receipt holds the real result.

5 min readSume
All posts

If you retire a webhook endpoint while runs are in flight, those runs will still try to POST to it. The URL is stored on the run when you create it, and the docs state that any run whose caller supplied a webhook_url can receive a POST, including older runs that reach a terminal state later. So do not shut the endpoint down on the day you change the URL in your code. Keep it answering until the last run that carries the old URL has ended, or accept that those deliveries will fail and recover the results by polling.

What Sume does when your endpoint is gone

One signed POST is sent when a run completes or fails. A delivery outcome never changes the run: the run is finished, the result stays on the receipt whatever your server returned. The webhook_delivery block on each receipt shows the delivery state.

`webhook_delivery.status`MeaningYour move
not_armedURL stored; the run is still in progressNothing yet
retryingAn attempt failed; next_attempt_at is the next oneNothing, unless last_status_code points at a fault on your side
failed, exhaustedTen attempts failed on a refusal, a 10 s timeout or a redirect, or the URL failed re-validationRead result_url, fix the endpoint, POST …/webhook/redeliver

Retries use the longer of two values: exponential backoff (30 seconds times 2 to the power of attempt minus 1, with jitter), or your Retry-After on a 429 or 503. The longest backoff is one hour. An endpoint that returns 503 with a Retry-After is therefore a polite way to slow deliveries, but an endpoint that is simply gone consumes all ten attempts and then shows exhausted.

A safe retirement sequence

  • Create new runs with the new communication.webhook_url. Runs started before the change keep the old URL.
  • Keep the old endpoint alive and verifying signatures. Make it forward to the new handler, or return 2xx and record run_id for later reconciliation.
  • List your open runs from your own table (there is no cross-Format list route) and wait until none carry the old URL.
  • For runs whose old deliveries already ended in failed or exhausted, read the receipt from result_url. You do not need the webhook to get the result.
  • Only then remove the old route. If you remove it early, poll the affected runs and replay with POST …/webhook/redeliver once a new receiver exists.

Which endpoints can you choose

The docs advise registering only the endpoints where you still want traffic. Delivery is live on both api.dev.sume.com and api.sume.com, so a URL supplied on a development run will really be called. Use a separate URL per environment, and never point a development run at a production receiver unless you want its traffic there.

Do not return a redirect from the old route to the new one. Sume does not follow redirects, and a 3xx is not a delivery. Answer on the old route itself, or let the attempts fail and replay them later.

Signing secret rotation is separate

Moving endpoints does not change the signing secret, and rotating the secret does not change URLs. A rotation is not a cutover either: for 24 hours Sume signs each delivery with both secrets, newest first, in x-sume-webhook-signature. A receiver that holds either secret can verify. If you are retiring an endpoint and rotating at the same time, do the receiver upgrade first. The Run webhooks page has the delivery rules, and the SDK webhooks page covers verifyWebhook and the rotation window.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume