3 API3.3
XML übermitteln: POST /invoices/xml
UBL-, CII- oder FA(3)-XML.
- In der Sandbox
In einfachen Worten
Dieser Aufruf übermittelt eine Rechnung, die schon als fertige XML-Datei vorliegt. Sie erhält eine Sicherheitsprüfung und die eigenen Validatoren des Übermittlungswegs und geht in die Warteschlange, wenn sie besteht.
POST /invoices/xml nimmt eine fertige UBL-, CII- oder FA(3)-Datei an. Es findet kein Mapping statt. Der Service prüft die Datei auf Sicherheit und Typ, lässt die offiziellen Validatoren des Übermittlungswegs laufen, reiht sie dann ein und sendet sie unverändert. Bei FA(3) sind die Prüfungen das Schema plus die Datei- und Datumsregeln von KSeF.
Hinweis
Ein 202 bedeutet, dass die Datei die Sicherheitsprüfung bestanden hat und eingereiht ist. Um eine Datei vor dem Senden zu prüfen, senden Sie die Rechnung als JSON an POST /validate.
Die Anfrage
| Teil | Bedeutung |
|---|---|
Query-Parameter route | Pflicht. Einer der fünf Übermittlungswege. |
Query-Parameter invoice_ref | Pflicht. Die eigene Beleg-ID des ERP, bis zu 100 Zeichen. |
Query-Parameter client | Optional. Ein Kundenschlüssel darf ihn weglassen oder seinen eigenen Kunden nennen. |
Header Idempotency-Key | Pflicht, 8 bis 100 Zeichen. |
Header Content-Type | application/xml oder text/xml. application/pdf wird auf dieselbe Weise gespeichert und eingereiht. |
Welche Datei jeder Übermittlungsweg annimmt:
| Übermittlungsweg | Nimmt an |
|---|---|
DE-XRECHNUNG | UBL, CII |
FR-PA | UBL, CII |
PEPPOL | UBL |
RO-EFACTURA | UBL |
PL-KSEF | FA(3) |
Eine angenommene Datei
Das Beispiel ist fa3-pl-ksef.xml, eine polnische FA(3)-Datei mit erfundenen Beteiligten. Der Zustand ist queued.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PL-KSEF&invoice_ref=INV-2026-0042" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: order-2026-0042" \
--data-binary @fa3-pl-ksef.xmlimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PL-KSEF&invoice_ref=INV-2026-0042"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/xml")
.header("Idempotency-Key", "order-2026-0042")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("fa3-pl-ksef.xml")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PL-KSEF&invoice_ref=INV-2026-0042', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/xml',
'Idempotency-Key': 'order-2026-0042',
},
body: await readFile('fa3-pl-ksef.xml'),
});
console.log(response.status);
console.log(await response.text());{
"links": {
"self": "/invoices/inv_d249e33382ce2911876b7295",
"events": "/invoices/inv_d249e33382ce2911876b7295/events"
},
"id": "inv_d249e33382ce2911876b7295",
"state": "queued"
}Eine Datei, die zweimal gesendet wurde
Dieselbe Datei, die für denselben Kunden und Übermittlungsweg erneut gesendet wird, ist die Rechnung, die bereits vorliegt. Die Antwort enthält duplicate_of, die ID der ersten Rechnung, und nichts Neues wird gesendet. Eine Übermittlung, die mit rejected, validation_failed oder cancelled endete, zählt nicht, die Datei kann also erneut gesendet werden.
Abgewiesene Dateien
XML, das wohlgeformt, aber keine Rechnung ist, erhält 422 mit EI-XML-TYPE.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0051" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: order-2026-0051" \
--data-binary @not-an-invoice.xmlimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0051"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/xml")
.header("Idempotency-Key", "order-2026-0051")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("not-an-invoice.xml")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0051', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/xml',
'Idempotency-Key': 'order-2026-0051',
},
body: await readFile('not-an-invoice.xml'),
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/validation-failed",
"title": "The invoice did not pass the checks",
"errors": [
{
"code": "EI-XML-TYPE",
"fix_hint": "Send the invoice itself, in the format agreed for the route.",
"who_fixes": "erp",
"source": "XML-safety",
"message": "The file is not an invoice in a format this route accepts. Please send the invoice in the agreed format."
}
],
"status": 422
}Eine Datei mit einem DOCTYPE erhält 422 mit EI-XML-DTD, bevor irgendein Validator sie liest. Eine Datei, die nicht wohlgeformt ist, erhält EI-XML-SYNTAX.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0052" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/xml" \
-H "Idempotency-Key: order-2026-0052" \
--data-binary @with-doctype.xmlimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0052"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/xml")
.header("Idempotency-Key", "order-2026-0052")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("with-doctype.xml")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0052', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/xml',
'Idempotency-Key': 'order-2026-0052',
},
body: await readFile('with-doctype.xml'),
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/validation-failed",
"title": "The invoice did not pass the checks",
"errors": [
{
"code": "EI-XML-DTD",
"fix_hint": "Export the invoice without the DOCTYPE line. If the ERP adds one on purpose, raise it with the ERP vendor: no e-invoicing format uses it.",
"who_fixes": "erp",
"source": "XML-safety",
"message": "The invoice file contains a DOCTYPE declaration, which e-invoices never use, so we refused it for security before reading it. Export it again without the DOCTYPE line."
}
],
"status": 422
}Ein Inhaltstyp, der weder XML noch PDF ist, erhält 415.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0053" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: text/plain" \
-H "Idempotency-Key: order-2026-0053" \
--data-binary @hello.txtimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0053"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "text/plain")
.header("Idempotency-Key", "order-2026-0053")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("hello.txt")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0053', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'text/plain',
'Idempotency-Key': 'order-2026-0053',
},
body: await readFile('hello.txt'),
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/unsupported-media",
"title": "Not UBL, CII or FA(3)",
"status": 415
}Ein fehlender oder zu kurzer Idempotency-Key erhält 400.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0054" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/xml" \
--data-binary @ubl-peppol.xmlimport java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.file.Path;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0054"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/xml")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("ubl-peppol.xml")))
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}import { readFile } from 'node:fs/promises';
const response = await fetch('https://api-sandbox-eu.eurinvoice.com/invoices/xml?route=PEPPOL&invoice_ref=INV-2026-0054', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/xml',
},
body: await readFile('ubl-peppol.xml'),
});
console.log(response.status);
console.log(await response.text());{
"detail": "Idempotency-Key must be between 8 and 100 characters.",
"type": "https://eurinvoice.com/problems/bad-request",
"title": "The request could not be read",
"status": 400
}Antworten
| Status | Bedeutung |
|---|---|
202 | Angenommen und eingereiht. Location enthält die URL der Rechnung. |
400 | Ein Query-Parameter oder der Idempotency-Key fehlt oder ist falsch. |
401 | Kein Schlüssel oder ein unbekannter Schlüssel. |
403 | Dem Schlüssel fehlt der Scope submit, oder er nennt einen anderen Kunden (forbidden). |
409 | Der Schlüssel wurde mit einem anderen Body verwendet (idempotency-conflict), oder seine erste Anfrage läuft noch (request-in-progress). |
413 | Der Body ist größer als 5 MB (payload-too-large). |
415 | Der Inhaltstyp ist weder XML noch PDF (unsupported-media). |
422 | Eine abgewiesene Datei: EI-XML-DTD, EI-XML-SYNTAX oder EI-XML-TYPE. |
429 | Zu viele Anfragen für den Schlüssel. Warten Sie Retry-After Sekunden. |
503 | Eine andere Anfrage für dasselbe Dokument wird noch gespeichert (busy). Versuchen Sie es nach Retry-After Sekunden erneut. |