Idempotency: dubbele verzendingen voorkomen

Idempotency in de eConnect PSB API: hoe je dubbele verzendingen voorkomt met de X-EConnect-DocumentId header.

Bij het verzenden van facturen en andere documenten via een API is er altijd een risico op dubbele verzendingen. Een netwerk-timeout, een herstart van je applicatie of een onverwachte fout kan ertoe leiden dat je niet zeker weet of een document daadwerkelijk is verwerkt. Zonder bescherming zou je hetzelfde document opnieuw kunnen versturen, met dubbele facturen als gevolg.

De PSB API biedt een ingebouwd idempotency-mechanisme dat dit probleem oplost. Door een uniek documentId mee te sturen bij elke upload, herkent de PSB dubbele pogingen en voorkomt dat hetzelfde document twee keer wordt verwerkt.

Hoe het werkt

Het idempotency-mechanisme draait om de HTTP-header X-EConnect-DocumentId. Bij het verzenden van een document voeg je deze header toe met een unieke waarde die het document identificeert.

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>

De PSB verwerkt het document en slaat het documentId op. Als je hetzelfde verzoek opnieuw stuurt (bijvoorbeeld door een retry na een timeout), herkent de PSB dat het documentId al bestaat en retourneert een 409 Conflict-response in plaats van het document nogmaals te verwerken.

HTTP/1.1 409 Conflict

Die 409 is geen foutmelding in de traditionele zin. Het is een bevestiging dat het document al eerder succesvol is verwerkt. Je applicatie kan het verzoek veilig als afgerond markeren.

Vereisten voor het documentId

Het documentId dat je meestuurt in de X-EConnect-DocumentId-header moet aan een paar voorwaarden voldoen:

VereisteToelichtingMinimaal 6 tekensKortere waarden worden afgewezenGeen speciale tekensTekens als @ en _ zijn niet toegestaanUniek per documentElk document moet een eigen documentId krijgen

Let op: gebruik nooit het factuurnummer als documentId. Een factuurnummer kan hergebruikt worden bij een creditnota of een gecorrigeerde factuur, wat tot conflicten leidt. Gebruik in plaats daarvan een UUID/GUID die je per verzendpoging genereert.

Een UUID is de aanbevolen keuze. Die is gegarandeerd uniek en breed ondersteund in alle programmeertalen.

Goed:   550e8400-e29b-41d4-a716-446655440000  (UUID)
Goed:   DOC2026030800142                       (eigen reeks, mits uniek)
Fout:   INV-2026-001                           (factuurnummer, niet gebruiken)
Fout:   ab@cd                                  (speciale tekens)
Fout:   abc                                    (te kort)
Retry-logica implementeren

Idempotency wordt het meest waardevol in combinatie met retry-logica. Als een API-aanroep faalt door een netwerkfout of een 5xx-serverfout, wil je het verzoek opnieuw proberen zonder het risico op dubbele verwerking.

De aanbevolen aanpak werkt als volgt:

  1. Genereer een uniek documentId (UUID) voordat je het verzoek verstuurt.
  2. Stuur het document met de X-EConnect-DocumentId-header.
  3. Als je een 200 OK ontvangt: het document is verwerkt, klaar.
  4. Als je een 409 Conflict ontvangt: het document was al verwerkt bij een eerdere poging, klaar.
  5. Als je een 5xx-fout of een timeout ontvangt: wacht even en herhaal het verzoek met hetzelfde documentId.
  6. Als je een 4xx-fout ontvangt (behalve 409): er is een probleem met het verzoek zelf. Retrying heeft geen zin, de fout moet opgelost worden.

Tip: gebruik exponential backoff bij retries. Begin met een korte wachttijd (bijvoorbeeld 1 seconde) en verdubbel die bij elke volgende poging, tot een maximum van bijvoorbeeld 60 seconden. De PSB zelf hanteert een retry-beleid van maximaal 8 pogingen over circa 35 uur bij 5xx-fouten.

Welke endpoints ondersteunen idempotency?

De X-EConnect-DocumentId-header wordt ondersteund op alle endpoints waarmee je documenten uploadt naar de PSB. De belangrijkste zijn:

EndpointFunctiePOST /api/v1/{partyId}/salesInvoice/sendVerkoopfactuur verzendenPOST /api/v1/{partyId}/generic/sendGeneriek document verzenden (self-billing, despatch advice)POST /api/v1/{partyId}/purchaseOrder/sendOrder verzenden

Voor ontvangst-endpoints (download van documenten) is idempotency niet van toepassing: het ophalen van een document is van nature idempotent, want het wijzigt geen data. Let op: voor inbound Peppol-verkeer vindt geen duplicate-detectie plaats op basis van X-EConnect-DocumentId.

Scope en limieten

Idempotency met X-EConnect-DocumentId geldt voor outbound upload-endpoints. Voor Validate/Transform-endpoints en inbound Peppol-ontvangst geldt deze header niet als duplicate-mechanisme.

Daarnaast gelden per route verschillende limieten voor documenten en bijlagen:

Route / netwerkLimietToelichtingPeppol BIS (document + bijlagen)100 MBNetwerkgrens voor uitwisseling via PeppolSimpler Invoicing UBL 2.010 MBLimiet op SI-UBL 2.0 netwerkroutePOST /salesInvoice/send request24 MBWebserverlimiet per request inclusief overheadIDR upload15 MBLimiet voor IDR-documentinname

Embedded attachments worden uitsluitend ondersteund als inline base64 in het document (geen apart attachment-uploadendpoint).

Samenvatting

Idempotency is een klein mechanisme met een groot effect. Door consequent een X-EConnect-DocumentId mee te sturen bij elke documentupload, bescherm je jezelf tegen dubbele verzendingen. In combinatie met retry-logica en exponential backoff bouw je een robuuste integratie die bestand is tegen netwerkproblemen en tijdelijke serverfouten.

In het kort Stuur bij elke documentupload de header X-EConnect-DocumentId mee met een unieke UUID. Bij een retry retourneert de PSB 409 Conflict als het document al verwerkt is. Gebruik nooit het factuurnummer als documentId.

Veelgestelde vragen
Waarom mag ik het factuurnummer niet als documentId gebruiken?

Het factuurnummer is niet uniek genoeg over meerdere partijen en kan tot onverwachte conflicten leiden. Gebruik altijd een UUID (v4) als documentId. Dit garandeert uniekheid en voorkomt problemen bij retries.

Wat gebeurt er als ik geen X-EConnect-DocumentId meestuur?

De PSB genereert dan zelf een documentId. Het nadeel is dat je bij een netwerkfout niet kunt weten of het document al verwerkt is. Door zelf een documentId mee te sturen, kun je veilig retrien en ontvangt de PSB bij een dubbele upload een 409 Conflict.

Voor welke endpoints geldt idempotency?

Idempotency geldt voor alle write-endpoints die documenten uploaden, zoals het verzenden van facturen, orders en generieke documenten. Voor download-endpoints (ophalen van documenten) is idempotency niet van toepassing, omdat ophalen geen data wijzigt.

Bekijk de volledige API-documentatie