3 API3.2
Podanie JSON: POST /invoices
Kanonický JSON alebo export z ERP.
- V sandboxe
Jednoducho povedané
Toto volanie podá faktúru: ak prejde všetkými kontrolami, služba ju zaradí do frontu, a ak nie, odpoveď pomenuje pole, ktoré neprešlo, a nič sa do frontu nezaradí.
POST /invoices skontroluje faktúru ako skúšobný beh. Ak prejde, služba ju zaradí do frontu a odpovie 202 s ID. Ak kontrola zlyhá, odpoveď je 422 a nič sa do frontu nezaradí. Volanie vyžaduje kľúč s oprávnením submit a Idempotency-Key.
Požiadavka
| Časť | Význam |
|---|---|
Hlavička Idempotency-Key | Povinná, 8 až 100 znakov. |
invoice_ref | Povinné. Vlastné ID dokladu v ERP, najviac 100 znakov. |
route | Voliteľné. Jeden z piatich kanálov. Ak ho vynecháte, služba ho zvolí z faktúry (krajiny predávajúceho a kupujúceho, profil a uložené prístupové údaje klienta). Ak nevyhovuje žiadne pravidlo, odpoveď je 422, EI-ROUTE-UNDECIDED alebo EI-ROUTE-PEPPOL-UNKNOWN. |
document | Jedna faktúra v kanonickom modeli. Pošlite toto alebo export s connector, nie oboje. |
export, connector | Export z ERP tak, ako ho ERP napísalo, s connector nastaveným na business-central alebo sap-b1. Služba ho namapuje živou verziou mapovania konektora alebo verziou mapping_version, ktorú uvediete (pozri verzie mapovania). Zistenie v mapovaní odpovie 422 a pomenuje pole ERP. Export sa uchová s faktúrou. |
formats | Voliteľné. Uveďte najviac jeden: dokument, ktorý sa zostaví, skontroluje a odošle. |
environment | Voliteľné. Ak ho pošlete, musí zodpovedať prostrediu vášho kľúča, inak je odpoveď 400. |
client | Voliteľné. Kľúč klienta ho môže vynechať alebo uviesť vlastného klienta; ktorýkoľvek iný klient odpovie 403. Limity sietí sa počítajú pre každého klienta zvlášť (pozri limity). |
Telo je obmedzené na 5 MB. V produkcii sa export číta, len keď nastavenia konektora klienta obsahujú vlastné údaje predávajúceho a platobné údaje klienta; bez nich je odpoveď 422, connector-settings-missing, a pomenuje, čo chýba. Sandbox ho číta s príkladovými údajmi konektora.
Prijatá faktúra
Vzorka je submit-de.json. Location obsahuje URL faktúry a links odkazuje na faktúru a jej udalosti. Stav je queued: nič nebolo odoslané.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-2026-0001" \
--data-binary @submit-de.jsonimport 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"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.header("Idempotency-Key", "order-2026-0001")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("submit-de.json")))
.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', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
'Idempotency-Key': 'order-2026-0001',
},
body: await readFile('submit-de.json'),
});
console.log(response.status);
console.log(await response.text());{
"links": {
"self": "/invoices/inv_936a93e38de84e7b0a1d7681",
"events": "/invoices/inv_936a93e38de84e7b0a1d7681/events"
},
"id": "inv_936a93e38de84e7b0a1d7681",
"state": "queued"
}Faktúra, ktorá neprejde kontrolou
To isté volanie s odstráneným názvom predávajúceho, submit-de-missing-seller-name.json. Odpoveď je dokument s popisom problému a zoznamom errors. Každá chyba je zistenie ako tie v protokole zo skúšobného behu. Zvýraznené riadky sú kód a pole, ktoré treba opraviť.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-2026-0002" \
--data-binary @submit-de-missing-seller-name.jsonimport 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"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.header("Idempotency-Key", "order-2026-0002")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("submit-de-missing-seller-name.json")))
.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', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
'Idempotency-Key': 'order-2026-0002',
},
body: await readFile('submit-de-missing-seller-name.json'),
});
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-SCHEMA",
"field": "seller.name",
"related": [
{
"code": "Art.226(5)",
"source": "pre-check"
}
],
"fix_hint": "Read the JSON path in the error and correct the client mapping.",
"who_fixes": "us",
"source": "schema",
"message": "We could not read this invoice from your export. We are correcting our mapping; if a field is missing in the ERP we will tell you which one."
},
{
"code": "Art.226(5)",
"field": "seller.name",
"related": [
{
"code": "EI-SCHEMA",
"source": "schema"
}
],
"fix_hint": "Complete the party's name and address in the master data.",
"who_fixes": "erp",
"source": "pre-check",
"message": "A company name or street address is missing. Complete the company or customer record in the ERP."
}
],
"status": 422
}Idempotencia
- Rovnaký kľúč s rovnakým telom vráti znova prvú odpoveď s rovnakým ID.
- Rovnaký kľúč s iným telom vráti
409. - Medzi uložené odpovede patrí aj
422. Opravenú faktúru pošlite s novým kľúčom. - Uložená odpoveď sa uchováva tak dlho, ako sa uchovávajú údaje klienta.
- Druhá požiadavka s kľúčom, ktorého prvá požiadavka ešte beží, dostane
409,request-in-progress. Kľúč, ktorého požiadavka nikdy neodpovedala, pretože sa server zastavil, sa uvoľní po 15 minútach.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-2026-0001" \
--data-binary @submit-de.jsonimport 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"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.header("Idempotency-Key", "order-2026-0001")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("submit-de.json")))
.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', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
'Idempotency-Key': 'order-2026-0001',
},
body: await readFile('submit-de.json'),
});
console.log(response.status);
console.log(await response.text());{
"links": {
"self": "/invoices/inv_936a93e38de84e7b0a1d7681",
"events": "/invoices/inv_936a93e38de84e7b0a1d7681/events"
},
"id": "inv_936a93e38de84e7b0a1d7681",
"state": "queued"
}curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-2026-0001" \
--data-binary @submit-de-changed.jsonimport 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"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.header("Idempotency-Key", "order-2026-0001")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("submit-de-changed.json")))
.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', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
'Idempotency-Key': 'order-2026-0001',
},
body: await readFile('submit-de-changed.json'),
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/idempotency-conflict",
"title": "This Idempotency-Key was already used with a different body",
"status": 409
}Dokument, ktorý ste už poslali
Dokument zhodný s dokumentom aktívnej faktúry pre toho istého klienta a kanál sa pod novým kľúčom prijme znova. Odpoveď obsahuje duplicate_of, ID prvej faktúry, a nič nové sa do frontu nezaradí.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/invoices" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-2026-0003" \
--data-binary @submit-de.jsonimport 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"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.header("Idempotency-Key", "order-2026-0003")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("submit-de.json")))
.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', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
'Idempotency-Key': 'order-2026-0003',
},
body: await readFile('submit-de.json'),
});
console.log(response.status);
console.log(await response.text());{
"links": {
"self": "/invoices/inv_936a93e38de84e7b0a1d7681",
"events": "/invoices/inv_936a93e38de84e7b0a1d7681/events"
},
"id": "inv_936a93e38de84e7b0a1d7681",
"state": "queued",
"duplicate_of": "inv_936a93e38de84e7b0a1d7681"
}Odpovede
| Stav | Význam |
|---|---|
202 | Prijatá a zaradená do frontu alebo duplikát aktívnej faktúry. |
400 | Telo nie je platný JSON, niektoré pole je nesprávne alebo Idempotency-Key chýba či nemá 8 až 100 znakov. |
401 | Chýba kľúč alebo je neznámy. |
403 | Kľúču chýba oprávnenie submit alebo uvádza iného klienta (forbidden). |
409 | Kľúč bol použitý s iným telom (idempotency-conflict) alebo jeho prvá požiadavka ešte beží (request-in-progress). |
413 | Telo má viac ako 5 MB (payload-too-large). |
422 | Faktúra neprešla kontrolou. errors uvádza, čo je zle a kto to opraví. |
429 | Príliš veľa požiadaviek pre kľúč. Počkajte Retry-After sekúnd. |
503 | Iná požiadavka na ten istý dokument sa ešte ukladá (busy). Nič sa nezapísalo a kľúč sa dá použiť znova. Skúste znova po Retry-After sekundách. |
Varovanie
Po 202 už faktúru nikdy znova neposielate. Chyby na strane siete, ktoré sa môžu pominúť, opakujeme podľa nášho plánu a trvalé odmietnutie ide do zoznamu na riešenie.