API/Idempotency
Get started
Idempotency
Idempotency keys make it safe to retry a request without risking the same payout being created twice.
Send the header Idempotency-key on requests that have side effects. The key is stored on your partner account, and the API uses it to recognise a request it has already processed.
The rules
| Situation | Result |
|---|---|
| The header is omitted | The request is processed as normal. The header is optional. |
| The value is not a valid UUID | 400 – the key is rejected before the request is executed. |
| The key is already stored for the partner | 400 – the key has been used. The side effect is not executed again. |
| New, valid UUID | The request is executed and the key is stored. |
The check against the store is performed for all routes as soon as the key exists there. Therefore use one fresh UUID per logical operation – do not reuse the same key across different calls.
Especially for payouts
The header is recommended on POST /payouts. This is where a repeat does the most damage: without an idempotency key, a network failure that makes you retry can cause the same payouts to be created twice. For pure read operations you normally do not need it.
curl --location --request POST 'https://app.easyfreelance.no/api/v1/payouts' \ --header 'Content-Type: application/json' \ --header 'Authorization: Bearer <token>' \ --header 'API-key: <api-key>' \ --header 'Idempotency-key: 6922d7be-c098-11ec-9d64-0242ac120004' \ --data '{"due_date":"2026-09-15","payouts":[...]}'
Recommended pattern
Generate the key before the first attempt
Create one UUID when you decide to send the payout, and store it together with the payout row in your own system.
Use the same key when retrying
If you get a timeout or a 5XX response, retry with exactly the same key. The API then knows that it is the same operation.
Treat 400 as “already done”
The API responds
400because the key has been used, it means the first request went through. Feel free to verify withGET /payoutsbefore you mark the row as failed.
Keys have a limited lifetime. If a long time has passed since the previous attempt, you should check the result with GET /payouts rather than relying on the key still being stored.