Docs

Idempotency

Retry a request safely, without creating a letter twice.

A connection can drop after CartaFlow received your request but before the response reached your system. In that case you do not know whether the letter was created. Retrying carelessly could send your customer two invoices.

The Idempotency-Key header solves this. Send a unique value per operation. If the request is repeated with the same key, the API returns the first response instead of creating another object.

curl -X POST "https://api.cartaflow.com.br/v1/letters" \
  -H "Authorization: Bearer $CARTAFLOW_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: invoice-2026-10-0042" \
  -d '{
    "to": { "name": "Destinatário Exemplo", "postal_code": "01001-000", "number": "128" },
    "document": { "type": "url", "url": "https://arquivos.exemplo.com.br/faturas/2026-10-0042.pdf" }
  }'

Where to use it

Every POST accepts Idempotency-Key: creating letters, uploads and verifications, calculating a price, canceling and checking codes. Always use it on POST /v1/letters and POST /v1/verifications, which charge your balance.

Requests sent as multipart/form-data, with a file, accept the key the same way: POST /v1/letters and POST /v1/letters/quote.

GET does not need a key: repeating a read changes nothing. Canceling twice is safe too: the second call returns the object already canceled, with no error.

The PUT of the file to an upload’s upload_url does not go to the API and takes no Idempotency-Key. If it fails, create a new upload and send the file to the new upload_url.

How it works

SituationResponse
First request with the keyProcessed as usual. The response is stored for 24 hours.
Same key, same endpoint, same bodyThe stored response, with the same status and body, plus the Idempotent-Replayed: true header. Nothing is created or charged again.
Same key with another body or on another endpoint409 with idempotency_key_reused. Nothing is created.
Same key while the first request is still running409 with idempotency_key_in_use. Wait a second and retry.
The first request ended with a 5xx errorThe response is not stored. Since nothing was created, the retry is processed as new.

2xx and 4xx responses are stored. A request that failed because of something in it, such as an invalid postal code, keeps failing with the same key. Fix the body and use a new key.

After 24 hours the key expires and can be used again as if it were new.

Choosing the key

The key must stand for the operation, not the attempt. Every attempt of the same operation uses the same key.

  • Use an identifier from your business, such as the invoice or order id: invoice-2026-10-0042. It is already unique and stays the same when your system restarts.
  • Or generate a UUID and store it before calling. Save the key with the record in your database first, then make the request. If the process crashes, the next attempt uses the same key.

Do not generate a new key on each attempt: that turns the protection off.

A key can be up to 255 characters long. An empty key or a longer one gets a 400 with invalid_idempotency_key.

Retrying safely

Retry requests that failed with a network error, a timeout, 429, 500 or 503, always with the same Idempotency-Key and with growing waits between attempts. See Errors for the details and a code sample.

On this page