Submit a finished UBL or CII document (pass-through)
- In the sandbox
In plain words
For ERPs that already write UBL or CII, or FA(3) for the KSeF route. No mapping happens: the service runs
the official validators for the route (for FA(3): the XSD plus KSeF's file and date rules) and sends the
file unchanged. A Factur-X or ZUGFeRD PDF goes through the same endpoint
as application/pdf. The XML is parsed with entities, DTDs and network access off, and a file with a
DOCTYPE is refused (EI-XML-DTD) before any validator reads it, as is a file that is not well-formed
(EI-XML-SYNTAX) or not an invoice the route knows (EI-XML-TYPE). Since 0.18.4 the same file sent again for
the client and route is the invoice already held (duplicate_of), as on POST /invoices; nothing new is sent.
apiKeyAuthorizationBearer <token>Send your key as a bearer token: Authorization: Bearer <your-api-key>. Health is the only call that needs no key.
route*stringThe country route. The same values as country_route in status events.
"PEPPOL""PL-KSEF""RO-EFACTURA""FR-PA""DE-XRECHNUNG"invoice_ref*stringThe ERP's own document ID.
length <= 100Idempotency-Key*stringA unique key per logical request (a UUID is fine). Kept for as long as the client's data is kept. With the operator's key it may not begin with client: (400), the form client keys are stored under.
8 <= length <= 100body*stringAccepted for processing.
application/json- response
id*stringstate*InvoiceStateThe service's own state for an invoice. Status events report the partner-facing lifecycle;
queued and submitting are internal steps between validated and submitted. validation_failed means the official rules refused the document; since
0.18.4 a check that did not run (KOSIT-RUN, EI-PDF-CHECK) retries instead, then ends dead_letter with that
code. A dead_letter keeps its document held, so the same file answers with duplicate_of; since 0.18.6 the
operator can cancel one for which no call to the route was made, and then the file can go again.
"received""source_error""validated""validation_failed""queued""submitting""submitted""ready""accepted""rejected""delivered""cancelled""dead_letter"duplicate_of?|Set when the same document was already accepted for this client and route; nothing new is sent. A submission that ended rejected, validation_failed or cancelled does not count, so the file can be sent again. Since 0.18.5 this holds for two requests sent at the same moment too, under different keys; one makes the invoice and the other answers with duplicate_of.
links*route?RouteOnly when the router chose the route.
"PEPPOL""PL-KSEF""RO-EFACTURA""FR-PA""DE-XRECHNUNG"route_chosen_by?"router"Only when the request left out the route.
"router"route_rule?stringThe router's rule that chose the route; also written to the audit log as 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/xml?route=PL-KSEF&invoice_ref=INV-2026-0042" \ -H "Authorization: Bearer <your-api-key>" \ -H "Idempotency-Key: order-2026-0001" \ -H "Content-Type: application/xml" \ -d '<?xml version="1.0" encoding="UTF-8"?><Faktura xmlns="http://crd.gov.pl/wzor/2025/06/25/13775/"><Naglowek><KodFormularza kodSystemowy="FA (3)" wersjaSchemy="1-0E">FA</KodFormularza><WariantFormularza>3</WariantFormularza><DataWytworzeniaFa>2026-10-01T05:44:07Z</DataWytworzeniaFa><SystemInfo>eurinvoice</SystemInfo></Naglowek><Podmiot1><DaneIdentyfikacyjne><NIP>1234567890</NIP><Nazwa>Wisła Systemy sp. z o.o.</Nazwa></DaneIdentyfikacyjne><Adres><KodKraju>PL</KodKraju><AdresL1>ul. Floriańska 22</AdresL1><AdresL2>31-019 Kraków</AdresL2></Adres><DaneKontaktowe><Email>faktury@wisla.example</Email><Telefon>+48 12 345 67 89</Telefon></DaneKontaktowe></Podmiot1><Podmiot2><DaneIdentyfikacyjne><NIP>5213000000</NIP><Nazwa>Mazowiecka Hurtownia S.A.</Nazwa></DaneIdentyfikacyjne><Adres><KodKraju>PL</KodKraju><AdresL1>al. Jerozolimskie 100</AdresL1><AdresL2>00-807 Warszawa</AdresL2></Adres><JST>2</JST><GV>2</GV></Podmiot2><Fa><KodWaluty>PLN</KodWaluty><P_1>2026-09-26</P_1><P_1M>Kraków</P_1M><P_2>FV/2026/09/057</P_2><P_6>2026-09-25</P_6><P_13_1>25450.00</P_13_1><P_14_1>5853.50</P_14_1><P_15>31303.50</P_15><Adnotacje><P_16>2</P_16><P_17>2</P_17><P_18>2</P_18><P_18A>2</P_18A><Zwolnienie><P_19N>1</P_19N></Zwolnienie><NoweSrodkiTransportu><P_22N>1</P_22N></NoweSrodkiTransportu><P_23>2</P_23><PMarzy><P_PMarzyN>1</P_PMarzyN></PMarzy></Adnotacje><RodzajFaktury>VAT</RodzajFaktury><FaWiersz><NrWierszaFa>1</NrWierszaFa><P_7>Wdrożenie KSeF 2.0</P_7><P_8A>LS</P_8A><P_8B>1</P_8B><P_9A>24000.00</P_9A><P_11>24000.00</P_11><P_12>23</P_12></FaWiersz><FaWiersz><NrWierszaFa>2</NrWierszaFa><P_7>Obsługa odrzuconych faktur</P_7><P_8A>MON</P_8A><P_8B>1</P_8B><P_9A>1450.00</P_9A><P_11>1450.00</P_11><P_12>23</P_12></FaWiersz><Platnosc><TerminPlatnosci><Termin>2026-10-10</Termin></TerminPlatnosci><FormaPlatnosci>6</FormaPlatnosci><RachunekBankowy><NrRB>61109010140000071219812874</NrRB><SWIFT>WBKPPLPP</SWIFT></RachunekBankowy></Platnosc><WarunkiTransakcji><Zamowienia><DataZamowienia>2026-09-26</DataZamowienia><NrZamowienia>ZAM-2026-311</NrZamowienia></Zamowienia></WarunkiTransakcji></Fa><Stopka><Rejestry><PelnaNazwa>Wisła Systemy sp. z o.o.</PelnaNazwa><KRS>0000123456</KRS></Rejestry></Stopka></Faktura>'{ "links": { "self": "/invoices/inv_d249e33382ce2911876b7295", "events": "/invoices/inv_d249e33382ce2911876b7295/events" }, "id": "inv_d249e33382ce2911876b7295", "state": "queued"}Submit an invoice or credit note as canonical JSON POST
The service checks the document against the canonical model and the pre-checks at once, and answers 422 if either fails. Everything after that runs asynchronously (build, official validation, route submission, statuses) and is reported through status events. A corrected resubmission of a rejected invoice uses the same invoice_ref and a new Idempotency-Key; the service links the attempts. In production an ERP export is read only when the client's connector settings hold its own seller and payment, not the mapping's example: otherwise 422 connector-settings-missing, naming what is missing. A sandbox reads it with the example, as before.
Look up an error or reason code GET
Returns the catalogue entry for a rule ID, route error code or French reason code (IDs and aliases).