Safe retries
At the end of this guide a retried write never creates a second record.
The key
Send an Idempotency-Key header on any request that creates something. Use a new random value per intended write, such as a UUID, between 1 and 255 visible characters. Keep it with the work item so a retry sends the same key.
curl -X POST https://host.shiftly.au/v1/timesheets \
-H "Authorization: Bearer ..." \
-H "Idempotency-Key: 9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d" \
-H "Content-Type: application/json" \
-d '{ "employee_id": "...", "location_id": "...", "position_id": "...",
"start_time": "2026-10-06T09:00:00+11:00", "end_time": "2026-10-06T17:00:00+11:00" }'What happens on a repeat
Within 24 hours of the first request, a repeat with the same key and the same body returns the first response, status and all, with the header Idempotent-Replay: true. Nothing is created twice. After 24 hours the key is forgotten and the request runs as new.
Keys are scoped to your connection, so two businesses using the same key do not collide. A first request that is refused or fails is not remembered: the key is released, so you can correct the request and send it again with the same key.
What can go wrong
| You see | Why | What to do |
|---|---|---|
| 409 idempotency_key_reused | The same key was sent with a different body. | Use a new key for a different write. |
| 409 request_in_progress | The first request with this key is still running. | Wait a moment and send the same request again. |
| 400 invalid_request naming Idempotency-Key | The key is empty, over 255 characters, or has control characters. | Send a UUID. |
