# Documentation API externe V1

Convertissez vos factures en e-factures validées depuis vos propres systèmes : envoyez un document PDF, DOCX ou TXT – ou des données ERP structurées – et téléchargez la sortie XRechnung, ZUGFeRD, EN 16931, UBL ou CII une fois la validation réussie. Cette page constitue le contrat d’intégration complet : modèle d’accès, endpoints, catalogue d’erreurs et limites.

> Cinq endpoints REST transforment des factures PDF, DOCX ou TXT – ou des données ERP structurées – en e-factures validées XRechnung, ZUGFeRD, EN 16931, UBL et CII. Les abonnés Enterprise actifs créent directement leurs clés ; 100 conversions partagées E-mail/API sont incluses chaque mois, puis chaque conversion utilise 0,50 € de crédits prépayés.

## Vue d’ensemble

L’API accepte les envois multipart, renvoie des réponses JSON et utilise les codes de statut HTTP standard avec authentification Bearer. Chaque conversion est asynchrone : envoyez le document, interrogez la tâche, téléchargez le résultat. Un fichier n’est livré qu’après validation réussie – il n’existe aucune sortie non validée.

Envoyez un document de facture PDF, DOCX ou TXT ou des données de facture structurées à un endpoint de conversion. Invoice-Converter démarre une tâche asynchrone pour l’extraction, la validation et la génération d’artefacts. L’endpoint de résultat renvoie un fichier uniquement lorsque l’artefact demandé est validé, contrôlé et prêt ; pendant le traitement, il renvoie 202 TASK_NOT_READY, et les problèmes de validation bloquants renvoient 422 VALIDATION_FAILED.

> **Statut: accès Enterprise**: Chemin de base: /api/v1. Dernière synchronisation 2026-08-07.

## Fonctionnalités clés

- Endpoints d’upload pour factures PDF et données de facture structurées
- Extraction de données de facture assistée par IA
- Validation automatique EN 16931 et KoSIT
- Formats de sortie XRechnung, ZUGFeRD, EN16931, UBL et CII
- Traitement asynchrone avec polling, petites factures en environ 30 secondes et factures plus volumineuses jusqu’à 1-2 minutes
- Écritures idempotentes pour des retries sûrs

## Démarrer l’accès API Enterprise

Chaque abonné Enterprise actif peut créer des clés API de production directement dans son profil.

1. Créez un compte et démarrez Enterprise à 50 €/mois ou 420 €/an depuis la page des tarifs.
2. Utilisez les 100 conversions partagées E-mail/API incluses chaque mois ; les conversions supplémentaires utilisent des crédits prépayés à 0,50 € chacune.
3. Créez une clé API live depuis la section d’accès API de votre profil.
4. Envoyez la première requête avec des identifiants côté serveur, puis surveillez l’usage et tournez les clés depuis votre profil.

## Démarrer Enterprise

- [Offre Enterprise et tarifs](/pricing)

## Démarrage rapide

Trois appels API terminent une conversion. L’endpoint de conversion est servi sous /api/v1 et nécessite une authentification.

### POST /api/v1/invoices:convert (Live)
Convertir un document de facture

### POST /api/v1/invoices:convert-structured (Live)
Convertir des données structurées

### GET /api/v1/tasks/{task_id} (Live)
Interroger le statut de tâche

## Démarrage rapide avec curl

Remplacez $API_KEY par votre clé live et $TASK_ID par le task_id de la première réponse. Les trois mêmes appels fonctionnent pour tous les formats de sortie.

### 1. Lancer la conversion
```
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. Interroger la tâche jusqu’à completed
```
curl "https://www.invoice-converter.com/api/v1/tasks/$TASK_ID" \
  -H "Authorization: Bearer $API_KEY"
```

### 3. Télécharger le fichier validé
```
curl -o invoice.xml \
  "https://www.invoice-converter.com/api/v1/tasks/$TASK_ID/result?download=xml" \
  -H "Authorization: Bearer $API_KEY"
```

## URL de base et clés API

- URL de base production : `https://www.invoice-converter.com/api/v1`.
- Les clés live utilisent le host de production et le préfixe `icp_...`.
- Lancez les requêtes d’onboarding et de validation avec votre clé live avant d’envoyer du volume de production.
- Traitez les clés comme des secrets serveur. Ne les intégrez pas dans des clients navigateur ou mobiles.

## Première requête réussie

Utilisez cette séquence comme parcours minimal après création d’une clé API.

- Téléversement : `POST /api/v1/invoices:convert` avec `Authorization`, `Idempotency-Key`, `file=@invoice.pdf` (ou `.docx`/`.txt`) et `format=XRECHNUNG`.
- Interrogez avec backoff : attendez environ `20 secondes` après le `202`, puis appelez `GET /api/v1/tasks/{task_id}` à 20s, 30s, 45s, 60s puis 60s d’intervalle jusqu’au statut `completed` ou `failed`. Restez dans le quota de statut de `10/min` et `120/hour`, et abandonnez après environ 16 minutes.
- Téléchargement : `GET /api/v1/tasks/{task_id}/result?download=xml` et stockez `X-Correlation-ID` pour le traçage support.
- Pour une sortie PDF ZUGFeRD, demandez `format=ZUGFERD` au convert et `download=pdf` au result ; la sortie PDF hybride exige une source PDF.
- Pour une entrée structurée, appelez `POST /api/v1/invoices:convert-structured` avec `pdf_file=@invoice.pdf`, `data_file=@invoice-data.json` et le `format` cible.
- Envoyez éventuellement `client_reference` ou `external_invoice_id` et `source_system` pour le rapprochement ERP.
- Pour des exports ERP fractionnés d’une facture, répétez `data_file` ; pour plusieurs factures, démarrez une tâche par facture avec sa propre clé d’idempotence.
- Conservez `result_artifacts` depuis la réponse de statut pour savoir quels artefacts XML/PDF sont validés, mis en cache ou encore indisponibles à cause de dépendances.

