Workflow SDK adds idempotent starts
The Workflow SDK's start() function can now admit a run and claim a hook in one atomic step. Duplicate workflow starts fail safely. The atomic start replaces the previous getHookByToken()-then-start() pattern, whose gap between the lookup and the start left a documented duplicate-start race.
Subscribe to messages inside the run
The claimed Hook exists from the moment the run is admitted, so resumeHook works even before the run begins executing, and early payloads are buffered and delivered in order. Inside the workflow, createHook({ token }) with the same token binds to the already-claimed hook: guaranteed, registering nothing new, adding no step, and resolving getConflict() to null.
Idempotency with no extra code
The token is the idempotency key, and it comes from your own domain: an order ID, an invoice ID, an import ID, or a request ID. The token alone guarantees idempotency. Exactly one run owns it, and a duplicate start() throws HookConflictError carrying the owner's conflictingRunId and never becomes a run. The workflow doesn't have to open the hook at all, and if it never does, the token was only an idempotency key and the run completes normally.
Setting experimental_minRetention keeps the token unavailable after the run ends, counted from start(), so late duplicates are still refused.
Upgrade to workflow 5.3.1 and read the idempotency documentation to get started.