Pristupni podaci za prijenosne sustave
Spremanje i zamjena klijentovih pristupnih podataka za prijenosne sustave.
- U sandboxuspremanje
- Još nije u sandboxuprijenosni sustavi
Jednostavnim riječima
Pristupni podaci za prijenosni sustav ključ su ili ovlaštenje koje nam omogućuje da u ime jednog klijenta postupamo u mreži ili kod tijela neke zemlje, primjerice token za poljski nacionalni sustav e-računa (KSeF). Klijent ih izdaje ili autorizira, a u eurinvoice unose se putem API-ja, nikad e-poštom ni chatom. Čuvamo ih šifrirane i nikad ih ponovno ne prikazujemo. Hostirani sandbox još ih ne sadrži, pa kanal slanja u njemu ništa ne šalje.
Pristupni podaci za prijenosni sustav omogućuju nam da u ime jednog klijenta postupamo na kanalu slanja: KSeF token, ovlaštenje za ANAF, ključ platforme. Unose se putem ovog API-ja, nikad e-poštom ni chatom. API ih čuva i nikad ih ne vraća. Za pozive je potreban ključ s opsegom admin, a klijentski ključ sprema pristupne podatke samo za vlastitog klijenta.
Kako se čuva vrijednost
Vrijednost se šifrira prije spremanja, čuva se odvojeno od ključa koji je štiti i nikad se ne prikazuje ponovno. Pristupni podaci otvaraju se samo kad bi usluga trebala pozvati kanal tog klijenta. Svaka upotreba zapisuje redak u revizijski zapis, bez vrijednosti.
Za pristupne podatke čiji expires_on pada za manje od 30 dana bilježi se upozorenje. Opoziv briše vrijednost i zadržava datume.
Polja
| Polje | Značenje |
|---|---|
client | Identifikator klijenta, isti onaj koji nosi račun: od 1 do 64 slova, znamenki, točaka, podvlaka ili crtica. Vlastiti ključ klijenta može ga izostaviti. |
route | DE-XRECHNUNG, PEPPOL, FR-PA, PL-KSEF ili RO-EFACTURA. |
kind | Imenuje pristupne podatke i određuje kako se čitaju, do 80 znakova (slova, znamenke, točke, podvlake i crtice): ksef-token za KSeF i anaf-oauth za ANAF. Za kanal Peppol ili Francusku vrstu i oblik vrijednosti navodimo vam pri početku uvođenja. |
issued_by | Tko ih je izdao, do 200 znakova. |
issued_on | Datum izdavanja, YYYY-MM-DD. |
expires_on | Neobavezno, YYYY-MM-DD. Postavite ga ako pristupni podaci istječu. |
environment | Neobavezno. Mora biti okruženje usluge koju pozivate; sandbox sprema samo sandbox pristupne podatke. |
legal_entity | Neobavezno, do 64 znaka. ID prodavatelja za kojeg pristupni podaci vrijede: PDV ID, NIP, SIREN ili ID tvrtke. Pristupni podaci bez njega služe ostalim računima klijenta. |
value | Tajna vrijednost, do 16.384 znaka. Obavezno i nikad se ne vraća. |
Usluga provjerava može li vrijednost raditi za svoju vrstu, na primjer je li KSeF token JSON s poljima nip i token. Vrijednost anaf-oauth je JSON tekst s poljem cui i ili poljem access_token, ili poljem refresh_token uz client_id i client_secret aplikacije. Vrijednost koja ne može daje odgovor 422, credential-unusable, a odgovor navodi koji se oblik očekuje, bez citiranja vrijednosti.
Odgovor sadrži id (cred_ i 24 heksadecimalna znaka), gornja polja osim value, stored (true dok se vrijednost čuva) i revoked_at nakon opoziva.
Klijent može imati jedne aktivne pristupne podatke za svaki kanal, kind, okruženje i pravni subjekt. Pozadinski proces za račun klijenta i kanal koristi najstarije pristupne podatke koji nisu opozvani.
Spremanje pristupnih podataka
POST /credentials prima gornja polja kao JSON i odgovara 201. Zahtjev je u datoteci credential-create.json.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @credential-create.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/credentials"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("credential-create.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/credentials', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('credential-create.json'),
});
console.log(response.status);
console.log(await response.text());{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"kind": "anaf-oauth",
"expires_on": "2027-09-01",
"stored": true,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}Ponovno spremanje istih pristupnih podataka dok su prvi aktivni daje odgovor 409.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @credential-create.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/credentials"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("credential-create.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/credentials', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('credential-create.json'),
});
console.log(response.status);
console.log(await response.text());{
"type": "https://eurinvoice.com/problems/credential-exists",
"title": "This client already has this credential",
"status": 409
}Popis i čitanje
GET /credentials vraća sve pristupne podatke, aktivne i opozvane, kao {"data": [...]}. GET /credentials/{id} vraća jedne, a za ID koji nema odgovara 404.
curl "https://api-sandbox-eu.eurinvoice.com/credentials" \
-H "Authorization: Bearer <your-api-key>"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials"))
.header("Authorization", "Bearer <your-api-key>")
.GET()
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials', {
headers: {
Authorization: 'Bearer <your-api-key>',
},
});
console.log(response.status);
console.log(await response.text());{
"data": [
{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"kind": "anaf-oauth",
"expires_on": "2027-09-01",
"stored": true,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}
]
}Zamjena
POST /credentials/{id} prima novi value i po želji novi expires_on. Klijent, kanal, vrsta i datum izdavanja ostaju. Koristite ga nakon osvježavanja tokena. Zahtjev je u datoteci credential-replace.json.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284" \
-H "Authorization: Bearer <your-api-key>" \
-H "Content-Type: application/json" \
--data-binary @credential-replace.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/credentials/cred_5bebc3172daf651a788e4284"))
.header("Authorization", "Bearer <your-api-key>")
.header("Content-Type", "application/json")
.POST(HttpRequest.BodyPublishers.ofFile(Path.of("credential-replace.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/credentials/cred_5bebc3172daf651a788e4284', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
'Content-Type': 'application/json',
},
body: await readFile('credential-replace.json'),
});
console.log(response.status);
console.log(await response.text());{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"kind": "anaf-oauth",
"expires_on": "2028-09-01",
"stored": true,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}Opoziv
POST /credentials/{id}/revoke briše vrijednost i upisuje revoked_at. Ponavljanje ništa ne mijenja.
curl -X POST "https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284/revoke" \
-H "Authorization: Bearer <your-api-key>"import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Example {
public static void main(String[] args) throws Exception {
HttpRequest request = HttpRequest.newBuilder(URI.create("https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284/revoke"))
.header("Authorization", "Bearer <your-api-key>")
.POST(HttpRequest.BodyPublishers.noBody())
.build();
HttpResponse<String> response = HttpClient.newHttpClient()
.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
System.out.println(response.body());
}
}const response = await fetch('https://api-sandbox-eu.eurinvoice.com/credentials/cred_5bebc3172daf651a788e4284/revoke', {
method: 'POST',
headers: {
Authorization: 'Bearer <your-api-key>',
},
});
console.log(response.status);
console.log(await response.text());{
"issued_by": "ANAF",
"environment": "sandbox",
"route": "RO-EFACTURA",
"revoked_at": "2026-10-06T19:49:12.987Z",
"kind": "anaf-oauth",
"expires_on": "2028-09-01",
"stored": false,
"client": "acme-srl",
"issued_on": "2026-09-01",
"id": "cred_5bebc3172daf651a788e4284"
}Upozorenje
Opozvani zapis ostaje, radi revizijskog traga. Ne može se zamijeniti: odgovor je 409, credential-revoked. Nove pristupne podatke spremite kao novi zapis. Opozvani pristupni podaci više ne sprječavaju ponovno spremanje za istog klijenta, kanal i vrstu.
Odgovori
| Status | Značenje |
|---|---|
200 | Popis, jedni pristupni podaci, zamjena ili opoziv. |
201 | Spremljeno. |
400 | Tijelo nije JSON, obavezno polje nedostaje ili je predugo, route nije jedan od pet kanala ili datum nije u obliku YYYY-MM-DD. |
401 | Nema ključa ili je ključ nepoznat. |
403 | Ključ nema opseg admin ili navodi drugog klijenta. |
404 | Nema takvih pristupnih podataka. |
409 | Klijent već ima te pristupne podatke (credential-exists) ili su pristupni podaci opozvani (credential-revoked). |
413 | Tijelo je veće od 5 MB (payload-too-large). |
422 | Vrijednost ne može raditi za ovu vrstu (credential-unusable). |
429 | Previše zahtjeva za ključ. Pričekajte onoliko sekundi koliko navodi Retry-After. |
503 | Usluga nema glavni ključ kojim bi šifrirala vrijednost (unavailable). |
Što traži pojedini kanal
U sandboxuiz službenih izvora, provjereno 2. lis. 2026.| Kanal | Klijent daje | Tko izdaje | Valjanost |
|---|---|---|---|
PL-KSEF | KSeF token koji može slati račune (InvoiceWrite) i, za statuse, čitati ih (InvoiceRead). Njegova se ovlaštenja utvrđuju pri izradi, pa je za promjenu potreban novi token. Prijava KSeF certifikatom još nije podržana. Spremanje pristupnih podataka ksef koji nisu ksef-token daje odgovor 422, credential-unusable. | Administrator KSeF-a kod klijenta. | Pogledajte napomenu u nastavku. |
RO-EFACTURA | OAuth ovlaštenje za našu registriranu ANAF aplikaciju. | Osoba sa SPV ovlastima za CUI klijenta: zakonski zastupnik ili računovođa. Na ANAF-ov portal prijavljuje se kvalificiranim certifikatom. | Pristupni token vrijedi 90 dana, a token za osvježavanje 365 dana. |
PEPPOL | Suglasnost za registraciju klijenta kao sudionika mreže Peppol i provjera identiteta koju traži pristupna točka. | Klijent potpisuje suglasnost i prolazi provjeru. Ključ pristupne točke držimo mi, pa nema klijentovih pristupnih podataka za spremanje. | Ključ pristupne točke je naš i mi ga rotiramo. |
FR-PA | Vlastiti korisnički profil klijenta na njegovoj platformi Plateforme Agréée i API pristupni podaci za tvrtku. | Klijent ih izrađuje na svojoj platformi ili nam daje pristup. | Određuje platforma. Pitajte koju vrstu izdaje. |
DE-XRECHNUNG | Ništa za samu Njemačku. Pri slanju e-poštom: poštanski sandučić s kojeg se šalje. Pri slanju putem mreže Peppol: registracija kod pristupne točke. | Klijent. | Nije primjenjivo. |
Savjet
Postavite expires_on prema gornjim rokovima kako bi se upozorenje 30 dana unaprijed pokrenulo prije nego što token za osvježavanje istekne.
Izvori: ANAF-ov postupak za OAuth (trajanje tokena), dokumentacija API-ja KSeF: tokeni (ovlaštenja se utvrđuju pri izradi tokena).
Upozorenje
Poljska: izvori se ne slažu o tome koliko dugo KSeF token vrijedi. Priručnik Ministarstva financija (izdanje od 9. velj. 2026.) i stranica aplikacije za porezne obveznike (izmijenjena 31. ožu. 2026.) navode da tokeni služe za autentifikaciju do 31. pro. 2026. Stranica Ministarstva s pitanjima i odgovorima navodi da je Ministarstvo odlučilo zadržati tokene u KSeF 2.0 bez datuma isteka (odgovor 39). Javni zahtjev (issue) u repozitoriju Ministarstva za KSeF API traži da Ministarstvo razriješi tu razliku. Provjereno 2. lis. 2026. Dok se to ne razriješi, računajte da ćete token morati obnoviti ako Ministarstvo odredi datum isteka. Prijava certifikatom još nije podržana, pa je token jedini put do KSeF-a. Pogledajte priručnik, pitanja i odgovore i zahtjev.