GitHub wants a 2xx in 10 seconds: Sume times out at 10 too
GitHub says respond 2XX within 10 seconds. Sume also gives each delivery attempt 10 seconds, so store the event first and do the work after you answer.

GitHub's best practices page tells you to respond with a 2XX within 10 seconds. Sume's docs give each webhook attempt the same 10-second timeout. A receiver that downloads the finished media inside the request will lose the race on a slow file, and Sume will count the attempt as failed and retry.
The shared rule
Both vendors want the same shape: verify, record, answer, then work. GitHub also says redelivery is allowed and that the X-GitHub-Delivery header stays identical across redeliveries, so you can use it to detect duplicates. Sume gives you a different stable id, which depends on the family.
| Rule | GitHub | Sume |
|---|---|---|
| Respond within | 10 seconds with a 2XX | 10 seconds per attempt, any 2xx |
| Dedupe on | X-GitHub-Delivery, identical on redelivery | job_id for jobs, request_id (the run id) for Format runs |
| Retry spacing | Redelivery is allowed; the page gives no schedule | Jobs: fixed 30s by default. Runs: 30s x 2^(attempt-1) with jitter |
| Attempts | Not stated on the page I read | Up to 10 in total |
What to do inside the request
Do three things before you return 200: check the signature over the raw body, write the event id and body to durable storage, and enqueue the follow-up. Anything that touches the network, such as downloading an artifact or calling another API, belongs in the worker.
Sume's docs say it plainly: return any 2xx after durably storing the event. A slow endpoint burns the attempt budget and gets retried, and ten refused attempts leave a failed delivery but a job that still reached its real terminal state.
- Verify with the raw bytes, not a re-serialised JSON body.
- Store job_id (or request_id) in a unique column so a duplicate insert fails cleanly.
- Return 200 for a duplicate. Returning an error for a duplicate causes more retries.
- Keep polling status_url for jobs whose webhook never arrives.
A note on redelivery
When you redeliver from Sume, the timestamp and signature are fresh but the job_id is the same. A receiver that dedupes on the id will therefore skip the work, which is what you want. A receiver that dedupes on the timestamp or on a hash of the whole request will process it twice.
Testing the 10-second line
Add a deliberate delay to a staging receiver and watch what the sender reports. Set it to 12 seconds and confirm the delivery row shows a timeout and a retry, then set it to 2 seconds and confirm the row goes green. Sume's dashboard shows delivery status and the attempt count on the job, so you can see the retry without reading server logs.
If your handler has to do heavy work, move it to a queue worker that reads from your own table. The webhook then becomes a trigger, and the real source of truth is the stored event plus the job on Sume. That separation also makes a bad deploy harmless, since events keep landing while the worker is fixed.
Sources
Related posts
More in Developers
- GPT Image 2.5 complex prompts take up to 2 minutes: use a webhook
OpenAI says complex GPT Image prompts may take up to 2 minutes. Sume waits 30 seconds, then returns a job. Send mode webhook and read the result from the job.
- GPT Image 2.5 edit changed shape? Use aspect_ratio auto on Sume
On Sume edit and image-to-image calls, aspect_ratio auto is not the same as leaving the field out. How to read the model descriptor and keep the photo's shape.
- GPT Image 2.5 image_size rules: validate in Python before you send
Custom image_size on GPT Image 2.5 needs edges in multiples of 16, max edge 3840, aspect 3:1 or less, and 655,360 to 8,294,400 pixels. A Python checker for it.
- GPT Image 2.5 edit with several references: number each image
With up to 16 references in a GPT Image 2.5 edit, name each one by number and role in the prompt. A Sume request with three references, and what to check.
Written by Sume