# Externe API V1-documentatie

Zet facturen vanuit je eigen systemen om naar gevalideerde e-facturen: upload een PDF-, DOCX- of TXT-document – of gestructureerde ERP-data – en download de XRechnung-, ZUGFeRD-, EN 16931-, UBL- of CII-output zodra de validatie is geslaagd. Deze pagina is het volledige integratiecontract: toegangsmodel, endpoints, foutcatalogus en limieten.

> Vijf REST-endpoints zetten PDF-, DOCX- of TXT-facturen – of gestructureerde ERP-data – om naar gevalideerde XRechnung-, ZUGFeRD-, EN 16931-, UBL- en CII-e-facturen. Actieve Enterprise-abonnees maken sleutels direct aan; elke maand zijn 100 gedeelde E-mail/API-conversies inbegrepen, daarna gebruikt elke conversie € 0,50 aan prepaid credits.

## Overzicht

De API accepteert multipart-uploads, geeft JSON-antwoorden terug en gebruikt standaard HTTP-statuscodes met Bearer-authenticatie. Elke conversie verloopt asynchroon: verstuur het document, poll de taak, download het resultaat. Een bestand wordt pas geleverd nadat de validatie is geslaagd – ongevalideerde output bestaat niet.

Stuur een PDF-, DOCX- of TXT-factuurdocument of gestructureerde factuurdata naar een conversie-endpoint. Invoice-Converter start daarmee een asynchrone task voor extractie, validatie en artefactgeneratie. Het resultaat-endpoint levert alleen een bestand wanneer het gevraagde artefact gevalideerd, gecontroleerd en klaar voor uitvoer is; tijdens verwerking retourneert het 202 TASK_NOT_READY, bij blokkerende validatiefouten 422 VALIDATION_FAILED.

> **Status: Enterprise-toegang**: Basispad: /api/v1. Laatst gesynchroniseerd 2026-08-07.

## Belangrijkste mogelijkheden

- Upload-endpoints voor PDF-facturen en gestructureerde factuurdata
- AI-ondersteunde extractie van factuurgegevens
- Geautomatiseerde EN 16931- en KoSIT-validatie
- Uitvoerformaten voor XRechnung, ZUGFeRD, EN16931, UBL en CII
- Asynchrone verwerking met polling, kleine facturen rond 30 seconden en grotere facturen tot 1-2 minuten
- Idempotente writes voor veilige retries

## Start Enterprise API-toegang

Elke actieve Enterprise-abonnee kan productie-API-sleutels direct in het profiel maken.

1. Maak een account aan en start Enterprise voor € 50/maand of € 420/jaar via de prijzenpagina.
2. Gebruik de 100 gedeelde E-mail/API-conversies die elke maand zijn inbegrepen; extra conversies gebruiken prepaid credits van € 0,50 per stuk.
3. Maak een live API-sleutel aan in het API-toegangsgedeelte van je profiel.
4. Verstuur de eerste request met Bearer-token en een stabiele Idempotency-Key.

## Start Enterprise

- [Enterprise-abonnement en prijzen](/pricing)

## Snelstart

Drie API-aanroepen voltooien een conversie. Het convert-endpoint wordt aangeboden op /api/v1 en vereist authenticatie.

### POST /api/v1/invoices:convert (Live)
Factuurdocument converteren

### POST /api/v1/invoices:convert-structured (Live)
Gestructureerde data converteren

### GET /api/v1/tasks/{task_id} (Live)
Taskstatus pollen

## Snelstart met curl

Vervang $API_KEY door je live sleutel en $TASK_ID door de task_id uit het eerste antwoord. Dezelfde drie aanroepen werken voor elk uitvoerformaat.

### 1. Start de conversie
```
curl -X POST "https://www.invoice-converter.com/api/v1/invoices:convert" \
  -H "Authorization: Bearer $API_KEY" \
  -H "Idempotency-Key: inv-2026-0001" \
  -F "file=@invoice.pdf" \
  -F "format=XRECHNUNG"
```

### 2. Poll de taak tot completed
```
curl "https://www.invoice-converter.com/api/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"
```

### 3. Download het gevalideerde bestand
```
curl -o invoice.xml \
  "https://www.invoice-converter.com/api/v1/tasks/$TASK_ID/result?download=xml" \
  -H "Authorization: Bearer $API_KEY"
```

## Base-URL en API-sleutels

- Productie-base-URL: `https://www.invoice-converter.com/api/v1`.
- Live-sleutels gebruiken de productiehost en het prefix `icp_...`.
- Gebruik uw live sleutel voor onboarding en validatieruns voordat u productievolume verstuurt.
- Behandel sleutels als server-side secrets. Plaats ze niet in browser- of mobiele clients.

## Eerste succesvolle request

Gebruik deze volgorde als minimale happy path nadat je een API-sleutel hebt aangemaakt.

- Uploaden: `POST /api/v1/invoices:convert` met `Authorization`, `Idempotency-Key`, `file=@invoice.pdf` (of `.docx`/`.txt`) en `format=XRECHNUNG`.
- Poll met backoff: wacht na de `202` ongeveer `20 seconden` en roep daarna `GET /api/v1/tasks/{task_id}` aan met intervallen van 20s, 30s, 45s, 60s en 60s tot de status `completed` of `failed` is. Blijf binnen het statusquotum van `10/min` en `120/hour` en stop na ongeveer 16 minuten.
- Downloaden: `GET /api/v1/tasks/{task_id}/result?download=xml` en sla `X-Correlation-ID` op voor support-tracing.
- Voor ZUGFeRD PDF-output vraagt u `format=ZUGFERD` bij convert en `download=pdf` bij result; hybride PDF-output vereist een PDF-bronupload.
- Voor gestructureerde invoer roept u `POST /api/v1/invoices:convert-structured` aan met `pdf_file=@invoice.pdf`, `data_file=@invoice-data.json` en het doel-`format`.
- Stuur optioneel `client_reference` of `external_invoice_id` en `source_system` mee voor ERP-reconciliatie.
- Voor gesplitste ERP-exports van één factuur herhaalt u `data_file`; voor meerdere facturen start u één task per factuur met een eigen idempotency key.
- Sla `result_artifacts` uit de statusresponse op om te zien of XML/PDF-artefacten gevalideerd, gecachet of door afhankelijkheden nog niet beschikbaar zijn.

## Veelgebruikte payloadvoorbeelden