## Exemples courants de payload

- `XRECHNUNG` : envoyez `format=XRECHNUNG`.
- `ZUGFERD` : envoyez `format=ZUGFERD` ; utilisez `download=pdf` au result pour la sortie hybride PDF/A-3.
- `Entrée structurée` : envoyez `pdf_file` avec une ou plusieurs parties `data_file` ; les formats de données acceptés sont CSV, JSON, XML, XLSX et TXT, avec tout format cible pris en charge. Les parties `data_file` doivent contenir toutes les données obligatoires ; le PDF ne complète pas les champs manquants. .xls, les PDF et les images sont refusés comme `data_file`.
- `Factures multiples` : envoyez des requêtes convert séparées et suivez chaque `task_id` renvoyé ; les parties `data_file` répétées servent uniquement aux exports fractionnés de la même facture.
- `UBL` : envoyez `format=UBL` ; les profils acceptés sont `XRECHNUNG`, `PEPPOL` et `EN16931`, avec `EN16931` par défaut.
- `CII` : envoyez `format=CII` ; les profils acceptés sont `XRECHNUNG`, `EN16931`, `ZUGFERD_EN16931` et `ZUGFERD_XRECHNUNG`, avec `EN16931` par défaut.
- `format` x `profile` est une table fermée : `XRECHNUNG` accepte `[XRECHNUNG]` (par défaut `XRECHNUNG`), `EN16931` accepte `[EN16931]` (par défaut `EN16931`), `UBL` accepte `[XRECHNUNG, PEPPOL, EN16931]` (par défaut `EN16931`), `CII` accepte `[XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG]` (par défaut `EN16931`) et `ZUGFERD` accepte `[ZUGFERD_EN16931, ZUGFERD_XRECHNUNG]` (par défaut `ZUGFERD_EN16931`). Les profils sont comparés sans tenir compte de la casse ; `ZUGFERD`, `FACTURX`, `FACTUR-X` et `FACTUR_X` sont des alias de `ZUGFERD_EN16931`, et `ZUGFERD-XRECHNUNG` est un alias de `ZUGFERD_XRECHNUNG`.

## En-têtes requis

- Authorization: Bearer <api_key>

## Règles d’authentification

Chaque abonné Enterprise actif peut créer des clés API depuis le profil et les utiliser comme Bearer token. Le quota partagé E-mail/API comprend 100 conversions par mois ; les conversions supplémentaires utilisent des crédits prépayés à 0,50 € chacune.

- Les clés sont des identifiants live limités au tenant pour les abonnements Enterprise actifs. Le préfixe de production actuel est `icp_...`.
- Créez, tournez et révoquez les clés API depuis votre profil tant que l’abonnement Enterprise est actif. Copiez les nouvelles clés immédiatement, car leur valeur en clair n’est affichée qu’une seule fois.
- Une clé manquante ou invalide renvoie `401`.
- Les appels vers `/api/v1` reçoivent automatiquement un `X-Correlation-ID` s’il est omis.
- Les appels d’écriture exigent `Idempotency-Key` ; gardez cette valeur stable entre les réessais.
- Utilisez une intégration serveur-à-serveur depuis votre backend. L’accès depuis une origine navigateur est restreint en production.

## Contrat d’idempotence

- Envoyez un `Idempotency-Key` à chaque appel d’écriture.
- Les clés d’idempotence doivent correspondre à `[A-Za-z0-9._:-]+` et faire au plus 200 caractères.
- Si vous fournissez votre propre clé, la même clé + le même payload renvoie la réponse en cache.
- La même clé + un payload différent renvoie `409 IDEMPOTENCY_CONFLICT`, qui n’est pas réessayable ; utilisez une nouvelle clé pour un nouveau payload.
- Une seconde requête avec la même clé pendant que la première est encore en cours renvoie `409 IDEMPOTENCY_IN_PROGRESS` ; réessayez la même clé après un court délai. Une réservation bloquée est libérée après `15 minutes`.
- Une fois la tâche d’origine au-delà de sa rétention de 24 heures, un rejeu renvoie `409 IDEMPOTENCY_REPLAY_EXPIRED` ; lancez une nouvelle conversion avec une nouvelle clé.
- Les enregistrements d’idempotence vivent `24 heures`, comme la rétention des tâches.

## Référence des endpoints

Tous les endpoints sont disponibles sous /api/v1. Les timeouts apparaissent en 504 et les autres erreurs temporaires de connectivité en 502 ; les ID de corrélation aident le support à suivre les requêtes de bout en bout.

