Idempotency in the eConnect PSB API: how to prevent duplicate submissions with the X-EConnect-DocumentId header.
When sending invoices and other documents through an API there is always a risk of duplicate submissions. A network timeout, a restart of your application or an unexpected error can leave you unsure whether a document was actually processed. Without protection you could end up sending the same document again, resulting in duplicate invoices.
The PSB API offers a built-in idempotency mechanism that solves this problem. By including a unique documentId with every upload, the PSB recognises duplicate attempts and prevents the same document from being processed twice.
The idempotency mechanism revolves around the HTTP header X-EConnect-DocumentId. When sending a document you add this header with a unique value that identifies the document.
POST /api/v1/{partyId}/salesInvoice/send HTTP/1.1
Host: psb.econnect.eu
Authorization: Bearer {token}
Content-Type: application/xml
X-EConnect-DocumentId: 550e8400-e29b-41d4-a716-446655440000
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
...
</Invoice>
The PSB processes the document and stores the documentId. If you send the same request again (for example as a retry after a timeout), the PSB recognises that the documentId already exists and returns a 409 Conflict response instead of processing the document a second time.
HTTP/1.1 409 Conflict
That 409 is not an error in the traditional sense. It is a confirmation that the document was already processed successfully. Your application can safely mark the request as completed.
The documentId you include in the X-EConnect-DocumentId header must meet a few requirements:
@ and _ are not allowedImportant: never use the invoice number as documentId. An invoice number can be reused for a credit note or a corrected invoice, leading to conflicts. Use a UUID/GUID instead, generated per submission attempt.
A UUID is the recommended choice. It is guaranteed to be unique and widely supported in all programming languages.
Good: 550e8400-e29b-41d4-a716-446655440000 (UUID)
Good: DOC2026030800142 (custom sequence, as long as it is unique)
Bad: INV-2026-001 (invoice number, do not use)
Bad: ab@cd (special characters)
Bad: abc (too short)
Idempotency becomes most valuable in combination with retry logic. If an API call fails due to a network error or a 5xx server error, you want to retry the request without the risk of duplicate processing.
The recommended approach works as follows:
X-EConnect-DocumentId header.200 OK: the document has been processed, done.409 Conflict: the document was already processed in a previous attempt, done.5xx error or a timeout: wait and retry the request with the same documentId.4xx error (other than 409): there is a problem with the request itself. Retrying is pointless; the error needs to be fixed.Tip: use exponential backoff for retries. Start with a short wait time (for example 1 second) and double it with each subsequent attempt, up to a maximum of, say, 60 seconds. The PSB itself uses a retry policy of up to 8 attempts over approximately 35 hours for 5xx errors.
The X-EConnect-DocumentId header is supported on all endpoints that upload documents to the PSB. The most important ones are:
POST /api/v1/{partyId}/salesInvoice/sendPOST /api/v1/{partyId}/generic/sendPOST /api/v1/{partyId}/purchaseOrder/sendFor receive endpoints (downloading documents) idempotency does not apply: retrieving a document is inherently idempotent, as it does not modify any data. Note that inbound Peppol traffic does not use X-EConnect-DocumentId for duplicate detection.
Idempotency via X-EConnect-DocumentId applies to outbound upload endpoints. It does not function as a duplicate mechanism for Validate/Transform endpoints or inbound Peppol reception.
In addition, different routes have different document and attachment limits:
POST /salesInvoice/send requestEmbedded attachments are supported as inline base64 only (no separate attachment upload endpoint).
Idempotency is a small mechanism with a big impact. By consistently including an X-EConnect-DocumentId with every document upload, you protect yourself against duplicate submissions. Combined with retry logic and exponential backoff, you build a robust integration that withstands network issues and temporary server errors.
In short
Include the X-EConnect-DocumentId header with a unique UUID for every document upload. On a retry the PSB returns 409 Conflict if the document has already been processed. Never use the invoice number as documentId.
View the full API documentation