- `XRECHNUNG`: stuur `format=XRECHNUNG`.
- `ZUGFERD`: stuur `format=ZUGFERD`; gebruik `download=pdf` bij result voor de hybride PDF/A-3-output.
- `Gestructureerde invoer`: stuur `pdf_file` plus een of meer `data_file`-parts; geaccepteerde dataformaten zijn CSV, JSON, XML, XLSX en TXT, met elk ondersteund doelformaat. De data_file-parts moeten alle verplichte data bevatten; de PDF vult geen ontbrekende velden aan.
- `Meerdere facturen`: verstuur afzonderlijke convert-requests en volg elke geretourneerde `task_id`; herhaalde `data_file`-parts zijn alleen voor gesplitste exports van dezelfde factuur.
- `UBL`: stuur `format=UBL`; geaccepteerde profielen zijn `XRECHNUNG`, `PEPPOL` en `EN16931`, met `EN16931` als standaard.
- `CII`: stuur `format=CII`; geaccepteerde profielen zijn `XRECHNUNG`, `EN16931`, `ZUGFERD_EN16931` en `ZUGFERD_XRECHNUNG`, met `EN16931` als standaard.
- `format` x `profile` is een gesloten tabel: `XRECHNUNG` accepteert `[XRECHNUNG]` (standaard `XRECHNUNG`), `EN16931` accepteert `[EN16931]` (standaard `EN16931`), `UBL` accepteert `[XRECHNUNG, PEPPOL, EN16931]` (standaard `EN16931`), `CII` accepteert `[XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG]` (standaard `EN16931`) en `ZUGFERD` accepteert `[ZUGFERD_EN16931, ZUGFERD_XRECHNUNG]` (standaard `ZUGFERD_EN16931`). Profielen worden hoofdletterongevoelig vergeleken; `ZUGFERD`, `FACTURX`, `FACTUR-X` en `FACTUR_X` zijn aliassen voor `ZUGFERD_EN16931`, en `ZUGFERD-XRECHNUNG` is een alias voor `ZUGFERD_XRECHNUNG`.

## Vereiste headers

- Authorization: Bearer <api_key>

## Auth-regels

Elke actieve Enterprise-abonnee kan API-sleutels in het profiel maken en als Bearer-token gebruiken. Het gedeelde E-mail/API-tegoed omvat 100 conversies per maand; extra conversies gebruiken prepaid credits van € 0,50 per stuk.

- API-sleutels zijn tenant-gebonden live-credentials voor actieve Enterprise-abonnementen. Het huidige productieprefix is `icp_...`.
- Maak, roteer en trek API-sleutels in vanuit je profiel zolang Enterprise actief is. Kopieer nieuwe sleutels meteen, want plaintext sleutels worden maar één keer getoond.
- Een ontbrekende of ongeldige sleutel retourneert `401`.
- Aanroepen naar `/api/v1` krijgen automatisch een `X-Correlation-ID` wanneer die ontbreekt.
- Schrijfaanroepen vereisen `Idempotency-Key`; houd deze waarde stabiel over retries.
- Gebruik server-to-server-integratie vanuit uw backend. Browser-origin-toegang is in productie beperkt.

## Idempotency-contract

- Stuur bij elke schrijfaanroep een `Idempotency-Key`.
- Idempotency keys moeten overeenkomen met `[A-Za-z0-9._:-]+` en maximaal 200 tekens lang zijn.
- Als u uw eigen key opgeeft, retourneert dezelfde key + identieke payload de gecachte response.
- Dezelfde key + andere payload retourneert `409 IDEMPOTENCY_CONFLICT`; dat is niet herhaalbaar — gebruik een nieuwe key voor een nieuwe payload.
- Een tweede request met dezelfde key terwijl de eerste nog loopt, retourneert `409 IDEMPOTENCY_IN_PROGRESS`; probeer dezelfde key na een korte pauze opnieuw. Een vastgelopen in-progress claim wordt na `15 minuten` vrijgegeven.
- Is de oorspronkelijke task voorbij de bewaartermijn van 24 uur, dan retourneert een replay `409 IDEMPOTENCY_REPLAY_EXPIRED`; start een nieuwe conversie met een nieuwe key.
- Idempotency-records blijven `24 uur` bestaan, gelijk aan de taskbewaartermijn.

## Endpoint-referentie

Alle endpoints zijn beschikbaar onder /api/v1. Timeouts verschijnen als 504 en andere tijdelijke verbindingsfouten als 502; correlatie-ID’s helpen support om requests end-to-end te volgen.