### POST /api/v1/invoices:convert (Live)
Téléversez un document de facture PDF, DOCX ou TXT et démarrez la conversion asynchrone. Renvoie un task_id pour le polling. Les PDF hybrides ZUGFeRD/Factur-X exigent une source PDF ; pour les sources DOCX/TXT, demandez des résultats XML. Requête: multipart/form-data; file (binary, requis) — document source de facture PDF, DOCX ou TXT ; les anciens fichiers DOC/RTF, images et autres fichiers sont refusés; format (string, requis) — format de sortie cible ; voir la matrice des formats ci-dessous; profile (string, optionnel, recommandé pour les intégrations déterministes) — profil de conformité explicite, comparé sans tenir compte de la casse. Chaque format a un ensemble fermé de valeurs acceptées et une seule valeur par défaut : XRECHNUNG → [XRECHNUNG] (par défaut XRECHNUNG) ; EN16931 → [EN16931] (par défaut EN16931) ; UBL → [XRECHNUNG, PEPPOL, EN16931] (par défaut EN16931) ; CII → [XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (par défaut EN16931) ; ZUGFERD → [ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (par défaut ZUGFERD_EN16931). ZUGFERD, FACTURX, FACTUR-X et FACTUR_X sont des alias de ZUGFERD_EN16931 ; ZUGFERD-XRECHNUNG est un alias de ZUGFERD_XRECHNUNG. Une valeur hors de l’ensemble accepté renvoie 422 OUTPUT_PROFILE_CONFLICT ; un nom de profil non reconnu renvoie 422 INVALID_PROFILE avec details.allowed_profiles; jurisdiction (string, optionnel) — contexte de juridiction ISO 3166-1 alpha-2 explicite utilisé pour les contrôles de validation/conseil ; ne remplace pas le profil; transaction_scope (string, optionnel) — contexte de périmètre transactionnel explicite, par exemple B2G ; appliqué à la tâche mise en file; delivery_channel (string, optionnel) — PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF ou UNKNOWN ; appliqué à la tâche mise en file; client_reference ou external_invoice_id (string, optionnel) — référence facture/job côté client renvoyée dans les uploads acceptés et les réponses de statut; source_system (string, optionnel) — libellé ERP ou système de facturation amont renvoyé dans les uploads acceptés et les réponses de statut; use_seller_master_data (boolean, optionnel) — si omis, la valeur par défaut du profil du tenant s’applique ; false ignore les données de base vendeur enregistrées pour cette requête, true fournit/utilise les données de base vendeur; seller_master_data (chaîne d’objet JSON, optionnel) — données vendeur utilisées uniquement lorsque use_seller_master_data=true ; prend en charge les champs société, adresse, fiscalité, contact et paiement (payment_means_code 30/42/58, payment_iban, payment_bic, payment_account_name, payment_terms_note) ; chaque valeur du profil remplace la valeur extraite correspondante, les champs absents du profil restent inchangés et les différences créent des avertissements non bloquants. Réponse: 202 Accepted.

### POST /api/v1/invoices:convert-structured (Live)
Téléversez un PDF porteur avec des données de facture CSV, JSON, XML, XLSX ou TXT et démarrez une conversion asynchrone depuis données structurées. Les parties data_file sont la seule source sémantique ; le PDF ne complète pas les champs de facture manquants. Pour ZUGFeRD/Factur-X, il sert de PDF porteur ; pour les sorties orientées XML, il est conservé comme artefact PDF soumis. Utilisez une requête de conversion par facture ; répétez data_file uniquement pour des exports ERP fractionnés décrivant la même facture. Requête: multipart/form-data; pdf_file (binary, requis) — PDF porteur utilisé pour l’intégration ZUGFeRD/Factur-X et conservé pour les sorties orientées XML; data_file (binary, requis, répétable) — données de facture CSV, JSON, XML, XLSX ou TXT utilisées comme seule source sémantique ; .xls, les PDF et les images sont refusés comme data_file ; répéter pour les exports header/lines fractionnés de la même facture ; les alias data_files et data_files[] sont acceptés; taille totale des données structurées — maximum 2 MB sur toutes les parties data_file; format (string, requis) — format de sortie cible ; prend en charge XRECHNUNG, ZUGFERD, EN16931, UBL et CII; profile (string, optionnel, recommandé pour les intégrations déterministes) — profil de conformité explicite, comparé sans tenir compte de la casse. Chaque format a un ensemble fermé de valeurs acceptées et une seule valeur par défaut : XRECHNUNG → [XRECHNUNG] (par défaut XRECHNUNG) ; EN16931 → [EN16931] (par défaut EN16931) ; UBL → [XRECHNUNG, PEPPOL, EN16931] (par défaut EN16931) ; CII → [XRECHNUNG, EN16931, ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (par défaut EN16931) ; ZUGFERD → [ZUGFERD_EN16931, ZUGFERD_XRECHNUNG] (par défaut ZUGFERD_EN16931). Une valeur hors de l’ensemble accepté renvoie 422 OUTPUT_PROFILE_CONFLICT ; un nom de profil non reconnu renvoie 422 INVALID_PROFILE avec details.allowed_profiles; jurisdiction (string, optionnel) — contexte de juridiction ISO 3166-1 alpha-2 explicite utilisé pour les contrôles de validation/conseil ; ne remplace pas le profil; transaction_scope (string, optionnel) — contexte de périmètre transactionnel explicite, par exemple B2G ; appliqué à la tâche mise en file; delivery_channel (string, optionnel) — PEPPOL, DIRECT_XML, PORTAL, EMAIL_PDF ou UNKNOWN ; appliqué à la tâche mise en file; client_reference ou external_invoice_id (string, optionnel) — référence facture/job côté client renvoyée dans les uploads acceptés et les réponses de statut; source_system (string, optionnel) — libellé ERP ou système de facturation amont renvoyé dans les uploads acceptés et les réponses de statut; use_seller_master_data (boolean, optionnel) — si omis, la valeur par défaut du profil du tenant s’applique ; false ignore les données de base vendeur enregistrées pour cette requête, true fournit/utilise les données de base vendeur; seller_master_data (chaîne d’objet JSON, optionnel) — données vendeur utilisées uniquement lorsque use_seller_master_data=true ; prend en charge les champs société, adresse, fiscalité, contact et paiement (payment_means_code 30/42/58, payment_iban, payment_bic, payment_account_name, payment_terms_note) ; chaque valeur du profil remplace la valeur extraite correspondante, les champs absents du profil restent inchangés et les différences créent des avertissements non bloquants. Réponse: 202 Accepted.

### GET /api/v1/tasks/{task_id} (Live)
Interrogez le statut actuel d’une tâche de conversion. Renvoie pending (acceptée et en file, pas encore démarrée), processing, completed ou failed. Rate limit 10/min et 120/hour, ce qui constitue la contrainte déterminante pour le polling : attendez environ 20 secondes après le 202 accepté avant le premier appel, puis espacez les appels (20s, 30s, 45s, 60s, puis 60s ensuite) et arrêtez sur completed ou failed. Les tâches terminées incluent des diagnostics `result_artifacts` pour indiquer quels artefacts XML/PDF sont disponibles, mis en cache et prouvés par validation. Les payloads des tâches terminées peuvent inclure des entrées additives `_processing_warnings` et `_validation_warnings` avec des ID de règle SOURCE_CONTEXT_* lorsque les preuves source étaient indisponibles, douteuses ou tronquées ; traitez-les comme des signaux de revue, pas comme des échecs. En cas d’échec, la réponse inclut un champ error avec le motif. Requête: aucun (GET); task_id (path, requis) — UUID renvoyé par l’endpoint de conversion; include_validation_report_html (query, optionnel) — true ou false (false par défaut) ; avec true, la réponse de statut inclut le rapport de validation HTML assaini de l’artefact strict actuel lorsqu’il est disponible. Réponse: 200 OK.

### GET /api/v1/tasks/{task_id}/result (Live)
Téléchargez le fichier généré (XML ou PDF). La syntaxe du résultat correspond au format initial de la tâche : XRECHNUNG/EN16931/UBL renvoient du XML UBL, CII/ZUGFERD renvoient du XML CII, et ZUGFERD + download=pdf renvoie un PDF/A-3 hybride. Pour d’autres formats, download=pdf peut renvoyer un PDF rendu ; sur une tâche terminée, download=xml est l’artefact attendu comme disponible, pas un artefact garanti. Les téléchargements répétés peuvent être servis depuis des artefacts générés en cache lorsque la preuve de validation est encore actuelle. Pendant le traitement, cet endpoint renvoie un 202 portant l’enveloppe d’erreur standard ({"code":"TASK_NOT_READY","message":"Strict conversion is still processing. No validated artifact is available yet.","correlation_id":"<uuid>"}) ; les problèmes de validation bloquants renvoient 422 VALIDATION_FAILED, les dépendances temporairement indisponibles renvoient 503, les échecs de conversion terminaux renvoient 500 TASK_FAILED avec la raison dans details.code, et les échecs d’invariant d’artefact renvoient 500 INTERNAL_ARTIFACT_INVARIANT_FAILED, toujours sans corps de fichier. Les téléchargements réussis portent 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 et X-Validator-Bundle-Id ; X-Task-Id n’est pas défini sur cet endpoint. Rate limit 10/min et environ 134/hour. Requête: aucun (GET); task_id (path, requis) — UUID renvoyé par l’endpoint de conversion; download (query, requis) — xml ou pdf. Réponse: 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. Requête: none (GET); task_id (path, required) — UUID returned by the convert endpoint; download (query, optional) — html or xml. Réponse: 200 OK.

## Matrice des formats de sortie

| Format | Syntaxe | Version / Profil | Content-Type | Extension |
| --- | --- | --- | --- | --- |
| XRECHNUNG | UBL 2.1 XML | XRechnung 3.0.2 | application/xml | .xml |
| ZUGFERD | CII XML (download=xml) / PDF/A-3 hybride (download=pdf) | ZUGFeRD 2.3.2 / Factur-X 1.07.2 | application/xml ou 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 |

## Contrat d’erreur

| Code | HTTP | À retenter | Notes |
| --- | --- | --- | --- |
| AUTHENTICATION_REQUIRED | 401 | Non | Bearer token manquant/vide |
| INVALID_API_KEY | 401 | Non | Clé API introuvable, révoquée ou expirée |
| API_NOT_ENABLED_FOR_TENANT | 403 | Non | Key is valid but External API access is not enabled for the account; contact support instead of retrying |
| INSUFFICIENT_API_CREDITS | 402 | Non | L’allocation mensuelle incluse plus les crédits API prépayés ne couvraient pas la requête. Deux formes de details : prépayé (remaining, minimum_purchase 100) et allocation incluse (included_remaining, credit_remaining, shortfall, minimum_purchase 100). Analysez le code et lisez les clés effectivement présentes |
| IDEMPOTENCY_KEY_REQUIRED | 400 | Non | Endpoint d’écriture appelé sans Idempotency-Key |
| INVALID_IDEMPOTENCY_KEY | 400 | Non | La clé d’idempotence doit correspondre à [A-Za-z0-9._:-]+ et faire au plus 200 caractères |
| IDEMPOTENCY_CONFLICT | 409 | Non | La clé a déjà été utilisée avec un payload différent, ou la réservation idempotente n’a pas pu démarrer ; utilisez une nouvelle clé pour un nouveau payload |
| IDEMPOTENCY_IN_PROGRESS | 409 | Oui | La première requête avec cette clé est encore en cours ; réessayez avec la MÊME clé après un court délai. Une réservation bloquée est libérée après 15 minutes |
| IDEMPOTENCY_REPLAY_EXPIRED | 409 | Non | The original task is past its 24-hour retention and cannot be recovered; start a new conversion with a new key |
| FORMAT_REQUIRED | 400 | Non | Format requis manquant dans la requête de conversion |
| INVALID_FORMAT | 422 | Non | Format de conversion non pris en charge |
| CLIENT_REFERENCE_CONFLICT | 400 | Non | client_reference et external_invoice_id diffèrent |
| INVALID_CLIENT_METADATA | 400 | Non | client_reference, external_invoice_id ou source_system dépasse la limite de longueur ou contient des caractères de contrôle |
| INVALID_SELLER_MASTER_DATA | 400 | Non | use_seller_master_data ou seller_master_data n’est pas analysable ou échoue à la validation des champs |
| METHOD_NOT_ALLOWED | 405 | Non | Les chemins de conversion n’acceptent que POST et les chemins de tâche que GET ; la réponse inclut Allow: POST, OPTIONS (conversion) ou Allow: GET, OPTIONS (tâche) |
| DOWNLOAD_FORMAT_REQUIRED | 400 | Non | Paramètre download requis manquant dans la requête de résultat de tâche |
| INVALID_DOWNLOAD_FORMAT | 400 | Non | download doit être xml ou pdf |
| AUTH_SERVICE_UNAVAILABLE | 503 | Oui | Backend d’auth indisponible |
| RATE_LIMIT_SERVICE_UNAVAILABLE | 503 | Oui | Le service de rate-limit n’a pas pu être joint ; réessayez avec backoff |
| PLAN_TIER_CHECK_FAILED | 503 | Oui | Plan/API access could not be verified right now; retry with backoff |
| API_CREDIT_SERVICE_UNAVAILABLE | 503 | Oui | La vérification des crédits API prépayés ou du quota de canal est temporairement indisponible sur les uploads de conversion |
| RATE_LIMITED | 429 | Oui | Respecter Retry-After. Retry-After, X-RateLimit-Limit-Minute et X-RateLimit-Limit-Hour ne sont renvoyés que sur les réponses 429 ; le corps porte details.minute_count, details.hour_count, details.limit_minute et details.limit_hour |
| BAD_REQUEST | 400 | Non | JSON invalide ou paramètre de chemin UUID invalide |
| INVALID_QUERY_PARAMETER | 400 | Non | include_validation_report_html doit être true ou false |
| PAYLOAD_TOO_LARGE | 413 | Non | Limite de taille d’upload dépassée |
| INVALID_UPLOAD | 400 | Non | Échec de lecture/parsing de l’upload |
| UPLOAD_FAILED | 422 | Non | Un champ de contexte optionnel (jurisdiction, transaction_scope, delivery_channel) contenait une valeur non reconnue ; les valeurs autorisées figurent dans le message |
| INVALID_PROFILE | 422 | Non | The value is not a recognized profile name; details.allowed_profiles lists the accepted set |
| TASK_NOT_READY | 202 | Oui | Poller à nouveau pour la fin asynchrone |
| TASK_NOT_FOUND | 404 | Non | La tâche est inconnue, n’appartient pas au tenant, ou a dépassé sa rétention de 24 heures après avoir atteint un état terminal |
| VALIDATION_FAILED | 422 | Non | Des problèmes de validation bloquants subsistent, y compris les échecs de prérequis stricts ZUGFeRD et les entrées blocking_source_conflict non résolues ; corrigez les données de facture avant de réessayer |
| AUTHORITATIVE_VALIDATION_UNAVAILABLE | 503 | Oui | La validation faisant autorité, la persistance de la preuve ou une dépendance de génération hybride est indisponible ; réessayez plus tard |
| TASK_STATUS_FAILED | 4xx/5xx | Conditionnel | Réessayer si la condition de service est transitoire |
| TASK_RESULT_FAILED | 4xx/5xx | Conditionnel | Réessayer si la condition de service est transitoire |
| TASK_FAILED | 500 | Conditionnel | Échec de conversion signalé sur l’endpoint de résultat. Lisez details.code et details.retryable : MULTIPLE_INVOICES_IN_DOCUMENT, NO_INVOICE_DETECTED, INSUFFICIENT_INVOICE_SIGNAL, SCHEMA_PARSE_FAILED et ARTIFACT_PARITY_FAILED sont terminaux ; PROVIDER_ERROR et tout details.code non reconnu suivent details.retryable, et details.retryable=true signifie lancer une NOUVELLE conversion avec une nouvelle Idempotency-Key au lieu de re-poller la même tâche. La conversion échouée ne consomme pas d’unité de facturation |
| MULTIPLE_INVOICES_IN_DOCUMENT | 500 (details code) | Non | 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) | Non | Terminal: the document does not look like an invoice. Route to human handling |
| INSUFFICIENT_INVOICE_SIGNAL | 500 (details code) | Non | Terminal: not enough invoice data for reliable extraction. Supply a better source document or use structured conversion |
| SCHEMA_PARSE_FAILED | 500 (details code) | Non | 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) | Conditionnel | Extraction-provider failure; details.retryable is authoritative. When details.classification is provider_context_too_large, use a smaller source document |
| XML_GENERATION_FAILED | 500 | Oui | Échec transitoire ou timeout de génération XML |
| PDF_GENERATION_FAILED | 500 | Oui | Échec transitoire ou timeout de génération PDF |
| ARTIFACT_GENERATION_RERUN_REQUIRED | 503 | Non | La génération stricte d’artefact a échoué après les réessais serveur ; lancez une nouvelle conversion après le rétablissement de la dépendance |
| EXTRACTION_INCOMPLETE_GROUP_FAILURE | 503 | Non | 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) | Non | Enregistré sur les tâches échouées pour les échecs d’émission stricte réessayables ; les téléchargements de résultat renvoient 503 ARTIFACT_GENERATION_RERUN_REQUIRED avec ce code dans details |
| ARTIFACT_PARITY_FAILED | 500 (details code) | Non | Signalé dans les details de 500 TASK_FAILED lorsque l’artefact strict ne correspond pas aux données de facture finales revues ; escaladez avec l’ID de corrélation |
| INTERNAL_ARTIFACT_INVARIANT_FAILED | 500 | Non | La tâche stricte terminée n’a aucun artefact stocké sûr pour le téléchargement demandé ; escaladez avec l’ID de corrélation |
| PROFILE_MISMATCH | 422 | Non | Le profil demandé ne correspond pas au CustomizationID du résultat stocké lors du téléchargement du résultat |
| ZUGFERD_SOURCE_PDF_INCOMPATIBLE | 422 | Non | La génération stricte du PDF hybride ne peut pas intégrer le XML dans le PDF source téléversé |
| ZUGFERD_SOURCE_PDF_REQUIRED | 422 | Non | download=pdf pour ZUGFERD exige une source PDF (les sources DOCX/TXT ne peuvent pas porter le PDF hybride) ; demandez download=xml à la place |
| VALIDATION_REPORT_NOT_FOUND | 404 | Non | Aucun rapport de validation n’est lié à la preuve de l’artefact actuellement livré |
| VALIDATION_REPORT_FAILED | 4xx/5xx | Conditionnel | Échec de récupération du rapport de validation ; réessayez uniquement pour les cas 5xx transitoires |
| OUTPUT_PROFILE_REQUIRED | 422 | Non | Un contrat de sortie générique exige un profil explicite lorsqu’aucune valeur par défaut non ambiguë ne peut être déterminée |
| OUTPUT_PROFILE_CONFLICT | 422 | Non | Le profil contredit le format de sortie sélectionné ou la variante explicite |
| PROXY_ERROR | 502/504 | Oui | Défaillance de transport plutôt que résultat de conversion : échec proxy/amont (504 pour timeout). Réessayez avec backoff et la même clé d’idempotence |

