Idempotency
A timeout tells you nothing about whether the work happened. Send an Idempotency-Key on every mutating call and the retry is free: the engine returns the first response instead of acting twice.
curl -X POST https://api.indpayroll.com/v1/payroll-runs/run_2026_09_0042/mark-paid \
-H "Authorization: Bearer $INDP_API_KEY" \
-H "Idempotency-Key: markpaid-run-2026-09-0042" \
-H "Content-Type: application/json" \
-d '{ "paid_on": "2026-10-05", "payment_method_id": 2 }'The rules
- Keys are scoped to the API key and remembered for 24 hours.
- A replay within that window returns the original status and body, and changes nothing.
- Reusing a key with a different body returns
409 idempotency_key_reused- it is a bug, not a retry. - Keys are at most 255 characters. Derive them from your own identifiers, not from a clock.
Where it matters most
calculate, mark-paid, reverse and the FnF endpoints. A double calculation wastes a cycle; a double mark-paid corrupts what you tell your customer they disbursed.GET requests need no key - they change nothing. PUT endpoints that replace a whole resource are already idempotent by shape, but a key still protects you from an interleaved retry landing after a later write.