3 API3.3
Predaja XML-a: POST /invoices/xml
XML u formatu UBL, CII ili FA(3).
- U sandboxu
Jednostavnim riječima
Ovaj poziv predaje račun koji već postoji kao gotova XML datoteka. Prolazi sigurnosnu provjeru i vlastite validatore kanala te ide u red čekanja ako prođe.
POST /invoices/xml prima gotovu datoteku u formatu UBL, CII ili FA(3). Mapiranje se ne provodi. Usluga provjerava sigurnost i vrstu datoteke, izvodi službene validatore za kanal, a zatim je stavlja u red čekanja i šalje nepromijenjenu. Za FA(3) provjere su shema te pravila KSeF-a za datoteke i datume.
Napomena
Odgovor 202 znači da je datoteka prošla sigurnosnu provjeru i da je u redu čekanja. Da biste datoteku provjerili prije slanja, pošaljite račun kao JSON na POST /validate.
Zahtjev
| Dio | Značenje |
|---|---|
Parametar upita route | Obavezno. Jedan od pet kanala slanja. |
Parametar upita invoice_ref | Obavezno. Vlastiti ID dokumenta u ERP-u, do 100 znakova. |
Parametar upita client | Neobavezno. Vlastiti ključ klijenta može ga izostaviti ili navesti vlastitog klijenta. |
Zaglavlje Idempotency-Key | Obavezno, od 8 do 100 znakova. |
Zaglavlje Content-Type | application/xml ili text/xml. application/pdf sprema se i stavlja u red čekanja na isti način. |
Koje datoteke prima pojedini kanal:
| Kanal | Prima |
|---|---|
DE-XRECHNUNG | UBL, CII |
FR-PA | UBL, CII |
PEPPOL | UBL |
RO-EFACTURA | UBL |
PL-KSEF | FA(3) |
Prihvaćena datoteka
Primjer je fa3-pl-ksef.xml, poljska datoteka FA(3) s izmišljenim stranama. Stanje je 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"
}Datoteka poslana dvaput
Ista datoteka poslana ponovno za istog klijenta i isti kanal jest račun koji već imamo. Odgovor sadrži duplicate_of, ID prvog računa, i ništa se novo ne šalje. Predaja koja je završila u stanju rejected, validation_failed ili cancelled ne računa se, pa se datoteka može poslati ponovno.
Odbijene datoteke
XML koji je ispravno oblikovan, ali nije račun, dobiva 422 s 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
}Datoteka s DOCTYPE dobiva 422 s EI-XML-DTD, prije nego što je ijedan validator pročita. Datoteka koja nije ispravno oblikovana dobiva 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
}Vrsta sadržaja koja nije XML ni PDF dobiva 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
}Idempotency-Key koji nedostaje ili je prekratak dobiva 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
}Odgovori
| Status | Značenje |
|---|---|
202 | Prihvaćeno i stavljeno u red čekanja. Location sadrži URL računa. |
400 | Parametar upita ili Idempotency-Key nedostaje ili nije ispravan. |
401 | Nema ključa ili je ključ nepoznat. |
403 | Ključ nema opseg submit ili navodi drugog klijenta (forbidden). |
409 | Ključ je upotrijebljen s drugačijim tijelom (idempotency-conflict) ili je njegov prvi zahtjev još u tijeku (request-in-progress). |
413 | Tijelo je veće od 5 MB (payload-too-large). |
415 | Vrsta sadržaja nije XML ni PDF (unsupported-media). |
422 | Odbijena datoteka: EI-XML-DTD, EI-XML-SYNTAX ili EI-XML-TYPE. |
429 | Previše zahtjeva za ključ. Pričekajte onoliko sekundi koliko navodi Retry-After. |
503 | Drugi zahtjev za isti dokument još se sprema (busy). Pokušajte ponovno nakon onoliko sekundi koliko navodi Retry-After. |