## Erreurs courantes et actions à mener

- Réessayez avec backoff : `429`, `502`, `504`, `503` avec un code réessayable, et les `500` transitoires qui ne sont pas `TASK_FAILED` ni `INTERNAL_ARTIFACT_INVARIANT_FAILED`. `500 TASK_FAILED` n’est réessayable que si `details.retryable` vaut `true`, et uniquement sous forme de nouvelle conversion.
- Ne réessayez pas : `400`, `401`, `402`, `403`, `404`, `405`, `413`, `422`, `409 IDEMPOTENCY_CONFLICT`, `409 IDEMPOTENCY_REPLAY_EXPIRED`, `500 TASK_FAILED` lorsque `details.retryable` ne vaut pas `true`, et `500 INTERNAL_ARTIFACT_INVARIANT_FAILED`.
- Corrigez la requête ou les données source : `400`, `413`, `422`.
- Corrigez l’accès ou les identifiants : `401 INVALID_API_KEY`. `403 API_NOT_ENABLED_FOR_TENANT` signifie que la clé est valide mais que l’accès External API n’est pas activé pour le compte — contactez le support.
- Vérifiez l’allocation mensuelle incluse ou achetez un pack de crédits API prépayés : `402 INSUFFICIENT_API_CREDITS`. Lisez les clés `details` effectivement présentes (`remaining` pour les comptes prépayés, ou `included_remaining`/`credit_remaining`/`shortfall` lorsqu’une allocation incluse s’applique).
- Continuez à poller plus tard : `202 TASK_NOT_READY`.
- Pour `500 TASK_FAILED`, lisez `details.code` et `details.retryable`. `MULTIPLE_INVOICES_IN_DOCUMENT`, `NO_INVOICE_DETECTED`, `INSUFFICIENT_INVOICE_SIGNAL`, `SCHEMA_PARSE_FAILED` et `ARTIFACT_PARITY_FAILED` sont terminaux ; `PROVIDER_ERROR` et tout code non reconnu suivent `details.retryable`, et `true` signifie lancer une NOUVELLE conversion au lieu de re-poller la même tâche. Une conversion échouée ne consomme pas d’unité de facturation.
- Pour `422 VALIDATION_FAILED`, montrez le champ, l’ID de règle et la correction proposée à une personne chargée de la revue avant de réessayer avec les données corrigées.
- Pour `503 AUTHORITATIVE_VALIDATION_UNAVAILABLE`, récupérez le même résultat de tâche plus tard ; aucun artefact non vérifié n’a été livré. Pour `503 ARTIFACT_GENERATION_RERUN_REQUIRED` et `503 EXTRACTION_INCOMPLETE_GROUP_FAILURE`, lancez plutôt une nouvelle conversion.
- `502` et `504 PROXY_ERROR` sont des défaillances de transport et non des résultats de conversion ; réessayez avec backoff et la même clé d’idempotence.

