Documentation › Concepts
Idempotency
How Idempotency-Key and referencia prevent duplicate invoices, and how to repeat a call safely.
How to avoid a duplicate invoice
Two protections, which complement each other:
Idempotency-Key (header) |
referencia (body field) |
|
|---|---|---|
| What it is | Identifier of YOUR call attempt | Identifier of the invoice in YOUR system (e.g. order number) |
| Where it applies | POST /v1/nfse, POST /v1/lotes, POST /v1/webhooks and POST /v1/companies |
POST /v1/nfse and each item of POST /v1/lotes |
| Required | No, but recommended | No, but recommended |
| Scope | Account and environment (applies to all API keys of the account in that environment) | Company and environment |
| Validity | 24 hours of exclusive use; the response is kept for 30 days | Forever |
| Repeated | Returns the response stored the first time | 409 referencia_duplicada, with the nfse_id of the invoice that already exists |
| Size | Free text (a UUID works) | Up to 60 characters |
Use both. The Idempotency-Key handles the immediate retry (timeout,
network drop). The referencia always prevents a doubled invoice, even if your
system loses the key.
What happens in each case
| Situation | Result |
|---|---|
Same Idempotency-Key, same body |
The SAME response as the first time (status and body), without creating anything. Applies to 201, 202 and to the 422 nfse_rejeitada and falha_transmissao. |
Same Idempotency-Key, different body |
409 idempotencia_conflito. Nothing is created. |
| The first call with the key is still in progress | The second waits about 3 seconds. If the first has not finished, 409 conflito: wait and repeat. |
The first call ended in an error without creating anything (412, 422 validacao, 409 referencia_duplicada, 403, 404, 500) |
Nothing is stored: repeating with the same key runs again. |
| 24 hours have passed, same body | The SAME response as the first time, as before. The same request never becomes two invoices while the record exists (30 days). |
| 24 hours have passed, different body | The key is free: it is a new request and it runs. |
| 30 days have passed | The key record was deleted: the key counts as new. The referencia still protects. |
The body is compared as JSON, with the keys in order: whitespace and field order
do not count. In POST /v1/lotes with a spreadsheet, the "body" is the file
(hash) plus the form fields.
The repeated response is a snapshot of the first. If the first call returned
202 transmitindo and the invoice was authorized later, repeating the call returns the
same 202. For the current status, use GET /v1/nfse/{id}.
Correct retry
seu sistema Sudrel
| POST /v1/nfse |
| Idempotency-Key: 7f1c... referencia: PED-1001
|-------------------------------------------->|
| (timeout: a resposta se perdeu) | a nota foi criada
| |
| POST /v1/nfse (MESMA chave, MESMO corpo) |
|-------------------------------------------->|
|<--------------------------------------------| mesma resposta, mesma nota
Never generate a new
Idempotency-Keyto repeat the same invoice. A new key is a new request. If thereferenciais also new, another invoice is issued.
In a batch, send referencia in each item: the line whose reference already became an invoice
appears as ja_existente and does not become another invoice. See
Batch issuance.