Ako to funguje

Tri základné scenáre použitia SAPI rozhrania.

1 Odosielanie faktúry

Váš ERPPOST /auth/tokenePošťák AP
Váš ERPJWT tokenePošťák AP
Váš ERPPOST /document/sendePošťák APAS4Prijímateľ

2 Prijímanie faktúry

OdosielateľAS4ePošťák AP
uloží dokument
Váš ERPGET /document/receiveePošťák AP
Váš ERPPOST .../acknowledgeePošťák AP

3 Životný cyklus tokenu

1
POST /api/auth/token
Získate access_token 15 min a refresh_token 30 dní
2
POST /api/auth/renew
Keď access_token expiruje, vymeňte refresh_token za nový pár (token rotation)
3
POST /api/auth/revoke
Na konci zneplatnite refresh_token (napr. pri odhlásení)

Rýchly štart

Za 2 minúty odošlite prvú faktúru.

1

Použite sandbox credentials

2

Získajte token

curl -X POST https://epostak.sk/api/auth/token \
  -H "Content-Type: application/json" \
  -d '{"client_id":"test_98b486a08b3e3d7f","client_secret":"sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6","grant_type":"client_credentials"}'
import requests

resp = requests.post("https://epostak.sk/api/auth/token", json={
    "client_id": "test_98b486a08b3e3d7f",
    "client_secret": "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6",
    "grant_type": "client_credentials"
})
token = resp.json()["access_token"]
const resp = await fetch("https://epostak.sk/api/auth/token", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    client_id: "test_98b486a08b3e3d7f",
    client_secret: "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6",
    grant_type: "client_credentials"
  })
});
const { access_token } = await resp.json();
$resp = json_decode(file_get_contents(
  "https://epostak.sk/api/auth/token", false,
  stream_context_create(["http" => [
    "method" => "POST",
    "header" => "Content-Type: application/json",
    "content" => json_encode([
      "client_id" => "test_98b486a08b3e3d7f",
      "client_secret" => "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6",
      "grant_type" => "client_credentials"
    ])
  ]])
));
$token = $resp->access_token;
using var client = new HttpClient();
var body = new StringContent(
  JsonSerializer.Serialize(new {
    client_id = "test_98b486a08b3e3d7f",
    client_secret = "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6",
    grant_type = "client_credentials"
  }),
  Encoding.UTF8, "application/json"
);
var resp = await client.PostAsync("https://epostak.sk/api/auth/token", body);
var json = await resp.Content.ReadFromJsonAsync<TokenResponse>();
var token = json.access_token;
HttpClient client = HttpClient.newHttpClient();
String json = """
  {"client_id":"test_98b486a08b3e3d7f","client_secret":"sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6","grant_type":"client_credentials"}
  """;

HttpRequest req = HttpRequest.newBuilder()
  .uri(URI.create("https://epostak.sk/api/auth/token"))
  .header("Content-Type", "application/json")
  .POST(HttpRequest.BodyPublishers.ofString(json))
  .build();

HttpResponse<String> resp = client.send(req, HttpResponse.BodyHandlers.ofString());
JsonObject obj = JsonParser.parseString(resp.body()).getAsJsonObject();
String token = obj.get("access_token").getAsString();
3

Odošlite faktúru

curl -X POST https://epostak.sk/api/document/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "X-Peppol-Participant-Id: 0245:0000000001" \
  -H "Content-Type: application/json" \
  -d '{"metadata":{"documentId":"INV-001","documentTypeId":"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1","processId":"urn:fdc:peppol.eu:2017:poacc:billing:01:1.0","senderParticipantId":"0245:0000000001","receiverParticipantId":"0245:0000000002","creationDateTime":"2026-03-31T10:00:00Z"},"payload":"<Invoice xmlns=\\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\\">...</Invoice>","payloadFormat":"XML"}'

Testovacie prostredie (Sandbox)

Otestujte integráciu end-to-end bez produkčných dát.

A

Firma A — odosielateľ

ParameterHodnota
Peppol ID0245:0000000001
Client IDtest_98b486a08b3e3d7f
Client Secretsk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6
B

Firma B — prijímateľ

ParameterHodnota
Peppol ID0245:0000000002
Client IDtest_02b1c35552f99f1c
Client Secretsk_test_94e7d84efbf9000c2c0f3970c909750a8797a44a9a31e41e

Postup krok za krokom