## Limites de débit et de payload

Les rate limits par clé API et les contraintes de taille de payload s’appliquent à tous les appels API. Les conversions refusées ne consomment pas de crédits API prépayés ; les rate limits sont évaluées séparément par endpoint.

- Les limites sensibles à l’endpoint sont pondérées par coût, et chaque endpoint a son propre bucket afin que le polling ne puisse pas affamer le débit de conversion. Valeurs par défaut par clé API : `POST /invoices:convert` et `POST /invoices:convert-structured` `30/min` et `500/hour` ; `GET /tasks/{task_id}` `10/min` et `120/hour` ; `GET /tasks/{task_id}/result` `10/min` et environ `134/hour` ; `GET /tasks/{task_id}/validation-report` `10/min` et `120/hour`.
- Les headers de quota ne sont renvoyés que sur les réponses `429 RATE_LIMITED`. Les réponses réussies ne portent pas de headers de quota : traitez le tableau ci-dessus comme le contrat de travail et lisez les valeurs effectives exactes sur une réponse `429`.
- Le bucket de statut est la contrainte déterminante pour le polling : attendez environ `20 secondes` après le `202` accepté avant le premier appel de statut, puis espacez les appels (20s, 30s, 45s, 60s, puis 60s ensuite) et arrêtez sur `completed` ou `failed`. N’interrogez pas toutes les 10 secondes ; une seule tâche interrogée ainsi épuise tout son budget horaire en 20 minutes.
- Taille maximale d’upload de document source : `20 MB` pour les fichiers PDF, DOCX ou TXT.
- Taille maximale d’upload des données structurées : `2 MB` au total sur toutes les parties `data_file`.
- Taille maximale de payload JSON : `1 MB`
- Les réponses `429` incluent `Retry-After`, `X-RateLimit-Limit-Minute` et `X-RateLimit-Limit-Hour`, ainsi que `details.minute_count`, `details.hour_count`, `details.limit_minute` et `details.limit_hour`.

