Soumettre une facture ou un avoir en JSON canonique
- Dans le bac à sable
En termes simples
Le service contrôle d’emblée le document par rapport au modèle canonique et aux pré-contrôles, et répond 422 si l’un des deux échoue. Tout le reste s’exécute de façon asynchrone (construction, validation officielle, transmission au canal, statuts) et est signalé par des événements de statut.
Une nouvelle soumission corrigée d’une facture rejetée utilise le même invoice_ref et une nouvelle
Idempotency-Key ; le service relie les tentatives.
En production, un export ERP n’est lu que si les paramètres du connecteur du client contiennent ses propres données de vendeur et de paiement,
et non l’exemple du mapping : sinon 422 connector-settings-missing, qui indique ce qui manque. Un bac à sable le lit
avec l’exemple, comme avant.
apiKeyAuthorizationBearer <token>Envoyez votre clé sous forme de jeton bearer : Authorization: Bearer <your-api-key>. L’état du service est le seul appel qui ne nécessite pas de clé.
Idempotency-Key*stringUne clé unique par requête logique (un UUID convient). Conservée aussi longtemps que les données du client. Avec la clé de l’opérateur, elle ne peut pas commencer par client: (400), la forme sous laquelle les clés de client sont stockées.
8 <= length <= 100application/json- body
Envoyez soit document (une facture canonique), soit connector avec export (un document ERP tel que l’ERP le renvoie),
pas les deux (400). Un export est mappé par la version de mapping active du connecteur, ou par mapping_version, puis
traité exactement comme la facture canonique à laquelle il correspond ; l’export lui-même est conservé avec la facture
(erp-export). Le profil XRechnung du connecteur ne s’applique que sur DE-XRECHNUNG, et quand le routeur choisit pour
un acheteur allemand. Un défaut de mapping (une unité inconnue, un champ ERP manquant) répond 422 en nommant le champ ERP.
connector?connectorDe quel ERP vient l’export. business-central : une facture de vente Business Central API v2.0. Un autre objet SAP, comme une commande ou un brouillon, répond 400.
"business-central""sap-b1"export?Le document ERP tel que l’ERP le renvoie. Les champs que le mapping ne lit pas sont ignorés.
mapping_version?mapping_versionUne version de mapping de ce connecteur. La version active si omise ; une version inconnue répond 400.
^v[0-9]+$client?stringLe client auquel appartient la facture. La clé de l’opérateur le nomme (omis, la facture appartient au client local de l’opérateur). Une clé de client peut l’omettre ou nommer son propre client ; tout autre client répond 403.
^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$invoice_ref?stringL’identifiant du document propre à l’ERP. Repris dans chaque événement de statut.
length <= 100route?|Omis ou null, le routeur le choisit d’après le document : le
country du vendeur, le buyer.address.country de l’acheteur, le profile, les identifiants d’accès stockés du client et, quand une règle
en a besoin, l’enregistrement Peppol de l’acheteur. Quand aucune règle ne convient, la réponse est 422 avec EI-ROUTE-UNDECIDED ou
EI-ROUTE-PEPPOL-UNKNOWN (source router). POST /validate l’exige toujours.
environment?stringDoit correspondre à l’environnement de la clé d’API ; donné explicitement comme garde-fou.
"sandbox""production"document*Une facture dans le modèle canonique. La signification des champs suit le modèle sémantique EN 16931. Les totaux ne font pas partie du modèle : le service les calcule à partir des lignes.
formats?array<>Quels documents produire là où le canal laisse un choix (Allemagne : xrechnung-ubl,
xrechnung-cii ou zugferd ; France : ubl, cii ou facturx). Les valeurs par défaut par canal sont fixées à l’intégration.
Sur POST /invoices, n’en nommez qu’un : c’est le document qui est construit, contrôlé et envoyé (le premier de chaque
liste ci-dessus si omis). Peppol et la Roumanie prennent ubl, la Pologne fa3. Une autre valeur, ou plus d’une,
répond 400. Factur-X et ZUGFeRD sont contrôlés deux fois : le CII intégré avec les règles du canal, puis le PDF.
Sur le canal allemand, un document sans profile est construit comme XRechnung.
erp_totals?Les totaux calculés par l’ERP. Le service calcule les siens à partir des lignes et refuse la facture (422, EI-TOTALS-MISMATCH, avec le nom du champ ERP) s’ils diffèrent, plutôt que d’envoyer un document que l’ERP contredit. Un connecteur les lit dans l’export lui-même ; les totaux nommés ici l’emportent.
Acceptée pour traitement. Suivez-la avec les liens renvoyés ou attendez les événements de statut.
application/json- response
id*stringstate*InvoiceStateL’état propre au service pour une facture. Les événements de statut rapportent le cycle de vie visible du partenaire ;
queued et submitting sont des étapes internes entre validated et submitted. validation_failed signifie que les règles officielles ont refusé le document ; depuis la
0.18.4, un contrôle qui n’a pas pu s’exécuter (KOSIT-RUN, EI-PDF-CHECK) est retenté, puis finit en dead_letter avec ce
code. Une dead_letter garde son document, de sorte que le même fichier répond avec duplicate_of ; depuis la 0.18.6, l’
opérateur peut annuler celle pour laquelle aucun appel au canal n’a été fait, et le fichier peut alors repartir.
"received""source_error""validated""validation_failed""queued""submitting""submitted""ready""accepted""rejected""delivered""cancelled""dead_letter"duplicate_of?|Renseigné quand le même document a déjà été accepté pour ce client et ce canal ; rien de nouveau n’est envoyé. Une soumission qui s’est terminée en rejected, validation_failed ou cancelled ne compte pas, donc le fichier peut être renvoyé. Depuis la 0.18.5, cela vaut aussi pour deux requêtes envoyées au même moment, sous des clés différentes ; l’une crée la facture et l’autre répond avec duplicate_of.
links*route?RouteSeulement quand le routeur a choisi le canal.
"PEPPOL""PL-KSEF""RO-EFACTURA""FR-PA""DE-XRECHNUNG"route_chosen_by?"router"Seulement quand la requête a omis le canal.
"router"route_rule?stringLa règle du routeur qui a choisi le canal ; également écrite dans le journal d’audit sous route_chosen.
"fr-domestic""fr-cross-border""pl-domestic""ro-domestic""be-domestic""de-domestic-peppol""de-domestic""cross-border-peppol"curl -X POST "https://example.com/invoices" \ -H "Authorization: Bearer <your-api-key>" \ -H "Idempotency-Key: order-2026-0001" \ -H "Content-Type: application/json" \ -d '{ "invoice_ref": "CAPTURE-JSON-1790961440", "route": "DE-XRECHNUNG", "environment": "sandbox", "document": { "lang": "de", "country": "DE", "invoice": { "number": "DOC-mux3dlqm", "issue_date": "2026-09-26", "due_date": "2026-10-10", "type_code": 380, "currency": "EUR", "buyer_reference": "PO-88731", "period": { "start": "2026-09-01", "end": "2026-09-30" }, "notes": [ "Vielen Dank für Ihren Auftrag." ] }, "seller": { "name": "Nordlicht Software GmbH", "address": { "street": "Hafenstraße 12", "city": "Hamburg", "postcode": "20457", "country": "DE" }, "vat_id": "DE938296582", "tax_number": "27/123/45678", "company_id": "HRB 123456", "register": "Amtsgericht Hamburg HRB 123456", "managing_directors": "Geschäftsführer: Jana Petersen", "legal_info": "GmbH", "endpoint": { "id": "DE938296582", "scheme": "9930" }, "contact": { "name": "Jana Petersen", "email": "[email protected]", "phone": "+49 40 1234567" }, "brand_color": "#1160FF", "accent_color": "#FF9021" }, "buyer": { "name": "Brauhaus Weber AG", "address": { "street": "Marienplatz 4", "city": "München", "postcode": "80331", "country": "DE" }, "vat_id": "DE965003781", "endpoint": { "id": "DE965003781", "scheme": "9930" } }, "lines": [ { "name": "E-Rechnung Einführung (Festpreis)", "description": "Mapping Business Central → EN 16931, Validierung XRechnung, Test im Peppol-Testnetz", "quantity": 1, "unit": "LS", "unit_price": 5900, "vat_category": "S", "vat_rate": 19 }, { "name": "Betreuung abgelehnter Rechnungen", "description": "Care Plus, September 2026", "quantity": 1, "unit": "MON", "unit_price": 349, "vat_category": "S", "vat_rate": 19 }, { "name": "Zusätzliche Schulung", "description": "Remote, Buchhaltungsteam", "quantity": 3, "unit": "HUR", "unit_price": 120, "vat_category": "S", "vat_rate": 19 } ], "payment": { "means_code": 58, "iban": "DE89 3704 0044 0532 0130 00", "bic": "COBADEFFXXX", "reference": "RE-2026-0143", "terms": "Zahlbar innerhalb von 14 Tagen ohne Abzug." }, "profile": "xrechnung" } }'{ "links": { "self": "/invoices/inv_936a93e38de84e7b0a1d7681", "events": "/invoices/inv_936a93e38de84e7b0a1d7681/events" }, "id": "inv_936a93e38de84e7b0a1d7681", "state": "queued"}Lister et rechercher des factures GET
Une clé de client voit les factures de son propre client ; l’opérateur voit celles de tous les clients, ou celles d’un seul avec client. Les lignes portent ce que porte GET /invoices/{id}, sans documents, et aucun contenu de facture : ni acheteur ni montants, ni date d’émission (pour la Roumanie et la Pologne, le deadline_at en découle, à quelques jours près). Un paramètre inconnu répond 400.
Soumettre un document UBL ou CII fini (transmission directe) POST
Pour les ERP qui écrivent déjà de l’UBL ou du CII, ou du FA(3) pour le canal KSeF. Aucun mapping n’a lieu : le service exécute les validateurs officiels du canal (pour FA(3) : le XSD plus les règles de fichier et de date de KSeF) et envoie le fichier tel quel. Un PDF Factur-X ou ZUGFeRD passe par le même point d’accès comme application/pdf. Le XML est analysé sans entités, sans DTD et sans accès réseau, et un fichier avec un DOCTYPE est refusé (EI-XML-DTD) avant qu’un validateur ne le lise, tout comme un fichier mal formé (EI-XML-SYNTAX) ou qui n’est pas une facture connue du canal (EI-XML-TYPE). Depuis la 0.18.4, le même fichier renvoyé pour le client et le canal est la facture déjà détenue (duplicate_of), comme sur POST /invoices ; rien de nouveau n’est envoyé.