1
POST /api/auth/token
Získajte token pre Firmu A (použite Client ID + Secret Firmy A)
2
POST /api/document/send
Odošlite faktúru z A na B — hlavička X-Peppol-Participant-Id: 0245:0000000001, v metadata receiverParticipantId: "0245:0000000002"
3
POST /api/auth/token
Získajte token pre Firmu B (použite Client ID + Secret Firmy B)
4
GET /api/document/receive
Overte prijatie na B — hlavička X-Peppol-Participant-Id: 0245:0000000002
5
POST /api/document/receive/{id}/acknowledge
Potvrďte prijatie dokumentu
i

Podporované typy dokumentov a poznámky

Podporované typy pre testovanie:

Faktúra (Invoice 380) Dobropis (Credit Note 381) Samozdanenie (Self-Billing 389)
Poznámka
Testovacie prostredie používa Peppol testbed
BuyerReference (BT-10) je povinný
Idempotency-Key musí byť unikátny UUID

API Referencia

Interaktívna dokumentácia. Kliknite na endpoint pre detail a vyskúšanie.

Autentifikácia

OAuth2 client_credentials flow s JWT tokenmi.

POST /api/auth/token Získať prístupový token

Prihláste sa s vašimi API kľúčmi. Pošlite client_id a client_secret, dostanete prístupový token (platí 15 minút) a obnovovací token (platí 30 dní).

Request Body

ParameterTypPopis
client_idstringPovinnýVáš klientský identifikátor
client_secretstringPovinnýVáš tajný kľúč
grant_typestringPovinnýVzdy "client_credentials"
scopestringNepovinnýRozsah oprávnení, napr. "document:send document:receive"

Odpovede

200 OK400 Neplatný grant_type401 Neplatné credentials403 IP adresa nie je povolená423 Účet zablokovaný

Príklad odpovede — 200 OK

{
  "access_token": "eyJ...",
  "refresh_token": "ref_...",
  "token_type": "Bearer",
  "expires_in": 900,
  "scope": "document:send document:receive"
}

Vyskúšajte

GET /api/auth/token/status Skontrolovať platnosť tokenu

Skontrolujte či je váš prístupový token ešte platný, kedy expiruje, a či ho treba obnoviť.

Headers

HeaderTypPopis
AuthorizationstringPovinnýBearer <access_token>

Odpovede

200 OK401 Neplatný token

Vyskúšajte

POST /api/auth/renew Obnoviť tokeny

Keď vám vyprší prístupový token, pošlite obnovovací token a dostanete nový pár. Starý obnovovací token prestane platiť — pre väčšiu bezpečnosť.

Request Body

ParameterTypPopis
refresh_tokenstringPovinnýPlatný refresh token

Odpovede

200 Nový pár tokenov401 Neplatný refresh token

Vyskúšajte

POST /api/auth/revoke Zneplatniť refresh token

Zrušte platnosť refresh tokenu (napr. keď sa odhlasujete). Môžete zavolať opakovane — nič sa nestane.

Request Body

ParameterTypPopis
tokenstringPovinnýRefresh token na zneplatnenie
token_type_hintstringNepovinnýEnum: "refresh_token"

Odpovede

200 Token zneplatnený

Príklad odpovede — 200 OK

{
  "revoked": true
}

Vyskúšajte

Dokumenty

Odosielanie a prijímanie Peppol dokumentov (faktúr, dobropisov).

POST/api/document/sendOdoslať dokument cez Peppol

Odošlite faktúru alebo dobropis cez Peppol sieť. Pošlite XML a my ho doručíme príjemcovi. Header Idempotency-Key zabráni duplicitnému odoslaniu ak zavoláte dvakrát.

Povinné Headers

HeaderPopis
AuthorizationBearer <access_token>
Idempotency-KeyUUID — zabraňuje duplicitnému odoslaniu
X-Peppol-Participant-IdVaše Peppol ID, napr. 0245:0000000001

Request Body

ParameterTypPopis
metadataobjectdocumentId, documentTypeId, processId, senderParticipantId, receiverParticipantId, creationDateTime
payloadstringUBL XML obsah faktúry
payloadFormatstring"XML"
payloadEncodingstringNepovinný, default "UTF-8"
checksumstringNepovinný, SHA-256 hex digest payloadu

Odpovede

202 Prijatý400 Neplatný request401 Neplatný token403 Nemáte oprávnenie k tejto organizácii409 Duplicitný kľúč503 Dočasne nedostupné