## Guide de nouvelle tentative

- Utilisez un backoff exponentiel avec jitter, et réutilisez la même `Idempotency-Key` à chaque réessai d’une requête d’écriture.
- Décidez sur le `code` lisible par machine — et sur `details.code` plus `details.retryable` pour `500 TASK_FAILED` — jamais sur le seul statut HTTP. Un `500` n’est pas automatiquement réessayable dans cette API.
- Réessayable : `429`, `502`, `504`, `503` avec un code réessayable, les `500` transitoires qui ne sont PAS `TASK_FAILED` ni `INTERNAL_ARTIFACT_INVARIANT_FAILED`, et `500 TASK_FAILED` lorsque `details.retryable` vaut `true` (échecs fournisseur transitoires : limitation de débit, timeout, erreur de transport) — réessayez ce cas comme une NOUVELLE conversion avec une nouvelle `Idempotency-Key`, pas en re-pollant la même tâche.
- Ne jamais réessayer : `400`, `401`, `402`, `403`, `404`, `405`, `413`, `422`, `409 IDEMPOTENCY_CONFLICT`, `409 IDEMPOTENCY_REPLAY_EXPIRED`, `500 TASK_FAILED` lorsque `details.retryable` ne vaut pas `true`, et `500 INTERNAL_ARTIFACT_INVARIANT_FAILED`. Une conversion échouée de manière terminale ne consomme pas d’unité de facturation.
- `409 IDEMPOTENCY_IN_PROGRESS` est réessayable avec la MÊME clé après un court délai ; une réservation bloquée est libérée après 15 minutes.
- `503 ARTIFACT_GENERATION_RERUN_REQUIRED` et `503 EXTRACTION_INCOMPLETE_GROUP_FAILURE` exigent une NOUVELLE conversion plutôt qu’un réessai de la même tâche.

