Skip to main content

Idempotency

In payment systems, retries due to network errors are unavoidable. Without idempotency, a retry can create duplicate charges or duplicate accounts. The API offers two complementary mechanisms:

Any POST, PUT, PATCH or DELETE can carry the Idempotency-Key header with a unique identifier chosen by the integrator (UUID, hash, or any string ≤ 255 characters).

Semantics

SituationResponse
First time with that keyExecutes normally. The key + the result are cached for 24 hours.
Same Idempotency-Key + same request body, within 24hReturns the same response without re-executing the operation.
Same Idempotency-Key + different body409 idempotency-key-reuse. Almost always indicates an integrator bug.
After 24hThe key is reused as new.

Scope

The idempotency cache is scoped by (apiKeyId, idempotencyKey). This means:

  • Two integrators can use the same key without colliding.
  • The same integrator cannot reuse the key across API key rotations (not a practical concern).

When mandatory

ResourceRecommendedMandatory
POST /v1/clientsYesNo (see §2, native upsert)
POST /v1/associatesYesNo (UNIQUE on taxId + customer)
POST /v1/receivable-accountsYesYes (only way to recover the ID if the response is lost before reading it)
POST /v1/receivablesYesYes (especially for bulk ERP flows)
POST /v1/webhooksYesNo
PATCH /v1/receivables/{id}/statusYesNo

Example

POST /v1/receivables
Authorization: Bearer eyJ...
Idempotency-Key: erp-fac-2026-05-15-00012345
Content-Type: application/json

{
"receivableAccountId": 4242,
"amount": 45000.00,
"currencyCode": "ARS",
"receivableType": "INVOICE",
"legalNumber": "0001-00012345",
"issueDate": "2026-05-15",
"dueDate": "2026-05-30"
}

If the response is lost due to a timeout, resend the same request with the same Idempotency-Key and you will receive the same response without duplicating the receivable.

Generate the Idempotency-Key deterministically from stable ERP identifiers:

erp-{company}-{resource}-{externalId}
erp-distribuidora-demo-fac-202605-00012345

This lets you retry from scratch, without duplication risk within the 24h window. For retries beyond 24h, protection depends on the resource (see §2): some resources are natively idempotent, others require handling 409 conflicts.

Key and body are inseparable

If you change the body of a retry (correct an amount, add a field), you must also change the Idempotency-Key. Reusing the same key with a different body returns 409 idempotency-key-reuse.

2. Behavior on business-key collisions

Beyond Idempotency-Key (which protects within 24h), some resources have business keys that also detect duplicates — but behavior varies per resource:

ResourceBusiness keyBehavior on collision
POST /v1/clients(documentType, documentNumber, branchExternalCode) per customerIdempotent: 200 OK with the existing client.
POST /v1/associatestaxId per customerIdempotent: 200 OK with the existing associate.
POST /v1/receivable-accounts(clientId, associateId, currencyCode) per customer409 receivable-account-already-exists with existingResourceId in the body. The integrator decides whether to reuse the existing one or cancel it.
POST /v1/receivableslegalNumber per customer (when provided)409 duplicated-legal-number if the legalNumber already exists for that customer. If you do not send legalNumber, there is no business key and the receivable is created without a duplicate check.
Suggested patterns per resource
  • Clients and associates: use the native idempotency. If your initial sync always posts the same data, you do not need to handle special errors — it is enough that documentType + documentNumber (clients) or taxId (associates) are stable in your ERP.
  • Receivable-accounts: explicitly handle 409 receivable-account-already-exists by recovering the existingResourceId from the response — that is the resource your ERP should keep using.
  • Receivables: combine a deterministic Idempotency-Key (covers retries within 24h) with a business key unique on your side (for example externalId with the invoice number) that lets you query before posting in bulk flows where a late retry could duplicate.