Príklad odpovede — 202 Accepted

{
  "providerDocumentId": "bec4f875-996f-4794-b42e-8f3b5b2f1ba4",
  "status": "ACCEPTED", /* alebo "RECEIVED" | "REJECTED" */
  "receivedAt": "2026-03-31T10:00:00.000Z",
  "timestamp": "2026-03-31T10:00:00.000Z"
}

Príklad curl

curl -X POST https://epostak.sk/api/document/send \
  -H "Authorization: Bearer $TOKEN" \
  -H "Idempotency-Key: $(uuidgen)" \
  -H "X-Peppol-Participant-Id: 0245:0000000001" \
  -H "Content-Type: application/json" \
  -d '{
  "metadata": {
    "documentId": "INV-2026-001",
    "documentTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
    "processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
    "senderParticipantId": "0245:0000000001",
    "receiverParticipantId": "0245:0000000002",
    "creationDateTime": "2026-03-31T10:00:00Z"
  },
  "payload": "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\">...</Invoice>",
  "payloadFormat": "XML"
}'
GET/api/document/receiveZoznam prijatých dokumentov

Pozrite sa aké dokumenty vám prišli cez Peppol. Ak ich je veľa, stránkujte pomocou pageToken.

Query parametre

ParameterTypDefaultPopis
limitint201-100
statusstringRECEIVED alebo ACKNOWLEDGED
pageTokenstringToken pre ďalšiu stránku

Povinné Headers

HeaderPopis
AuthorizationBearer <access_token>
X-Peppol-Participant-IdVaše Peppol ID, napr. 0245:0000000001

Odpovede

200 Zoznam401 Neplatný token403 Nemáte oprávnenie503 Dočasne nedostupné

Príklad odpovede — 200 OK

{
  "documents": [
    {
      "documentId": "48b703c6-6fbb-4cfa-90e3-736b1d6fa2ec",
      "documentTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
      "processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
      "senderParticipantId": "iso6523-actorid-upis::0245:0000000001",
      "receiverParticipantId": "iso6523-actorid-upis::0245:0000000002",
      "creationDateTime": "2026-03-31T10:00:00.000Z",
      "status": "RECEIVED"
    }
  ],
  "nextPageToken": "eyJsYXN0SWQiOiI0OGI3MDNjNiJ9"
}

Príklad curl

curl "https://epostak.sk/api/document/receive?status=RECEIVED" \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Peppol-Participant-Id: 0245:0000000002"
GET/api/document/receive/{documentId}Detail prijatého dokumentu

Stiahnite si celý dokument aj s XML obsahom.

Povinné Headers

HeaderPopis
AuthorizationBearer <access_token>
X-Peppol-Participant-IdVaše Peppol ID

Odpovede

200 Detail401403 Nemáte oprávnenie404 Neexistuje503 Dočasne nedostupné

Príklad odpovede — 200 OK

{
  "metadata": {
    "documentId": "48b703c6-6fbb-4cfa-90e3-736b1d6fa2ec",
    "documentTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1",
    "processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
    "senderParticipantId": "iso6523-actorid-upis::0245:0000000001",
    "receiverParticipantId": "iso6523-actorid-upis::0245:0000000002",
    "creationDateTime": "2026-03-31T10:00:00.000Z"
  },
  "payload": "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\">...</Invoice>",
  "payloadFormat": "XML"
}

Príklad curl

curl https://epostak.sk/api/document/receive/{documentId} \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Peppol-Participant-Id: 0245:0000000002"
POST/api/document/receive/{documentId}/acknowledgePotvrdiť prijatie

Potvrdíte, že ste dokument prevzali a spracovali. Môžete zavolať opakovane — nič sa nestane.

Povinné Headers

HeaderPopis
AuthorizationBearer <access_token>
X-Peppol-Participant-IdVaše Peppol ID

Odpovede

200 OK401403 Nemáte oprávnenie404503

Príklad odpovede — 200 OK

{
  "documentId": "48b703c6-6fbb-4cfa-90e3-736b1d6fa2ec",
  "status": "ACKNOWLEDGED",
  "acknowledgedDateTime": "2026-03-31T10:00:07.664Z"
}

Príklad curl

curl -X POST https://epostak.sk/api/document/receive/{documentId}/acknowledge \
  -H "Authorization: Bearer $TOKEN" \
  -H "X-Peppol-Participant-Id: 0245:0000000002"

