Skip to main content
Networks are unreliable. A request can succeed on the server but the response never reaches you — leaving you unsure whether to retry. Idempotency removes that risk: you attach a unique key to each write, and the API guarantees the operation happens at most once.

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:
If the Idempotency-Key header is missing, the request is rejected with HTTP 400. There is no implicit default.
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 whose Idempotency-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.
A replayed response carries the header 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.
Reusing a key with a different request body is rejected with HTTP 409 Conflict — the server refuses to guess which version you meant. Retries must resend the exact same body; a new operation needs a new key. See Errors.