Idempotency
Retry a write safely. Send the same Idempotency-Key, and you get the first answer again instead of a second write.
A network can lose an answer after the write happened. Without a key, your retry starts a second run or makes a second workflow.
Send a key
Choose a key that names this one attempt, such as an order number. Send it again only when you retry the same request.
curl -X POST "$GORUNNER/api/workflows/$ID/run?environment=production" \
-H "Authorization: Bearer $GORUNNER_TOKEN" \
-H "Idempotency-Key: order-A-1001" \
-H "Content-Type: application/json" \
-d '{"name": "Ada"}'HTTP/1.1 202 Accepted
{"data": {"id": "61af1b4f-…", "status": "pending", …}}
The same call again:
HTTP/1.1 202 Accepted
Idempotency-Replayed: true
{"data": {"id": "61af1b4f-…", "status": "pending", …}}The retry gets the first answer, marked Idempotency-Replayed: true. Only one run was made.
Calls that take a key
- Create a workflow
POST /api/workflows- Import a workflow
POST /api/workflows/import- Duplicate a workflow
POST /api/workflows/{id}/duplicate- Get a new webhook address
POST /api/workflows/{id}/webhook/rotate- Run a workflow
POST /api/workflows/{id}/run- Run a run again
POST /api/runs/{id}/rerun- Run many runs again
POST /api/runs/rerun- Create a connection
POST /api/connections- Make a workflow from a template
POST /api/templates/{id}/use
Most Partner API POSTs take one too. These don’t: /login-codes, /accounts/{accountId}/tokens, /accounts/{accountId}/connections/oauth2/start, and /oauth-requests/{requestId}/complete and /deny. Each answers once, by design. An AI app’s run tools take the same thing as idempotencyKey.
A call to a workflow’s webhook takes one too, with its own rules: its keys belong to the workflow, not a token, a failed run’s answer is kept too, and no call is refused for too many keys. See Retry safely.
The rest need none. Publishing an unchanged draft gives back the same version. A PUT replaces, and can carry expectedRev. A DELETE is done once.
The rules
- The key
- Any text up to 255 characters. Longer is
400 VALIDATION_ERROR. - Whose
- Each token, or each signed-in person, has its own keys. Two tokens can use the same key.
- How long
- 24 hours after a successful answer. A failed answer isn’t kept, so fix the request and retry with the same key.
- How many
- At most 10,000 kept at once for one token or person. A new key past that is
429 RATE_LIMITED, withRetry-Afteruntil the oldest expires, and nothing is done. - A different request
- The same key with another method, path, query or body is
422 VALIDATION_ERROR. Soenvironment=testandproductionare different requests. - Still running
- A retry while the first is in progress waits up to a second, then answers
409 CONFLICT. Retry shortly. - A big answer
- An answer over 64 KB isn’t kept. The write still happens once, and a retry answers
409 CONFLICT: read the result with a get instead.
What if GoRunner can’t reach where it keeps the keys?
The call goes through without the key, so a retry could write twice. GoRunner logs it. This happens only while that store is down.