Integračné príklady

Kompletné príklady implementácie SAPI klienta v rôznych jazykoch.

# pip install requests
import requests
import uuid

BASE = "https://epostak.sk/api"
CLIENT_ID = "test_98b486a08b3e3d7f"
CLIENT_SECRET = "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6"

class EpostakClient:
    def __init__(self):
        self.token = None
        self.refresh_token = None

    def authenticate(self):
        """Ziskanie pristupoveho tokenu"""
        resp = requests.post(f"{BASE}/auth/token", json={
            "client_id": CLIENT_ID,
            "client_secret": CLIENT_SECRET,
            "grant_type": "client_credentials"
        })
        resp.raise_for_status()
        data = resp.json()
        self.token = data["access_token"]
        self.refresh_token = data["refresh_token"]
        return data

    def _headers(self, peppol_id):
        return {
            "Authorization": f"Bearer {self.token}",
            "X-Peppol-Participant-Id": peppol_id
        }

    def send_invoice(self, xml_payload, metadata, peppol_id):
        """Odoslanie faktury cez Peppol"""
        resp = requests.post(f"{BASE}/document/send",
            headers={**self._headers(peppol_id),
                     "Idempotency-Key": str(uuid.uuid4())},
            json={"metadata": metadata,
                  "payload": xml_payload,
                  "payloadFormat": "XML"})
        return resp.json()

    def get_received(self, peppol_id, status="RECEIVED"):
        """Zoznam prijatých dokumentov"""
        resp = requests.get(f"{BASE}/document/receive",
            headers=self._headers(peppol_id),
            params={"status": status})
        return resp.json()

    def acknowledge(self, doc_id, peppol_id):
        """Potvrdenie prijatia dokumentu"""
        resp = requests.post(
            f"{BASE}/document/receive/{doc_id}/acknowledge",
            headers=self._headers(peppol_id))
        return resp.json()

    def renew(self):
        """Obnovenie tokenov"""
        resp = requests.post(f"{BASE}/auth/renew",
            json={"refresh_token": self.refresh_token})
        data = resp.json()
        self.token = data["access_token"]
        self.refresh_token = data["refresh_token"]
        return data

# Pouzitie:
client = EpostakClient()
client.authenticate()

# Odoslanie faktury
result = client.send_invoice(
    xml_payload="<Invoice>...</Invoice>",
    metadata={"documentId": "INV-001", ...},
    peppol_id="0245:0000000001")

# Kontrola prijatých
docs = client.get_received("0245:0000000001")
for doc in docs["documents"]:
    print(doc["documentId"])
    client.acknowledge(doc["documentId"], "0245:0000000001")
// Node.js / browser (fetch API)
const BASE = "https://epostak.sk/api";

class EpostakClient {
  #token = null;
  #refreshToken = null;