### POST /api/v1/invoices:convert (Live)
Upload een PDF-, DOCX- of TXT-factuurdocument en start asynchrone conversie. Retourneert een task_id voor polling. ZUGFeRD/Factur-X hybride PDF-downloads vereisen een PDF-bronupload; DOCX/TXT-bronnen moeten XML-resultaten aanvragen. Verzoek: multipart/form-data; file (binary, verplicht) — PDF-, DOCX- of TXT-factuurbrondocument; oude DOC/RTF-, afbeeldings- en andere bestanden worden geweigerd; format (string, verplicht) — doeluitvoerformaat; zie de formaatmatrix hieronder; profile (string, optioneel, aanbevolen voor deterministische integraties) — expliciet complianceprofiel, hoofdletterongevoelig vergeleken. Elk formaat heeft een gesloten set toegestane waarden en één standaard: XRECHNUNG → [XRECHNUNG] (standaard XRECHNUNG); EN16931 → [EN16931] (standaard EN16931); UBL → [XRECHNUNG, PEPPOL, EN16931] (standaard EN16931); CII → [XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (standaard EN16931); ZUGFERD → [ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (standaard ZUGFERD_EN16931). ZUGFERD, FACTURX, FACTUR-X en FACTUR_X zijn aliassen voor ZUGFERD_EN16931; ZUGFERD-XRECHNUNG is een alias voor ZUGFERD_XRECHNUNG. Een waarde buiten de toegestane set geeft 422 OUTPUT_PROFILE_CONFLICT; een niet-herkende profielnaam geeft 422 INVALID_PROFILE met details.allowed_profiles; jurisdiction (string, optioneel) — expliciete ISO 3166-1 alpha-2-jurisdictiecontext voor validatie-/adviescontroles; overschrijft het profiel niet; transaction_scope (string, optioneel) — expliciete transactiecontext, zoals B2G; toegepast op de queued task; delivery_channel (string, optioneel) — een van PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF, UNKNOWN; toegepast op de queued task; client_reference of external_invoice_id (string, optioneel) — factuur-/jobreferentie van de klant, teruggegeven in geaccepteerde uploads en taskstatusresponses; source_system (string, optioneel) — upstream ERP- of facturatiesysteemlabel, teruggegeven in geaccepteerde uploads en taskstatusresponses; use_seller_master_data (boolean, optioneel) — zonder waarde geldt de standaard uit het tenantprofiel; false negeert opgeslagen verkopersstamgegevens voor deze request, true levert/gebruikt verkopersstamgegevens; seller_master_data (JSON-objectstring, optioneel) — verkopersstamgegevens die alleen worden gebruikt wanneer use_seller_master_data=true; ondersteunt bedrijfs-, adres-, belasting-, contact- en betaalvelden (payment_means_code 30/42/58, payment_iban, payment_bic, payment_account_name, payment_terms_note); elke profielwaarde vervangt de overeenkomstige geëxtraheerde waarde, ontbrekende profielvelden blijven ongewijzigd en verschillen geven niet-blokkerende waarschuwingen. Antwoord: 202 Accepted.

### POST /api/v1/invoices:convert-structured (Live)
Upload een drager-PDF met CSV-, JSON-, XML-, XLSX- of TXT-factuurdata en start asynchrone conversie vanuit gestructureerde data. De data_file-parts zijn de enige semantische bron; de PDF vult geen ontbrekende factuurvelden aan. Voor ZUGFeRD/Factur-X wordt de PDF gebruikt als drager-PDF, en bij XML-georiënteerde output wordt hij bewaard als ingediend PDF-artefact. Gebruik één conversierequest per factuur; herhaal data_file alleen voor gesplitste ERP-exports die dezelfde factuur beschrijven. Verzoek: multipart/form-data; pdf_file (binary, verplicht) — drager-PDF voor ZUGFeRD/Factur-X-insluiting en bewaring bij XML-georiënteerde output; data_file (binary, verplicht, herhaalbaar) — CSV-, JSON-, XML-, XLSX- of TXT-factuurdata als enige semantische bron; .xls, PDF’s en afbeeldingsbestanden worden als data_file geweigerd; herhaal voor gesplitste header-/regel-exports van dezelfde factuur; de aliassen data_files en data_files[] worden geaccepteerd; totale grootte gestructureerde data — maximaal 2 MB over alle data_file-parts; format (string, verplicht) — doeloutputformaat; ondersteunt XRECHNUNG, ZUGFERD, EN16931, UBL en CII; profile (string, optioneel, aanbevolen voor deterministische integraties) — expliciet complianceprofiel, hoofdletterongevoelig vergeleken. Elk formaat heeft een gesloten set toegestane waarden en één standaard: XRECHNUNG → [XRECHNUNG] (standaard XRECHNUNG); EN16931 → [EN16931] (standaard EN16931); UBL → [XRECHNUNG, PEPPOL, EN16931] (standaard EN16931); CII → [XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (standaard EN16931); ZUGFERD → [ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (standaard ZUGFERD_EN16931). Een waarde buiten de toegestane set geeft 422 OUTPUT_PROFILE_CONFLICT; een niet-herkende profielnaam geeft 422 INVALID_PROFILE met details.allowed_profiles; jurisdiction (string, optioneel) — expliciete ISO 3166-1 alpha-2-jurisdictiecontext voor validatie-/adviescontroles; overschrijft het profiel niet; transaction_scope (string, optioneel) — expliciete transactiecontext, zoals B2G; toegepast op de queued task; delivery_channel (string, optioneel) — een van PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF, UNKNOWN; toegepast op de queued task; client_reference of external_invoice_id (string, optioneel) — factuur-/jobreferentie van de klant, teruggegeven in geaccepteerde uploads en taskstatusresponses; source_system (string, optioneel) — upstream ERP- of facturatiesysteemlabel, teruggegeven in geaccepteerde uploads en taskstatusresponses; use_seller_master_data (boolean, optioneel) — zonder waarde geldt de standaard uit het tenantprofiel; false negeert opgeslagen verkopersstamgegevens voor deze request, true levert/gebruikt verkopersstamgegevens; seller_master_data (JSON-objectstring, optioneel) — verkopersstamgegevens die alleen worden gebruikt wanneer use_seller_master_data=true; ondersteunt bedrijfs-, adres-, belasting-, contact- en betaalvelden (payment_means_code 30/42/58, payment_iban, payment_bic, payment_account_name, payment_terms_note); elke profielwaarde vervangt de overeenkomstige geëxtraheerde waarde, ontbrekende profielvelden blijven ongewijzigd en verschillen geven niet-blokkerende waarschuwingen. Antwoord: 202 Accepted.

### GET /api/v1/tasks/{task_id} (Live)
Poll de huidige status van een conversietaak. Retourneert pending (geaccepteerd en in de wachtrij, nog niet gestart), processing, completed of failed. Rate limit 10/min en 120/hour; dat is de bindende beperking voor polling: wacht na de geaccepteerde 202 ongeveer 20 seconden voor de eerste aanroep, bouw daarna af (20s, 30s, 45s, 60s en vanaf dan 60s) en stop bij completed of failed. Voltooide taken bevatten `result_artifacts`-diagnostiek, zodat clients kunnen zien welke XML/PDF-artefacten beschikbaar, gecachet en met validatiebewijs onderbouwd zijn. Payloads van voltooide taken kunnen aanvullende `_processing_warnings`- en `_validation_warnings`-items met SOURCE_CONTEXT_*-regel-ID’s bevatten wanneer bronbewijs ontbrak, twijfelachtig of afgekapt was; behandel deze als beoordelingssignalen, niet als fouten. Bij failed bevat de response een error-veld met de reden. Verzoek: geen (GET); task_id (path, verplicht) — UUID die door het convert-endpoint is geretourneerd; include_validation_report_html (query, optioneel) — true of false (standaard false); bij true bevat de statusresponse het opgeschoonde HTML-validatierapport van het huidige strikte artefact wanneer dit beschikbaar is. Antwoord: 200 OK.

### GET /api/v1/tasks/{task_id}/result (Live)
Download het gegenereerde bestand (XML of PDF). De resultaantsyntaxis komt overeen met het oorspronkelijke taskformaat: XRECHNUNG/EN16931/UBL retourneren UBL XML, CII/ZUGFERD retourneren CII XML, en ZUGFERD + download=pdf retourneert een hybride PDF/A-3. Bij andere formaten kan download=pdf een gerenderde PDF leveren; op een voltooide task is download=xml het verwacht beschikbare artefact, geen gegarandeerd artefact. Herhaalde downloads kunnen uit gecachte artefacten worden bediend wanneer het validatiebewijs nog actueel is. Tijdens verwerking retourneert het endpoint een 202 met de standaard foutenvelope ({"code":"TASK_NOT_READY","message":"Strict conversion is still processing. No validated artifact is available yet.","correlation_id":"<uuid>"}); blokkerende validatiefouten retourneren 422 VALIDATION_FAILED, retrybare ontbrekende afhankelijkheden 503, definitieve conversiefouten 500 TASK_FAILED met de reden in details.code, en artefact-invariantfouten 500 INTERNAL_ARTIFACT_INVARIANT_FAILED, telkens zonder bestand. Geslaagde downloads bevatten X-Correlation-ID, Content-Disposition, Cache-Control: no-store, X-Artifact-Sha256, X-Validation-Proof-Id, X-Artifact-Proof-Id, X-Artifact-State, X-Validation-State, X-Proof-Status en X-Validator-Bundle-Id; X-Task-Id wordt op dit endpoint niet gezet. Rate limit 10/min en ongeveer 134/hour. Verzoek: geen (GET); task_id (path, verplicht) — UUID die door het convert-endpoint is geretourneerd; download (query, verplicht) — xml of pdf. Antwoord: 200 OK.

### GET /api/v1/tasks/{task_id}/validation-report (Live)
Download the validation report tied to the current validated result artifact. The report is available only after strict conversion has produced a cached artifact with current validation proof, and returns 404 when no report is bound to the delivered artifact. A 202 carries the standard TASK_NOT_READY error envelope, not a file body. Successful responses carry X-Correlation-ID, Content-Disposition, Cache-Control: no-store, X-Artifact-Sha256, X-Validation-Proof-Id, X-Artifact-Proof-Id, X-Artifact-State, X-Validation-State, X-Proof-Status, X-Validator-Bundle-Id, plus X-Task-Id, X-Validation-Report-Proof-Id, X-Validation-Report-Content-Type, X-Validation-Report-Format, X-Validation-Report-Source, and X-Report-Source-Artifact-Format. Those artifact-level diagnostics describe the validated result artifact the report covers, not the returned report bytes: X-Artifact-Sha256 is the SHA-256 of that source artifact and must not be used to checksum the downloaded report, while X-Validation-Report-Proof-Id identifies the proof that supplied the report payload. Rate limit 10/min and 120/hour. Verzoek: none (GET); task_id (path, required) — UUID returned by the convert endpoint; download (query, optional) — html or xml. Antwoord: 200 OK.

## Uitvoerformatenmatrix

| Formaat | Syntaxis | Versie / Profiel | Content-Type | Extensie |
| --- | --- | --- | --- | --- |
| XRECHNUNG | UBL 2.1 XML | XRechnung 3.0.2 | application/xml | .xml |
| ZUGFERD | CII XML (download=xml) / hybride PDF/A-3 (download=pdf) | ZUGFeRD 2.3.2 / Factur-X 1.07.2 | application/xml of application/pdf | .xml / .pdf |
| EN16931 | UBL 2.1 XML | EN 16931 | application/xml | .xml |
| UBL | UBL 2.1 XML | OASIS UBL 2.1 | application/xml | .xml |
| CII | UN/CEFACT CII XML | D16B | application/xml | .xml |

## Foutcontract

| Code | HTTP | Opnieuw te proberen | Notities |
| --- | --- | --- | --- |
| AUTHENTICATION_REQUIRED | 401 | Nee | Bearer-token ontbreekt/is leeg |
| INVALID_API_KEY | 401 | Nee | API-sleutel niet gevonden, ingetrokken of verlopen |
| API_NOT_ENABLED_FOR_TENANT | 403 | Nee | Key is valid but External API access is not enabled for the account; contact support instead of retrying |
| INSUFFICIENT_API_CREDITS | 402 | Nee | Het inbegrepen maandtegoed plus prepaid API-credits dekten de request niet. Twee details-vormen: prepaid (remaining, minimum_purchase 100) en inbegrepen tegoed (included_remaining, credit_remaining, shortfall, minimum_purchase 100). Verwerk op code en lees welke sleutels aanwezig zijn |
| IDEMPOTENCY_KEY_REQUIRED | 400 | Nee | Schrijfendpoint aangeroepen zonder Idempotency-Key |
| INVALID_IDEMPOTENCY_KEY | 400 | Nee | Idempotency key moet overeenkomen met [A-Za-z0-9._:-]+ en maximaal 200 tekens lang zijn |
| IDEMPOTENCY_CONFLICT | 409 | Nee | De key is al gebruikt met een andere payload, of de idempotente claim kon niet worden gestart; gebruik een nieuwe key voor een nieuwe payload |
| IDEMPOTENCY_IN_PROGRESS | 409 | Ja | De eerste request met deze key wordt nog verwerkt; probeer DEZELFDE key na een korte pauze opnieuw. Een vastgelopen in-progress claim wordt na 15 minuten vrijgegeven |
| IDEMPOTENCY_REPLAY_EXPIRED | 409 | Nee | The original task is past its 24-hour retention and cannot be recovered; start a new conversion with a new key |
| FORMAT_REQUIRED | 400 | Nee | Conversierequest mist het verplichte format |
| INVALID_FORMAT | 422 | Nee | Niet-ondersteund conversieformaat |
| CLIENT_REFERENCE_CONFLICT | 400 | Nee | client_reference en external_invoice_id verschillen |
| INVALID_CLIENT_METADATA | 400 | Nee | client_reference, external_invoice_id of source_system overschrijdt de lengtelimiet of bevat besturingstekens |
| INVALID_SELLER_MASTER_DATA | 400 | Nee | use_seller_master_data of seller_master_data is niet parseerbaar of doorstaat de veldvalidatie niet |
| METHOD_NOT_ALLOWED | 405 | Nee | Conversiepaden accepteren alleen POST en taskpaden alleen GET; de response bevat Allow: POST, OPTIONS (conversie) of Allow: GET, OPTIONS (task) |
| DOWNLOAD_FORMAT_REQUIRED | 400 | Nee | Task-resultrequest mist de verplichte download-query |
| INVALID_DOWNLOAD_FORMAT | 400 | Nee | Task-result download-query moet xml of pdf zijn |
| AUTH_SERVICE_UNAVAILABLE | 503 | Ja | Auth-backend niet beschikbaar |
| RATE_LIMIT_SERVICE_UNAVAILABLE | 503 | Ja | De rate-limit-service was niet bereikbaar; probeer opnieuw met backoff |
| PLAN_TIER_CHECK_FAILED | 503 | Ja | Plan/API access could not be verified right now; retry with backoff |
| API_CREDIT_SERVICE_UNAVAILABLE | 503 | Ja | Verificatie van prepaid API-credits of kanaalquotum is tijdelijk niet beschikbaar bij conversie-uploads |
| RATE_LIMITED | 429 | Ja | Respecteer Retry-After. Retry-After, X-RateLimit-Limit-Minute en X-RateLimit-Limit-Hour worden alleen op 429-responses teruggegeven; de body bevat details.minute_count, details.hour_count, details.limit_minute en details.limit_hour |
| BAD_REQUEST | 400 | Nee | Ongeldige JSON of ongeldig UUID-padparameter |
| INVALID_QUERY_PARAMETER | 400 | Nee | include_validation_report_html moet true of false zijn |
| PAYLOAD_TOO_LARGE | 413 | Nee | Uploadgrootte overschrijdt limiet |
| INVALID_UPLOAD | 400 | Nee | Upload lezen/parsen mislukt |
| UPLOAD_FAILED | 422 | Nee | Een optioneel contextveld (jurisdiction, transaction_scope, delivery_channel) bevatte een niet-herkende waarde; de toegestane waarden staan in de message |
| INVALID_PROFILE | 422 | Nee | The value is not a recognized profile name; details.allowed_profiles lists the accepted set |
| TASK_NOT_READY | 202 | Ja | Poll opnieuw voor asynchrone voltooiing |
| TASK_NOT_FOUND | 404 | Nee | De task is onbekend, hoort niet bij de tenant of is voorbij de bewaartermijn van 24 uur na het bereiken van een terminale status |
| VALIDATION_FAILED | 422 | Nee | Blokkerende validatieproblemen blijven bestaan, waaronder strikte ZUGFeRD-voorwaardefouten en onopgeloste blocking_source_conflict-items; corrigeer de factuurdata voordat u opnieuw probeert |
| AUTHORITATIVE_VALIDATION_UNAVAILABLE | 503 | Ja | Autoritatieve validatie, bewijsopslag of afhankelijkheid voor hybride generatie is niet beschikbaar; probeer later opnieuw |
| TASK_STATUS_FAILED | 4xx/5xx | Voorwaardelijk | Opnieuw proberen bij tijdelijke serviceconditie |
| TASK_RESULT_FAILED | 4xx/5xx | Voorwaardelijk | Opnieuw proberen bij tijdelijke serviceconditie |
| TASK_FAILED | 500 | Voorwaardelijk | Conversiefout op het resultaat-endpoint. Lees details.code en details.retryable: MULTIPLE_INVOICES_IN_DOCUMENT, NO_INVOICE_DETECTED, INSUFFICIENT_INVOICE_SIGNAL, SCHEMA_PARSE_FAILED en ARTIFACT_PARITY_FAILED zijn definitief; PROVIDER_ERROR en elke niet-herkende details.code volgen details.retryable, en details.retryable=true betekent een NIEUWE conversie met een nieuwe Idempotency-Key in plaats van opnieuw pollen van dezelfde task. De mislukte conversie verbruikt geen facturatie-eenheid |
| MULTIPLE_INVOICES_IN_DOCUMENT | 500 (details code) | Nee | Terminal: the source document contains more than one invoice, corroborated by distinct invoice identifiers or a reported invoice count. details.retryable and details.can_review are false. Split the PDF into one file per invoice and start a separate conversion for each invoice |
| NO_INVOICE_DETECTED | 500 (details code) | Nee | Terminal: the document does not look like an invoice. Route to human handling |
| INSUFFICIENT_INVOICE_SIGNAL | 500 (details code) | Nee | Terminal: not enough invoice data for reliable extraction. Supply a better source document or use structured conversion |
| SCHEMA_PARSE_FAILED | 500 (details code) | Nee | Terminal for that input: extraction returned a payload that failed schema parsing. Start a new conversion; escalate if it repeats on the same document |
| PROVIDER_ERROR | 500 (details code) | Voorwaardelijk | Extraction-provider failure; details.retryable is authoritative. When details.classification is provider_context_too_large, use a smaller source document |
| XML_GENERATION_FAILED | 500 | Ja | Tijdelijke XML-generatiefout of timeout |
| PDF_GENERATION_FAILED | 500 | Ja | Tijdelijke PDF-generatiefout of timeout |
| ARTIFACT_GENERATION_RERUN_REQUIRED | 503 | Nee | Strikte artifactgeneratie is mislukt na server-side retries; start een nieuwe conversie nadat de afhankelijkheid is hersteld |
| EXTRACTION_INCOMPLETE_GROUP_FAILURE | 503 | Nee | Extraction finished with one or more failed field groups. The same task will not recover: start a NEW conversion. details carries type "dependency", dependency "parallel_extraction", stage "extraction", retryable true, same_task_retryable false, recovery "start_new_conversion", and failed_groups |
| ARTIFACT_GENERATION_FAILED | 503 (details code) | Nee | Vastgelegd op mislukte tasks voor herhaalbare strikte uitgiftefouten; resultdownloads geven 503 ARTIFACT_GENERATION_RERUN_REQUIRED met deze code in details |
| ARTIFACT_PARITY_FAILED | 500 (details code) | Nee | Gemeld in de details van 500 TASK_FAILED wanneer het strikte artefact niet overeenkomt met de definitieve gecontroleerde factuurdata; escaleer met de correlatie-ID |
| INTERNAL_ARTIFACT_INVARIANT_FAILED | 500 | Nee | Voltooide strikte task heeft geen veilig opgeslagen artefact voor de gevraagde download; escaleer met de correlatie-ID |
| PROFILE_MISMATCH | 422 | Nee | Het gevraagde profiel komt bij de resultdownload niet overeen met de CustomizationID van het opgeslagen resultaat |
| ZUGFERD_SOURCE_PDF_INCOMPATIBLE | 422 | Nee | Strikte hybride PDF-generatie kan XML niet in de geüploade bron-PDF insluiten |
| ZUGFERD_SOURCE_PDF_REQUIRED | 422 | Nee | download=pdf voor ZUGFERD vereist een PDF-bronupload (DOCX/TXT-bronnen kunnen de hybride PDF niet dragen); vraag in plaats daarvan download=xml aan |
| VALIDATION_REPORT_NOT_FOUND | 404 | Nee | Er is geen validatierapport gekoppeld aan het bewijs van het huidige geleverde artefact |
| VALIDATION_REPORT_FAILED | 4xx/5xx | Voorwaardelijk | Ophalen van het validatierapport is mislukt; probeer alleen opnieuw bij tijdelijke 5xx-gevallen |
| OUTPUT_PROFILE_REQUIRED | 422 | Nee | Een generiek uitvoercontract vereist een expliciet profiel wanneer geen eenduidige standaard kan worden bepaald |
| OUTPUT_PROFILE_CONFLICT | 422 | Nee | Profiel is in strijd met het gekozen uitvoerformaat of de expliciete variant |
| PROXY_ERROR | 502/504 | Ja | Transportfout in plaats van een conversieresultaat: proxy-/upstreamfout (504 bij timeout). Probeer opnieuw met backoff en dezelfde idempotency key |

## Veelvoorkomende fouten en wat te doen

- Opnieuw proberen met backoff: `429`, `502`, `504`, `503` met een herhaalbare code, en tijdelijke `500`-fouten die geen `TASK_FAILED` of `INTERNAL_ARTIFACT_INVARIANT_FAILED` zijn. `500 TASK_FAILED` is alleen herhaalbaar wanneer `details.retryable` `true` is, en dan uitsluitend als nieuwe conversie.
- Niet opnieuw proberen: `400`, `401`, `402`, `403`, `404`, `405`, `413`, `422`, `409 IDEMPOTENCY_CONFLICT`, `409 IDEMPOTENCY_REPLAY_EXPIRED`, `500 TASK_FAILED` wanneer `details.retryable` niet `true` is, en `500 INTERNAL_ARTIFACT_INVARIANT_FAILED`.
- Request of brondata corrigeren: `400`, `413`, `422`.
- Toegang of credentials corrigeren: `401 INVALID_API_KEY`. `403 API_NOT_ENABLED_FOR_TENANT` betekent dat de sleutel geldig is maar External API-toegang niet is ingeschakeld voor het account — neem contact op met support.
- Controleer het inbegrepen maandtegoed of koop een prepaid API-creditpakket: `402 INSUFFICIENT_API_CREDITS`. Lees de `details`-sleutels die aanwezig zijn (`remaining` bij prepaid accounts, of `included_remaining`/`credit_remaining`/`shortfall` wanneer een inbegrepen tegoed geldt).
- Later blijven pollen: `202 TASK_NOT_READY`.
- Lees bij `500 TASK_FAILED` de `details.code` en `details.retryable`. `MULTIPLE_INVOICES_IN_DOCUMENT`, `NO_INVOICE_DETECTED`, `INSUFFICIENT_INVOICE_SIGNAL`, `SCHEMA_PARSE_FAILED` en `ARTIFACT_PARITY_FAILED` zijn definitief; `PROVIDER_ERROR` en elke niet-herkende code volgen `details.retryable`, en `true` betekent een NIEUWE conversie in plaats van opnieuw pollen van dezelfde task. Een mislukte conversie verbruikt geen facturatie-eenheid.
- Bij `422 VALIDATION_FAILED` toont u het teruggegeven veld, de regel-ID en de voorgestelde oplossing aan een menselijke controleur voordat u opnieuw probeert met gecorrigeerde factuurdata.
- Bij `503 AUTHORITATIVE_VALIDATION_UNAVAILABLE` haalt u dezelfde task later opnieuw op; er is geen ongecontroleerd artefact geleverd. Start bij `503 ARTIFACT_GENERATION_RERUN_REQUIRED` en `503 EXTRACTION_INCOMPLETE_GROUP_FAILURE` in plaats daarvan een nieuwe conversie.
- `502` en `504 PROXY_ERROR` zijn transportfouten en geen conversieresultaten; probeer opnieuw met backoff en dezelfde idempotency key.

## Rate- en payloadlimieten

Rate limits per API-sleutel en payloadgroottebeperkingen gelden voor alle API-aanroepen. Geweigerde conversies verbruiken geen prepaid API-credits; rate limits worden apart per endpoint bepaald.

- Endpointgebonden limieten zijn kostengewogen, en elk endpoint heeft een eigen bucket zodat polling de conversiedoorvoer niet kan uithongeren. Standaarden per API-sleutel: `POST /invoices:convert` en `POST /invoices:convert-structured` `30/min` en `500/hour`; `GET /tasks/{task_id}` `10/min` en `120/hour`; `GET /tasks/{task_id}/result` `10/min` en ongeveer `134/hour`; `GET /tasks/{task_id}/validation-report` `10/min` en `120/hour`.
- Quotaheaders worden alleen op `429 RATE_LIMITED`-responses teruggegeven. Geslaagde responses bevatten geen quotaheaders; behandel de bovenstaande tabel daarom als het geldende contract en lees de exacte effectieve waarden uit een `429`.
- De statusbucket is de bindende beperking voor polling: wacht na de geaccepteerde `202` ongeveer `20 seconden` voor de eerste statusaanroep, bouw daarna af (20s, 30s, 45s, 60s en vanaf dan 60s) en stop bij `completed` of `failed`. Poll niet elke 10 seconden; één zo bevraagde task verbruikt zijn hele uurbudget in 20 minuten.
- Maximale uploadgrootte voor brondocumenten: `20 MB` voor PDF-, DOCX- of TXT-bestanden.
- Maximale uploadgrootte gestructureerde data: `2 MB` totaal over alle `data_file`-parts.
- Maximale JSON-payloadgrootte: `1 MB`
- `429`-responses bevatten `Retry-After`, `X-RateLimit-Limit-Minute` en `X-RateLimit-Limit-Hour`, plus `details.minute_count`, `details.hour_count`, `details.limit_minute` en `details.limit_hour`.

## Retry-richtlijn

- Gebruik exponentiële backoff met jitter en hergebruik bij elke retry van een schrijfrequest dezelfde `Idempotency-Key`.
- Beslis op de machineleesbare `code` — en bij `500 TASK_FAILED` op `details.code` plus `details.retryable` — nooit op de HTTP-status alleen. Een `500` is in deze API niet automatisch herhaalbaar.
- Veilig te herhalen: `429`, `502`, `504`, `503` met een herhaalbare code, tijdelijke `500`-fouten die GEEN `TASK_FAILED` of `INTERNAL_ARTIFACT_INVARIANT_FAILED` zijn, en `500 TASK_FAILED` wanneer `details.retryable` `true` is (tijdelijke providerfouten: rate limiting, timeout, transportfout) — herhaal dat geval als een NIEUWE conversie met een nieuwe `Idempotency-Key`, niet door dezelfde task opnieuw te pollen.
- Nooit herhalen: `400`, `401`, `402`, `403`, `404`, `405`, `413`, `422`, `409 IDEMPOTENCY_CONFLICT`, `409 IDEMPOTENCY_REPLAY_EXPIRED`, `500 TASK_FAILED` wanneer `details.retryable` niet `true` is, en `500 INTERNAL_ARTIFACT_INVARIANT_FAILED`. Een definitief mislukte conversie verbruikt geen facturatie-eenheid.
- `409 IDEMPOTENCY_IN_PROGRESS` is met DEZELFDE key na een korte pauze herhaalbaar; een vastgelopen in-progress claim wordt na 15 minuten vrijgegeven.
- `503 ARTIFACT_GENERATION_RERUN_REQUIRED` en `503 EXTRACTION_INCOMPLETE_GROUP_FAILURE` vragen om een NIEUWE conversie in plaats van een retry van dezelfde task.

## Taaklevenscyclus en bewaartermijn

- Een task en de opgeslagen artefacten worden `24 uur` bewaard nadat de task een terminale status (`completed` of `failed`) bereikt en worden daarna verwijderd. Na verwijdering geven status-, result- en validatierapportrequests `404 TASK_NOT_FOUND`.
- Er is geen vaste conversietimeout. Een task mislukt na een stilstandvenster van `5 minuten` zonder fase- of voortgangsupdate, of zodra de totale verwerking de absolute bovengrens van `15 minuten` overschrijdt.
- Zet uw client-side timeout op ongeveer `16 minuten` vanaf de geaccepteerde `202`. De meeste conversies zijn ruim binnen twee minuten klaar.
- Idempotency-records blijven `24 uur` bestaan, gelijk aan de taskbewaartermijn. Een vastgelopen request wordt na `15 minuten` vrijgegeven.
- Rate-limit-tellers resetten op een rollend venster.

## Supportmodel

- Support tijdens kantooruren op basis van commercieel redelijke inspanningen.
- Geen formele SLA, servicecredit of reactietijdverplichting tenzij afgesproken in een order form.

## Wijzigingslogboek

Meest recente extern zichtbare API-wijzigingen.

### 2026-08-07
Documentation release 1.13.0: Enterprise is available through direct checkout for EUR 50 per month or EUR 420 per year. Every active Enterprise subscription includes 100 conversion units per month shared by Email Import and External API V1; additional units use prepaid credits at EUR 0.50 each. Email Import and External API V1 no longer require manual account approval. Email Import still requires profile enablement and a verified sender.

### 2026-07-29
Documentation release 1.12.0. No runtime behavior changed on this date; these entries document behavior that was already live. MULTIPLE_INVOICES_IN_DOCUMENT is now published in the error catalog. It is returned as 500 TASK_FAILED with details.code=MULTIPLE_INVOICES_IN_DOCUMENT, details.retryable=false, and details.can_review=false. It is terminal: split the source into one document per invoice. The failed attempt does not consume a billing unit. Retry guidance corrected: a 500 is not automatically retryable. Branch on code, and on details.code plus details.retryable for 500 TASK_FAILED, instead of on the HTTP status alone. Treat 500 TASK_FAILED as terminal unless details.retryable is true (transient provider failures such as rate limiting, timeouts, and transport errors), in which case start a new conversion with a new Idempotency-Key rather than re-polling the same task. Never retry 500 INTERNAL_ARTIFACT_INVARIANT_FAILED. Billing is documented as included-allowance-then-credits, so 402 INSUFFICIENT_API_CREDITS has two details shapes: prepaid (remaining, minimum_purchase) and included allowance (included_remaining, credit_remaining, shortfall, minimum_purchase). Newly documented runtime error codes that were already being returned: 403 API_NOT_ENABLED_FOR_TENANT, 409 IDEMPOTENCY_IN_PROGRESS, 409 IDEMPOTENCY_REPLAY_EXPIRED, 422 INVALID_PROFILE, 422 UPLOAD_FAILED, 400 INVALID_IDEMPOTENCY_KEY, 503 PLAN_TIER_CHECK_FAILED, 503 RATE_LIMIT_SERVICE_UNAVAILABLE, and 503 EXTRACTION_INCOMPLETE_GROUP_FAILURE. The 409 class is split by retry semantics: IDEMPOTENCY_IN_PROGRESS is retryable with the same key after a short delay, while IDEMPOTENCY_CONFLICT and IDEMPOTENCY_REPLAY_EXPIRED require a new key. Validation-report header passthrough fixed, and X-Validation-Report-Format, X-Validation-Report-Source, and X-Report-Source-Artifact-Format are now published. On the validation-report endpoint, X-Artifact-Sha256 is the SHA-256 of the result artifact the report validates, not of the returned report bytes; X-Validation-Report-Proof-Id identifies the proof that supplied the report payload. Added retention and lifecycle statements: 24-hour task/artifact retention after a terminal state, 24-hour idempotency records, a 15-minute in-progress reclaim, a 5-minute stall window, a 15-minute hard cap, and a recommended ~16-minute client timeout. Rate limits and polling guidance replaced with per-endpoint numbers, including the previously missing validation-report bucket. Quota headers are returned on 429 responses only, and the former "poll every 10-15 seconds" advice is replaced with a first-poll delay plus backoff. Published a closed format x profile compatibility table with the default profile for each format, and corrected download=xml on a completed task from "always available" to expected-available. Corrected 405 METHOD_NOT_ALLOWED to return Allow: POST, OPTIONS on conversion paths and Allow: GET, OPTIONS on task paths, and corrected 422 PROFILE_MISMATCH: there is no profile query parameter, and the fix is to start a new conversion with an aligned profile.

### 2026-07-28
External API conversions now run the same document-scope gate as the interactive product, including on forced extraction modes that previously skipped it. A source document whose extraction reports multiple invoices, corroborated by two or more distinct invoice identifiers or by an invoice count with no identifiers, now fails terminally with MULTIPLE_INVOICES_IN_DOCUMENT. The failure is not retryable: split the source into one document per invoice and submit each separately. An uncorroborated multiple_invoices verdict no longer fails the conversion. On strict API issuance it returns 422 VALIDATION_FAILED with a blocking_source_conflict issue entry, which covers duplicate renditions such as an original plus its copy, a reprint, or a second-language rendition.

### 2026-07-26
When seller master data is enabled, every supplied profile value replaces the corresponding extracted seller or payment value. Fields absent from the profile remain unchanged. Source differences are non-blocking review warnings.

### 2026-07-25
Superseded by the 2026-07-26 entry above. Seller master data filled missing seller and payment fields only; explicit invoice values remained unchanged, and material profile/source conflicts blocked strict issuance until review. Since 2026-07-26 every supplied profile value replaces the corresponding extracted value instead.

### 2026-07-10
Documentatie-inhaalslag; geen wijziging in runtimegedrag. De foutcatalogus documenteert nu eerder ongedocumenteerde runtime-foutcodes, waaronder API_CREDIT_SERVICE_UNAVAILABLE, TASK_NOT_FOUND, INVALID_CLIENT_METADATA, INVALID_SELLER_MASTER_DATA, PROFILE_MISMATCH, ZUGFERD_SOURCE_PDF_REQUIRED, VALIDATION_REPORT_NOT_FOUND, VALIDATION_REPORT_FAILED, INVALID_QUERY_PARAMETER en METHOD_NOT_ALLOWED. Clients die foutresponses via het machineleesbare code-veld verwerken, hoeven niets te wijzigen; clients die op een vaste lijst codes schakelen, moeten de nieuw gedocumenteerde waarden toevoegen. Changelogdatums gecorrigeerd: ondersteuning voor DOCX/TXT-bronnen verscheen op 2026-06-30, niet op 2026-07-06.

### 2026-07-06
Payloads van voltooide taken kunnen aanvullende _processing_warnings- en _validation_warnings-items met SOURCE_CONTEXT_*-regel-ID’s bevatten wanneer bronbewijs vóór extractie ontbrak, twijfelachtig of afgekapt was. Behandel SOURCE_CONTEXT_*-items als beoordelingssignalen voor klantzijdige uitzonderingsafhandeling; strikte artefactdownloads blijven onderworpen aan validatiebewijs en artefactcontroles.

### 2026-07-03
Strikte ZUGFeRD-voorwaardefouten (ontbrekende verplichte velden voor hybride generatie) falen nu als 422 VALIDATION_FAILED met de blokkerende regel-ID’s in plaats van een herhaalbare 503; leid deze naar een datacorrectieflow, niet naar een retry-lus. Voor XML-only formaten (XRECHNUNG, EN16931, UBL, CII) is de PDF-weergave nu een best-effort gemaksartefact: download=xml blijft leidend en beschikbaar op voltooide taken, terwijl download=pdf onbeschikbaar kan zijn als de weergave na de XML-uitgifte mislukte. Conversies met onopgeloste blokkerende bronconflicten falen nu als 422 VALIDATION_FAILED met blocking_source_conflict-items in plaats van een artefact uit te geven.

### 2026-06-30
POST /api/v1/invoices:convert accepteert nu PDF-, DOCX- en TXT-factuurbrondocumenten in het file-veld. Oude DOC-, RTF-, afbeeldings- en andere niet-ondersteunde bronbestanden worden geweigerd voordat de conversie start. ZUGFeRD/Factur-X hybride PDF-downloads vereisen nog steeds een PDF-bronupload; gebruik XML-downloads voor DOCX/TXT-bronconversies. Optionele include_validation_report_html=true toegevoegd op GET /api/v1/tasks/{task_id} om het opgeschoonde HTML-validatierapport inline te leveren wanneer beschikbaar. Conversie-uploads accepteren nu op beide endpoints optionele use_seller_master_data- en seller_master_data-velden, zodat goedgekeurde tenants opgeslagen of request-gebonden verkopersstamgegevens kunnen inschakelen.

### 2026-06-29
GET /api/v1/tasks/{task_id}/validation-report?download=html|xml toegevoegd om het validatierapport op te halen dat aan het huidige strikte resultaatartefactbewijs is gekoppeld. Validatierapportresponses tonen task-ID, artefact-SHA-256, validatiebewijs-ID, rapportbewijs-ID, rapportcontenttype en correlatie-ID-headers.

### 2026-06-10
Invoice data you submit is now the source of truth during hybrid ZUGFeRD generation; the server no longer overrides submitted quantities or totals with values recovered from the uploaded PDF. Deterministic cleanup and tax normalization still apply. Long-running conversions are no longer failed at a fixed 5-minute processing timeout. Tasks now fail only when they stop making progress for the stall window or exceed the absolute 15-minute hard cap, and extraction retries are bounded by a total wall-clock budget.

### 2026-06-09
Clarified that usage-tracking persistence failures are fail-open for response delivery: ready validated artifact responses are not denied, no extra prepaid API credit is consumed, and failed usage events are queued internally for reconciliation.

### 2026-06-02
External API-toegang is nu gedocumenteerd als goedgekeurde toegang in plaats van onbeperkte sleutelaanmaak. Verduidelijkt dat er geen formele SLA, servicecredit of contractuele boete geldt tenzij afgesproken in een order form. format is nu verplicht op beide conversie-endpoints; ontbrekende waarden retourneren 400 FORMAT_REQUIRED en niet-ondersteunde waarden 422 INVALID_FORMAT. download is nu verplicht op task-resultrequests; ontbrekende waarden retourneren 400 DOWNLOAD_FORMAT_REQUIRED en niet-ondersteunde waarden 400 INVALID_DOWNLOAD_FORMAT. Conversie-uploads accepteren nu client_reference/external_invoice_id en source_system voor klantzijdige reconciliatie. Geaccepteerde conversie- en taskstatusresponses bevatten nu status_url, primary_result_format, primary_result_url en meegestuurde reconciliatievelden.

### 2026-06-01
Gestructureerde conversie accepteert nu alle publieke outputformaten: XRECHNUNG, ZUGFeRD, EN16931, UBL en CII. Gestructureerde conversie accepteert nu herhaalbare data_file-onderdelen plus de aliassen data_files en data_files[] voor gesplitste ERP-exports. Gestructureerde multi-file bundles moeten precies één factuur beschrijven en falen vroeg bij conflicterende of ontbrekende bundle-factuur-ID’s. Verduidelijkt dat meerdere factuurdocumenten als afzonderlijke conversietasks moeten worden ingestuurd, elk met een eigen idempotency key.

### 2026-05-27
POST /api/v1/invoices:convert-structured toegevoegd voor conversie vanuit gestructureerde data met drager-PDF en CSV/JSON/XML/XLSX/TXT over ondersteunde outputformaten. Gedocumenteerd dat gestructureerde data op dit endpoint de enige semantische bron is; de PDF wordt gebruikt voor hybride insluiting. OpenAPI- en Postman-artefacten bijgewerkt voor gestructureerde conversie.

### 2026-05-26
Strict XML and hybrid ZUGFeRD PDF result artifacts now carry internal artifact parity metadata; public clients should use task-status result_artifacts for artifact readiness and validation-state diagnostics. Updated the documented production base URL to https://www.invoice-converter.com/api/v1.

### 2026-05-19
Task-result downloads are now strict retrieval-only: no XML/PDF generation, AI call, repair, or validation runs on GET /api/v1/tasks/{task_id}/result. Strict tasks complete only after a validated artifact is stored; completed tasks without a current proof fail closed with 500 INTERNAL_ARTIFACT_INVARIANT_FAILED. External API conversions are permanently pinned to strict issuance: no draft output, no warning override, and artifact validation always required. Conversions run on a dedicated processing tier chosen by the service. Added additive result_artifacts diagnostics to the task status response, and documented the canonical delivery_channel values PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF, and UNKNOWN. Documented 422 ZUGFERD_SOURCE_PDF_INCOMPATIBLE, and clarified that missing XRechnung/Peppol target metadata such as BT-10, BT-49, and BG-16 is a validation correction flow rather than a transport retry.

### 2026-05-08
Prepaid External API-credits toegevoegd voor niet-Enterprise-tenants. 402 INSUFFICIENT_API_CREDITS gedocumenteerd voor goedgekeurde tenants zonder Enterprise-facturering per order form of prepaid credits. Bevestigd dat idempotente replays geen extra API-credits verbruiken. Verduidelijkt dat External API V1 modelrouting server-side beheert, terwijl profiel- en leveringscontext door de aanroeper worden bepaald.

### 2026-03-28
Task status responses expose artifact readiness diagnostics for XML/PDF result availability. Documented that strict result downloads only return files after server-side artifact gates pass.

### 2026-03-26
Successful task-result downloads are backed by a server-side validation proof for the returned bytes. The result endpoint returns 503 AUTHORITATIVE_VALIDATION_UNAVAILABLE when required authoritative validation, proof persistence, or hybrid-generation dependencies are unavailable. Cached task-result downloads are reused only when the cached artifact still has a persisted validation proof.

### 2026-03-06
Task-result-downloads formaatgetrouw gemaakt voor CII- en ZUGFERD-uitvoer. Hergebruik van gecachte resultaatartefacten toegevoegd voor herhaalde XML/PDF-downloads van dezelfde task. Pollingquota afgestemd op endpoint-gescopeerde gewogen rate-limit-buckets.

### 2026-02-23
Duidelijkere, consistente API-foutresponses toegevoegd voor alle endpoints. Convert-opties uitgebreid en XML/PDF-downloadgedrag voor taskresultaten gedocumenteerd. Retryveiligheid verbeterd met strengere idempotency-vereisten en validatie. OpenAPI/Postman-artefacten bijgewerkt naar huidig API-gedrag.

## Leveringsartefacten

Download machineleesbare integratieartefacten voor de Developer API.

- [OpenAPI JSON](/developer-api/v1/openapi.json)
- [Postman-collectie](/developer-api/v1/postman.json)

## Postman en OpenAPI gebruiken

- Importeer de Postman-collectie en stel de collectievariabelen `base_url`, `api_key` en `idempotency_key` in.
- Voer de collectie op volgorde uit: convert, status pollen, daarna result ophalen.
- Gebruik de OpenAPI JSON om typed clients te genereren, maar dek file upload, polling en binaire result handling af met integratietests.
- Leg `X-Correlation-ID` vast in logs zodat support requests end-to-end kan traceren.

## Stuur technische feedback

Deel implementatievragen, risico’s en benodigde contractwijzigingen met ons team.

- [Technische feedback e-mailen](mailto:contact@invoice-converter.com?subject=Technische%20reviewfeedback%20Externe%20API%20V1&body=Hallo%20Invoice-Converter-team%2C%0D%0A%0D%0AWij%20hebben%20de%20Externe%20API%20V1-documentatie%20beoordeeld%20en%20hebben%20de%20volgende%20feedback%3A%0D%0A%0D%0A1)%20%0D%0A2)%20%0D%0A3)%20%0D%0A%0D%0AMet%20vriendelijke%20groet%2C)
