Hatchet durable event wait: let a Sume webhook wake the task

A Hatchet durable task can wait for an event instead of polling. Send Sume's signed terminal webhook into that event, and keep a status read as the fallback.

5 min readSume
All posts

The answer

Hatchet's durable execution page says durable tasks do one of two things: wait for something such as a sleep or an event, or spawn child tasks. Sume sends a signed webhook when a job reaches a terminal state. Wire the two together: a small receiver verifies the signature and pushes a Hatchet event, and the durable task waiting on that event wakes without polling.

Treat the webhook as an optimization. Sume's docs say delivery is not the only source of truth, so the task should also have a timeout path that reads the job status.

What Sume sends

Sume's webhook page says it sends terminal job events only: job.completed, job.failed and job.canceled, with no progress or partial events. Deliveries are signed with a sume-v1 HMAC, so your receiver recomputes the signature with the webhook secret and refuses the request on a mismatch or an empty secret.

Event wait with a status fallback (read 2026-10-03)
StepMechanismSource of truth
SubmitPOST with mode webhook and an Idempotency-KeyJob id in the response
WaitDurable event wait in HatchetEvent pushed by your receiver
TimeoutDurable sleep races the eventGET /v1/jobs/{id}/status
FetchGET /v1/jobs/{id}/result409 until result_ready

Racing the event against a sleep

The Hatchet page notes that waits can be composed, so a task can wait for either a sleep to complete or an event, whichever comes first. Use that: wait for the event, with a sleep slightly longer than the usual job time. If the sleep wins, read the status. If the status is not terminal, wait again. This gives you a bounded wait even if a delivery is lost.

Sume retries failed deliveries on a schedule of its own, and exposes a redeliver call for a job's webhook if you missed one. Use that before deciding a job is stuck.

Receiver rules

Verify on the raw body, before parsing. Return success only after you have pushed the event, so a failed push triggers Sume's retry. Make the push idempotent on the job id, since a retry can deliver the same event twice. The Python verifier post has a runnable check that refuses an empty secret.

When to skip webhooks

If your workers cannot be reached from the internet, or the job is short, a sleep and a status read are simpler. Use next_poll_after_seconds from the response as the delay so you stay inside the server's guidance.

Handling the awkward cases

A delivery can arrive before your task starts waiting, for example when the job finishes in a few seconds. Make the receiver store the event or push it under a key derived from the job id, so a task that begins waiting later still sees it. Whether your event system buffers events that arrived before a waiter existed is something to confirm in Hatchet's event documentation before relying on it.

If you rotate the webhook secret, verify against both the old and new secrets during the overlap, as the SDK verifyWebhook post describes, or you will drop legitimate deliveries and fall back to the sleep path.

Sources

Related posts

More in Developers

All Developers posts

Written by Sume