## Cycle de vie des tâches et rétention

- Une tâche et ses artefacts stockés sont conservés `24 heures` après que la tâche atteint un état terminal (`completed` ou `failed`), puis purgés. Après la purge, les requêtes de statut, de résultat et de rapport de validation renvoient `404 TASK_NOT_FOUND`.
- Il n’y a pas de timeout de conversion fixe. Une tâche échoue après une fenêtre d’inactivité de `5 minutes` sans mise à jour d’étape ou de progression, ou dès que le traitement total dépasse le plafond absolu de `15 minutes`.
- Réglez votre timeout côté client à environ `16 minutes` à partir du `202` accepté. La plupart des conversions se terminent bien en dessous de deux minutes.
- Les enregistrements d’idempotence vivent `24 heures`, comme la rétention des tâches. Une requête bloquée en cours est libérée après `15 minutes`.
- Les compteurs de rate-limit se réinitialisent sur une fenêtre glissante.

## Modèle de support

- Support en heures ouvrées selon des efforts commercialement raisonnables.
- Aucun SLA formel, crédit de service ou engagement de temps de réponse sauf accord dans un order form.

## Journal des modifications

Dernières évolutions visibles de l’API.

### 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
Rattrapage de documentation ; aucun changement de comportement à l’exécution. Le catalogue d’erreurs documente désormais des codes d’erreur d’exécution auparavant non documentés, dont 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 et METHOD_NOT_ALLOWED. Les clients qui analysent les réponses d’erreur via le champ code lisible par machine n’ont rien à changer ; les clients qui s’appuient sur une liste fixe de codes doivent ajouter les valeurs nouvellement documentées. Dates du changelog corrigées : la prise en charge des sources DOCX/TXT a été livrée le 2026-06-30 et non le 2026-07-06.

### 2026-07-06
Les payloads des tâches terminées peuvent inclure des entrées additives _processing_warnings et _validation_warnings avec des ID de règle SOURCE_CONTEXT_* lorsque les preuves source étaient indisponibles, douteuses ou tronquées avant l’extraction. Traitez les entrées SOURCE_CONTEXT_* comme des signaux de revue pour la gestion des exceptions côté client ; les téléchargements d’artefacts stricts restent régis par la preuve de validation et les contrôles d’artefact.

### 2026-07-03
Les échecs de prérequis stricts ZUGFeRD (champs obligatoires manquants pour la génération hybride) échouent désormais en 422 VALIDATION_FAILED avec les ID de règle bloquants au lieu d’un 503 réessayable ; orientez-les vers un flux de correction des données, pas vers une boucle de réessai. Pour les formats XML uniquement (XRECHNUNG, EN16931, UBL, CII), le rendu PDF est désormais un artefact de commodité en best effort : download=xml reste la référence disponible sur les tâches terminées, tandis que download=pdf peut être indisponible si le rendu a échoué après l’émission du XML. Les conversions avec des conflits de source bloquants non résolus échouent désormais en 422 VALIDATION_FAILED avec des entrées blocking_source_conflict au lieu d’émettre un artefact.

