Docs

Remettre une facture que le client a reçue par un canal

  • Dans le bac à sable
POST
/received

Depuis la 0.35.0 (17 oct. 2026). Le corps est le XML tel que le canal l’a livré (UBL, CII ou FA(3)) ; rien n’est modifié et rien n’est envoyé. Le fichier est d’abord stocké, scellé sous la clé de données du client, car en droit il est déjà reçu ; ensuite les validateurs propres au canal le contrôlent, comme pour un envoi en transmission directe, et le résultat arrive sous la forme d’un événement de statut (received, puis validated ou validation_failed, avec direction: in) sur le webhook du client et sur GET /received/{id}/events. Un fichier qui échoue aux règles est conservé et affiche validation_failed avec les erreurs ; il n’est jamais supprimé. Un fichier qui n’est pas une facture à conserver est refusé avec un 422 et rien n’est stocké, comme sur POST /invoices/xml : un DOCTYPE (EI-XML-DTD, jamais analysé), un XML mal formé (EI-XML-SYNTAX), ou un document qui n’est pas une facture connue du canal (EI-XML-TYPE). Un contrôle qui n’a pas pu s’exécuter (validateur indisponible) est relancé, et après la dernière nouvelle tentative la facture passe sur la liste de suivi et reste received. Un client remet au plus 120 documents par minute et 2 000 par jour, quelle que soit la clé utilisée (429, non conservé sous l’Idempotency-Key). Le fichier est restitué en téléchargement (Content-Disposition: attachment).

Un document de canal correspond à une facture reçue pour le client : par rail_id quand il est fourni, par le SHA-256 du fichier sinon. Le même document renvoyé répond 202 avec duplicate_of ; le même rail_id avec d’autres octets répond 409 received-id-conflict, et rien n’est stocké. Les factures reçues sont tenues à part des factures que le client envoie : elles ne figurent ni dans GET /invoices, ni dans les séries, ni dans les métriques, ni dans le rapport mensuel, et elles ne bloquent jamais l’envoi du même fichier. Une facture reçue est supprimée avec la conservation du client dès que plus rien n’est ouvert sur elle (son contrôle est terminé, ou une personne a traité sa ligne de suivi), et figure dans l’export du client sous received/. Droit d’envoi (submit) ; une clé de client agit pour son propre client uniquement.

Autorisation

apiKey
headerAuthorizationBearer <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é.

Paramètres de requête

route*string

Le canal par lequel le document est arrivé.

Valeur parmi"PEPPOL""PL-KSEF""RO-EFACTURA""FR-PA""DE-XRECHNUNG"
rail_id?string

L’identifiant propre du canal pour le document (l’identifiant de document du point d’accès, le numéro KSeF, l’identifiant de téléchargement d’ANAF). De 1 à 200 lettres, chiffres et . _ : / @ + = # -.

Motif^[A-Za-z0-9._:/@+=#-]{1,200}$
client?string

Le client qui l’a reçu. La clé de l’opérateur le désigne (omis, c’est le client local propre à l’opérateur) ; une clé de client peut l’omettre ou nommer son propre client, et tout autre répond 403.

Motif^[A-Za-z0-9][A-Za-z0-9._-]{0,63}$

Paramètres d’en-tête

Idempotency-Key*string

Une clé unique par requête logique (un UUID convient). Une clé qui commence par erp: (erp:{connector}:{scope}:{entity}:{id} d’une recette de transport ERP, avec la clé de l’opérateur ou celle d’un client) n’a pas de fenêtre ; elle est conservée avec sa première réponse jusqu’à la suppression du client, ou de la facture qu’elle a produite, de sorte qu’un document modifié et remis des semaines plus tard reçoit encore 409 idempotency-conflict. Une telle clé n’est acceptée que sur un export de connecteur ERP (POST /invoices avec un connector que cette version lit, un export qui est un objet JSON non vide, et avec la clé de l’opérateur client) ; sur toute autre requête, un document canonique, POST /invoices/xml ou une annulation, elle répond 400 idempotency-key-not-allowed et rien n’est conservé, et un export contenant un nombre de plus de 40 caractères reçoit le 422 EI-SCHEMA qu’il reçoit sous n’importe quelle autre clé, lui aussi conservé sous aucune clé. Quand l’opérateur libère un échec définitif (l’annule), les réponses antérieures sur cette facture partent avec lui, celle de la soumission et, depuis la 0.35.0, celle d’une annulation refusée antérieure, de sorte qu’une nouvelle tentative de cette annulation s’exécute à nouveau et répond 200 avec la facture annulée. Depuis la 0.32.0, une réponse 5xx et un 422 connector-settings-missing ne sont pas conservés, de sorte que la même requête avec la même clé peut être renvoyée. 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.

Longueur8 <= length <= 100

Corps de la requête

body*stringapplication/xml

Corps de la réponse

Stocké et mis en file pour le contrôle du canal, sauf s’il a déjà échoué ; ou déjà conservé (duplicate_of).

application/json
  1. response

Depuis la 0.35.0. Une facture que le client a reçue par un canal, telle que POST /received l’a prise. Comme Invoice, elle ne porte aucun contenu de facture : ni vendeur, ni acheteur, ni montants.

id*string
Motif^rcv_[0-9a-f]{24}$
invoice_ref*string

Le numéro de facture propre au fichier (BT-1 ; FA(3) Fa/P_2), sinon le rail_id, sinon l’identifiant.

invoice_number?string
route*Route

Le canal du pays. Les mêmes valeurs que country_route dans les événements de statut.

Valeur parmi"PEPPOL""PL-KSEF""RO-EFACTURA""FR-PA""DE-XRECHNUNG"
client*string
environment*string
Valeur parmi"sandbox""production"
state*string
Valeur parmi"received""validated""validation_failed"
direction*"in"
Valeur parmi"in"
rail_id?string

L’identifiant propre du canal pour le document, tel que donné sur POST /received.

document_sha256*string
Motif^[a-f0-9]{64}$
duplicate_of?string

Uniquement sur POST /received, quand le document était déjà conservé pour le client et le canal.

links?
errors?array<>
documents?array<>
created_at*string
Formatdate-time
updated_at*string
Formatdate-time
curl -X POST "https://example.com/received?route=PEPPOL" \  -H "Authorization: Bearer <your-api-key>" \  -H "Idempotency-Key: order-2026-0001" \  -H "Content-Type: application/xml" \  -d 'string'
{  "id": "string",  "invoice_ref": "string",  "invoice_number": "string",  "route": "PEPPOL",  "client": "string",  "environment": "sandbox",  "state": "received",  "direction": "in",  "rail_id": "string",  "document_sha256": "string",  "duplicate_of": "string",  "links": {    "self": "string",    "events": "string"  },  "errors": [    {      "code": "string"    }  ],  "documents": [    {      "kind": "received-xml",      "sha256": "string",      "href": "string"    }  ],  "created_at": "2019-08-24T14:15:22Z",  "updated_at": "2019-08-24T14:15:22Z"}