API – 3. Idempotency (duplicaten voorkomen)
Wat is idempotency?
Idempotency betekent: dezelfde aanmaak-request meerdere keren sturen geeft maar één factuur. Als een client herprobeert (timeout, slechte verbinding, gebruiker klikt twee keer), dan hergebruikt hij dezelfde identificator en krijgt hij hetzelfde resultaat terug i.p.v. een tweede factuur.
Waarom heb je dit nodig?
HTTP is niet perfect: timeouts, netwerkblips, automatische retries (mobile/SDKs/CDN’s) komen vaak voor. Zonder idempotency kun je per ongeluk dubbele facturen aanmaken.
Hoe Facturalia dit ondersteunt
Je kunt één van onderstaande strategieën gebruiken (combineer gerust A + B):
A) external_id in de body (aanbevolen, eenvoudig)
Laat je integratie een eigen unieke referentie meesturen per factuur.
- Body:
{ "external_id": "client-7f85c2", "invoice": { "...": "..." }, "customer": { "...": "..." }, "lines": [ ... ] } - Gedrag:
- Eerste keer:
201 Created+ nieuwe factuur. - Zelfde
external_id+ identieke payload: we geven hetzelfde resultaat terug (Idempotency-Status: replayed). - Zelfde
external_id+ andere payload:409 Conflict(je probeert dezelfde factuur-id voor andere inhoud te gebruiken).
- Eerste keer:
Tip: kies iets stabiels (bv. je eigen intern factuur-/order-ID).
B) Idempotency-Key header (optioneel)
De client stuurt per aanmaakpoging een unieke sleutel mee en hergebruikt diezelfde sleutel bij retries van exact die poging.
- Header:
Idempotency-Key: 3e5c8bde-6d4a-4f5f-922f-6a9c1b1b46d1 - Gedrag: zoals bij
external_id: eerste keer opslaan, herhaalde calls met dezelfde key replayen; bij andere payload 409 Conflict. - Bewaartermijn: idempotency-keys worden voor een beperkte periode behouden (typisch 24–72 uur).
Postman tip: gebruik
{{$guid}}om snel een UUID te genereren.
Retry policy: bij timeout/herprobeer dezelfde key opnieuw sturen.
C) Uniek factuurnummer
Als je invoice.number zelf meestuurt, moet dit uniek zijn per account. Herhaal je dezelfde request met hetzelfde nummer, dan krijg je dezelfde factuur terug; een andere payload met hetzelfde nummer geeft 409 Conflict.
Je kan ook geen factuurnummer meegeven, dan genereert Facturalia zelf het eerstvolgende factuurnummer (aangeraden).
Antwoordspecificatie bij idempotency
- Eerste creatie:
201 Created
Headers:Location: https://www.facturalia.be/api/v1/invoices/{id} Idempotency-Status: stored # indien header/external_id gebruikt - Herspeelde creatie (retry):
201 Created(of200 OK) met dezelfde body
Headers:Idempotency-Status: replayed - Conflict (zelfde sleutel/identifier, andere payload):
409 Conflict{ "error": { "code": "idempotency_conflict", "message": "Identifier reeds gebruikt voor andere payload" } }
Voorbeelden
cURL – met external_id
curl -X POST https://www.facturalia.be/api/v1/invoices \
-H "Authorization: Bearer <JOUW_API_KEY>" \
-H "Content-Type: application/json" \
-d '{
"external_id": "order-12345",
"invoice": { "date": "2025-09-26", "due_days": 30, "language": "nl" },
"customer": { "name": "ABCD BV" },
"lines": [{ "product_code":"CONS-001","quantity":1,"unit_price":120,"vat_rate":21 }]
}'
cURL – met Idempotency-Key
curl -X POST https://www.facturalia.be/api/v1/invoices \
-H "Authorization: Bearer <JOUW_API_KEY>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: 3e5c8bde-6d4a-4f5f-922f-6a9c1b1b46d1" \
-d '{ "invoice": { "date": "2025-09-26", "due_days": 30, "language": "nl" }, "customer": { "name": "ABCD BV" }, "lines": [ ... ] }'
Wanneer gebruik ik wat?
- Snelste integratie: zet
external_idin de body en hergebruik die bij retries. - Meer controle per poging: gebruik de
Idempotency-Keyheader.
Welke je ook kiest: hergebruik altijd dezelfde identifier bij een retry. Zo voorkom je dubbele facturen en krijg je voorspelbare responses.
Bij
autosend=1wordt nooit opnieuw verzonden tijdens een idempotent replay. De API retourneert dezelfde factuur en dezelfde verzendstatus (bijv.queuedofsent). Als jeexternal_idgebruikt: hergebruik dezelfdeexternal_idbij retries van dezelfde creatiepoging om dubbele verzending te voorkomen.