### 2026-06-30
POST /api/v1/invoices:convert accepte désormais les documents sources de facture PDF, DOCX et TXT dans le champ file. Les anciens fichiers DOC, RTF, images et autres sources non prises en charge sont refusés avant le démarrage de la conversion. Les téléchargements PDF hybrides ZUGFeRD/Factur-X exigent toujours une source PDF ; utilisez les téléchargements XML pour les conversions depuis DOCX/TXT. Ajout de l’option include_validation_report_html=true sur GET /api/v1/tasks/{task_id} pour inclure en ligne le rapport de validation HTML assaini lorsqu’il est disponible. Les uploads de conversion acceptent désormais les champs optionnels use_seller_master_data et seller_master_data sur les deux endpoints, afin que les tenants approuvés puissent activer des données de base vendeur enregistrées ou limitées à la requête.

### 2026-06-29
Ajout de GET /api/v1/tasks/{task_id}/validation-report?download=html|xml pour récupérer le rapport de validation lié à la preuve de l’artefact de résultat strict actuel. Les réponses du rapport de validation exposent les headers ID de tâche, SHA-256 de l’artefact, ID de preuve de validation, ID de preuve du rapport, type de contenu du rapport et ID de corrélation.

### 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
L’accès External API est maintenant documenté comme accès approuvé et non comme création de clé non contrôlée. Clarification qu’aucun SLA formel, crédit de service ou pénalité contractuelle ne s’applique sauf accord dans un order form. format est désormais requis sur les deux endpoints de conversion ; les valeurs manquantes renvoient 400 FORMAT_REQUIRED et les valeurs non prises en charge 422 INVALID_FORMAT. download est désormais requis sur les requêtes task-result ; les valeurs manquantes renvoient 400 DOWNLOAD_FORMAT_REQUIRED et les valeurs non prises en charge 400 INVALID_DOWNLOAD_FORMAT. Les uploads de conversion acceptent maintenant client_reference/external_invoice_id et source_system pour le rapprochement côté client. Les réponses de conversion acceptée et de statut de tâche incluent maintenant status_url, primary_result_format, primary_result_url et les champs de rapprochement fournis.

### 2026-06-01
La conversion structurée accepte désormais tous les formats de sortie publics : XRECHNUNG, ZUGFeRD, EN16931, UBL et CII. La conversion structurée accepte maintenant des parties data_file répétables ainsi que les alias data_files et data_files[] pour les exports ERP scindés. Les bundles structurés multi-fichiers doivent décrire exactement une facture et échouent rapidement si les ID de facture du bundle sont contradictoires ou manquants. Clarification que plusieurs documents de facture doivent être soumis comme tâches de conversion séparées, chacune avec sa propre clé d’idempotence.

### 2026-05-27
Ajout de POST /api/v1/invoices:convert-structured pour la conversion de données structurées avec PDF porteur et CSV/JSON/XML/XLSX/TXT sur les formats de sortie pris en charge. Documentation du fait que les données structurées sont la seule source sémantique sur cet endpoint ; le PDF sert à l’intégration hybride. Artefacts OpenAPI et Postman mis à jour pour la conversion structurée.

### 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
Crédits API externes prépayés ajoutés pour les tenants non Enterprise. 402 INSUFFICIENT_API_CREDITS documenté pour les tenants approuvés sans facturation Enterprise par order form ni crédits prépayés. Confirmation que les relectures idempotentes ne consomment pas de crédits API supplémentaires. Clarification que le routage de modèle External API V1 est géré côté serveur, tandis que le profil et le contexte de livraison restent contrôlés par l’appelant.

### 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
Les téléchargements task-result respectent désormais le format pour les sorties CII et ZUGFERD. Réutilisation d’artefacts de résultat en cache ajoutée pour les téléchargements XML/PDF répétés d’une même tâche. Quotas de polling alignés sur les buckets de rate-limit pondérés par endpoint.

### 2026-02-23
Réponses d’erreur API plus claires et cohérentes ajoutées sur tous les endpoints. Options de conversion étendues et comportement de téléchargement XML/PDF documenté pour les résultats de tâche. Sécurité des réessais améliorée avec des exigences d’idempotence et une validation plus strictes. Artefacts OpenAPI/Postman mis à jour pour correspondre au comportement actuel de l’API.

## Artefacts de livraison

Téléchargez les artefacts d’intégration lisibles par machine pour la Developer API.

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

## Utiliser Postman et OpenAPI

- Importez la collection Postman et définissez les variables de collection `base_url`, `api_key` et `idempotency_key`.
- Exécutez la collection dans l’ordre : convert, polling du statut, puis récupération du résultat.
- Utilisez l’OpenAPI JSON pour générer des clients typés, mais couvrez upload fichier, polling et résultat binaire par des tests d’intégration.
- Enregistrez `X-Correlation-ID` dans les logs afin que le support puisse tracer les requêtes de bout en bout.

## Envoyer un retour technique

Partagez avec notre équipe les questions d’implémentation, risques et changements de contrat nécessaires.

- [Envoyer un retour technique par e-mail](mailto:contact@invoice-converter.com?subject=Retour%20de%20revue%20technique%20API%20externe%20V1&body=Bonjour%20%C3%A9quipe%20Invoice-Converter%2C%0D%0A%0D%0ANous%20avons%20revu%20la%20documentation%20API%20externe%20V1%20et%20avons%20les%20retours%20suivants%20%3A%0D%0A%0D%0A1)%20%0D%0A2)%20%0D%0A3)%20%0D%0A%0D%0ACordialement%2C)