  async authenticate(clientId, clientSecret) {
    const resp = await fetch(`${BASE}/auth/token`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        client_id: clientId,
        client_secret: clientSecret,
        grant_type: "client_credentials"
      })
    });
    const data = await resp.json();
    this.#token = data.access_token;
    this.#refreshToken = data.refresh_token;
    return data;
  }

  #headers(peppolId) {
    return {
      "Authorization": `Bearer ${this.#token}`,
      "X-Peppol-Participant-Id": peppolId,
      "Content-Type": "application/json"
    };
  }

  async sendInvoice(xmlPayload, metadata, peppolId) {
    const resp = await fetch(`${BASE}/document/send`, {
      method: "POST",
      headers: {
        ...this.#headers(peppolId),
        "Idempotency-Key": crypto.randomUUID()
      },
      body: JSON.stringify({
        metadata, payload: xmlPayload, payloadFormat: "XML"
      })
    });
    return resp.json();
  }

  async getReceived(peppolId, status = "RECEIVED") {
    const resp = await fetch(
      `${BASE}/document/receive?status=${status}`,
      { headers: this.#headers(peppolId) }
    );
    return resp.json();
  }

  async acknowledge(docId, peppolId) {
    const resp = await fetch(
      `${BASE}/document/receive/${docId}/acknowledge`,
      { method: "POST", headers: this.#headers(peppolId) }
    );
    return resp.json();
  }

  async renew() {
    const resp = await fetch(`${BASE}/auth/renew`, {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({ refresh_token: this.#refreshToken })
    });
    const data = await resp.json();
    this.#token = data.access_token;
    this.#refreshToken = data.refresh_token;
    return data;
  }
}

// Pouzitie:
const client = new EpostakClient();
await client.authenticate("test_98b486a08b3e3d7f", "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6");

const docs = await client.getReceived("0245:0000000001");
for (const doc of docs.documents) {
  await client.acknowledge(doc.documentId, "0245:0000000001");
}
// PHP 8+ s cURL
class EpostakClient {
    private $base = "https://epostak.sk/api";
    private ?string $token = null;
    private ?string $refreshToken = null;

    public function authenticate(string $clientId, string $secret): array {
        $data = $this->post("/auth/token", [
            "client_id" => $clientId,
            "client_secret" => $secret,
            "grant_type" => "client_credentials"
        ]);
        $this->token = $data["access_token"];
        $this->refreshToken = $data["refresh_token"];
        return $data;
    }

    public function sendInvoice(string $xml, array $meta, string $peppolId): array {
        return $this->post("/document/send", [
            "metadata" => $meta,
            "payload" => $xml,
            "payloadFormat" => "XML"
        ], $peppolId, bin2hex(random_bytes(16)));
    }

    public function getReceived(string $peppolId, string $status = "RECEIVED"): array {
        return $this->get("/document/receive?status={$status}", $peppolId);
    }

    public function acknowledge(string $docId, string $peppolId): array {
        return $this->post("/document/receive/{$docId}/acknowledge", [], $peppolId);
    }

    private function post(string $path, array $body, ?string $peppolId = null, ?string $idem = null): array {
        $headers = ["Content-Type: application/json"];
        if ($this->token) $headers[] = "Authorization: Bearer {$this->token}";
        if ($peppolId) $headers[] = "X-Peppol-Participant-Id: {$peppolId}";
        if ($idem) $headers[] = "Idempotency-Key: {$idem}";

        $ch = curl_init($this->base . $path);
        curl_setopt_array($ch, [
            CURLOPT_POST => true,
            CURLOPT_HTTPHEADER => $headers,
            CURLOPT_POSTFIELDS => json_encode($body),
            CURLOPT_RETURNTRANSFER => true
        ]);
        $resp = curl_exec($ch);
        curl_close($ch);
        return json_decode($resp, true);
    }

    private function get(string $path, string $peppolId): array {
        $opts = ["http" => ["header" =>
            "Authorization: Bearer {$this->token}\r\nX-Peppol-Participant-Id: {$peppolId}"]];
        return json_decode(file_get_contents(
            $this->base . $path, false, stream_context_create($opts)), true);
    }
}

// Pouzitie:
$client = new EpostakClient();
$client->authenticate("test_98b486a08b3e3d7f", "sk_test_e888be545de8bf6e132e5934b790761cdabc65b67595b3a6");
$docs = $client->getReceived("0245:0000000001");
// C# / .NET 8+
using System.Net.Http.Json;

public class EpostakClient : IDisposable {
    private readonly HttpClient _http = new();
    private string? _token, _refreshToken;
    const string Base = "https://epostak.sk/api";

    public async Task<TokenResponse> AuthenticateAsync(string clientId, string secret) {
        var resp = await _http.PostAsJsonAsync($"{Base}/auth/token", new {
            client_id = clientId,
            client_secret = secret,
            grant_type = "client_credentials"
        });
        resp.EnsureSuccessStatusCode();
        var data = await resp.Content.ReadFromJsonAsync<TokenResponse>();
        _token = data.AccessToken;
        _refreshToken = data.RefreshToken;
        return data;
    }

    public async Task<JsonElement> SendInvoiceAsync(
        string xml, object metadata, string peppolId) {
        var req = new HttpRequestMessage(HttpMethod.Post, $"{Base}/document/send");
        req.Headers.Add("Authorization", $"Bearer {_token}");
        req.Headers.Add("Idempotency-Key", Guid.NewGuid().ToString());
        req.Headers.Add("X-Peppol-Participant-Id", peppolId);
        req.Content = JsonContent.Create(new {
            metadata, payload = xml, payloadFormat = "XML"
        });
        var resp = await _http.SendAsync(req);
        return await resp.Content.ReadFromJsonAsync<JsonElement>();
    }

    public void Dispose() => _http.Dispose();
}

public record TokenResponse(
    [property: JsonPropertyName("access_token")] string AccessToken,
    [property: JsonPropertyName("refresh_token")] string RefreshToken,
    [property: JsonPropertyName("expires_in")] int ExpiresIn
);
// Java 17+ (java.net.http)
import java.net.http.*;
import com.google.gson.*;

public class EpostakClient {
    private static final String BASE = "https://epostak.sk/api";
    private final HttpClient http = HttpClient.newHttpClient();
    private String token, refreshToken;

    public JsonObject authenticate(String clientId, String secret) throws Exception {
        String body = new Gson().toJson(Map.of(
            "client_id", clientId,
            "client_secret", secret,
            "grant_type", "client_credentials"));

        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create(BASE + "/auth/token"))
            .header("Content-Type", "application/json")
            .POST(HttpRequest.BodyPublishers.ofString(body))
            .build();

        HttpResponse<String> resp = http.send(req,
            HttpResponse.BodyHandlers.ofString());

        JsonObject json = JsonParser.parseString(resp.body())
            .getAsJsonObject();
        this.token = json.get("access_token").getAsString();
        this.refreshToken = json.get("refresh_token").getAsString();
        return json;
    }

    public JsonObject getReceived(String peppolId) throws Exception {
        HttpRequest req = HttpRequest.newBuilder()
            .uri(URI.create(BASE + "/document/receive?status=RECEIVED"))
            .header("Authorization", "Bearer " + token)
            .header("X-Peppol-Participant-Id", peppolId)
            .GET().build();

        HttpResponse<String> resp = http.send(req,
            HttpResponse.BodyHandlers.ofString());
        return JsonParser.parseString(resp.body()).getAsJsonObject();
    }
}
# Ruby (net/http)
require "net/http"
require "json"
require "securerandom"

class EpostakClient
  BASE = URI("https://epostak.sk/api")

  def authenticate(client_id, client_secret)
    data = post("/auth/token", {
      client_id: client_id,
      client_secret: client_secret,
      grant_type: "client_credentials"
    })
    @token = data["access_token"]
    @refresh = data["refresh_token"]
    data
  end

  def send_invoice(xml, metadata, peppol_id)
    post("/document/send",
      { metadata: metadata, payload: xml, payloadFormat: "XML" },
      peppol_id, SecureRandom.uuid)
  end

  def get_received(peppol_id, status: "RECEIVED")
    get("/document/receive?status=#{status}", peppol_id)
  end

  def acknowledge(doc_id, peppol_id)
    post("/document/receive/#{doc_id}/acknowledge", {}, peppol_id)
  end

  private

  def post(path, body, peppol_id = nil, idem = nil)
    uri = URI(BASE.to_s + path)
    req = Net::HTTP::Post.new(uri)
    req["Content-Type"] = "application/json"
    req["Authorization"] = "Bearer #{@token}" if @token
    req["X-Peppol-Participant-Id"] = peppol_id if peppol_id
    req["Idempotency-Key"] = idem if idem
    req.body = body.to_json
    resp = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |h| h.request(req) }
    JSON.parse(resp.body)
  end
end

Chybové kódy

Všetky chyby vracajú jednotný JSON formát s kľúčom error obsahujúcim category, code, message a correlation_id.

{
  "error": {
    "category": "VALIDATION",
    "code": "SAPI-VAL-001",
    "message": "Popis chyby",
    "details": [{ "field": "grant_type", "issue": "invalid_value" }],
    "retryable": false,
    "correlation_id": "550e8400-e29b-41d4-..."
  }
}
HTTPKategóriaOpakovať?Príklad
400VALIDATIONNieNeplatný XML, chýbajúce pole
401AUTHNieExpirovaný token, neplatné credentials
403AUTHNieNemáte oprávnenie
404VALIDATIONNieDokument neexistuje
409PROCESSINGNieDuplicitný Idempotency-Key
423AUTHNieÚčet dočasne zablokovaný (5 pokusov)
429TEMPORARYAnoPríliš veľa požiadaviek
500PROCESSINGNieInterná chyba servera
422VALIDATIONNieUBL validácia zlyhala
502TEMPORARYAnoChyba Peppol siete
504TEMPORARYAnoTimeout pri komunikácii s Peppol sieťou
503TEMPORARYAnoDočasná chyba servera — skúste znova o niekoľko sekúnd (nesúvisí s certifikáciou ani stavom účtu)