The Idempotency-Key header
Every POST (invoices, customers, items, and so on) requires an
Idempotency-Key header. It’s a client-generated unique string that identifies
this specific operation:
One exception:
POST /invoices/{id}/validate (and its credit-note twin) is a
read-only check that changes nothing, so it does not require an
Idempotency-Key — call it freely while fixing a draft.Choosing a key
- Make it unique per logical operation — for example one key per invoice you
intend to create. A UUID, or a stable business identifier like
invoice-2026-00042, both work. - Don’t reuse a key for a different operation. The key is what the server uses to recognise a duplicate.
- Generate it on the client before the first attempt, and reuse the same value on every retry of that same operation.
What happens on retry
When you send a request whoseIdempotency-Key the server has already processed,
it does not create a second record. Instead it safely returns the original
result of the first call:
1
First request
POST /invoices with Idempotency-Key: invoice-2026-00042 creates the
invoice and returns it.2
The response is lost
A timeout or dropped connection means you never see the response, so you don’t
know if it worked.
3
Retry with the same key
You resend the exact same request with the same
Idempotency-Key. The API
recognises the key and returns the original invoice — no duplicate is
created.Idempotency-Replayed: true so you
can tell it apart from a fresh execution.
This makes retries completely safe. Always retry with the same key rather than
generating a new one, otherwise the server treats it as a brand-new operation and
you may create a duplicate.