Technická reference všech 37 operací APEX Access Pointu: APEX API pro hlubokou integraci (odesílání včetně hromadného, příjem, validace, precheck, události, odpovědi, webhooky a MQTT, účastníci, reporting, licence) a SAPI pro zjednodušený přístup podle slovenské specifikace SAPI-SK v1.0. Ověřeno vůči zdrojovému kódu APEX 26.4.
/api-docs/api a /api-docs/sapi.
APEX Access Point nabízí dva rovnocenné způsoby integrace. Výběr závisí na tom, kde běží váš systém a jaký styl komunikace potřebujete. Obě cesty pokrývají plný Peppol tok (odesílání i příjem) a můžete je i kombinovat.
client_credentials). JSON tělo, UBL dokument jako XML text. Odesílání je asynchronní (202 / ACCEPTED), stav sledujete pollingem, webhooky nebo přes MQTT.SynchronizationMessage s entitou PeppolDocument (30); přijaté dokumenty i výsledky vašich odeslání (PeppolDocumentEvent, 32) přicházejí do vaší delivery queue. Registraci a přístupové údaje zřizuje ASOL nebo váš partner.Integraci vyvíjejte a testujte na sandboxu, do produkce přejdete výměnou URL a přístupových údajů. Obě prostředí mají stejné API, stejnou autentizaci a stejné limity.
https://api.sandbox.apex.qasida.sk/api-docs/api, /api-docs/sapihttps://iam.qasida.sk/oauth2/tokenDOCUMENTS_RECEIVED a odesílatel následně dostane MLS. Místo AS4 událostí uvidíte LOOPBACK_DETECTED a LOOPBACK_PROCESSING_COMPLETED. SML/SMP se nevolá: lookup zná jen účastníky sandboxu a precheck hlásí příjemce vždy jako dostupného. SAPI neznámého příjemce odmítne hned (RECEIVER_NOT_FOUND); APEX API a dávky ho přijmou a dokument po vyčerpání pokusů (cca 7,5 min) skončí v DEAD_LETTER./swagger-ui, /api-docs/api, /api-docs/sapi/oauth2/token serveru ASOL IAM uvedeného v přístupových údajíchclientId + clientSecret), vázaný na jednu organizaci (tenanta). Sandboxový přístup obsahuje i testovacího účastníka 0245:<DIČ> a sandboxovou licenci; vyžádáte si ho přes ASOL nebo svého partnera./api-docs/api (APEX API) a /api-docs/sapi (SAPI) — a Swagger UI na /swagger-ui s tlačítkem Authorize (OAuth 2.0 client_credentials). Z OpenAPI si můžete vygenerovat klienta (OpenAPI Generator, NSwag, Kiota…).
APEX AP poskytuje dvě skupiny API: APEX API (/api/v1, /api/v2) pro hlubokou integraci
a APEX SAPI (/sapi/v1) pro zjednodušené rozhraní podle specifikace SAPI-SK v1.0.
Obě běží na stejném serveru a sdílejí data i tokeny.
Technická cesta od prvního requestu po odeslání a přijetí faktury přes APEX API. Všechny kroky si vyzkoušíte na sandboxu.
client_credentials (platnost podle expires_in) a posílejte ho v hlavičce Authorization: Bearer <token>. Před vypršením si vyžádejte nový./api/** i /sapi/**.POST /api/v1/documents/send s hlavičkou Idempotency-Key (např. číslo faktury). Příjemce určuje receiverParticipantId (slovenské firmy 0245:DIČ). Odpověď 202 se stavem QUEUED a documentId. Při timeoutu opakujte se stejným klíčem.POST /api/v1/subscriptions) nebo MQTT, případně pollujte GET /api/v1/documents/{id}/status. Historii ukáže /events, odpovědi protistrany /responses.DELIVERED, nebo jasný důvod chyby.DOCUMENTS_RECEIVED nebo pravidelně volejte GET /api/v2/documents/inbox?status=VALIDATED, stáhněte detail a po uložení potvrďte POST /api/v1/documents/inbox/{id}/acknowledged.GET /api/v1/participants/lookup/dic?schema=0245&dic=2024000001 (nebo /lookup/ico?ico=…) zjistí, zda je odběratel v síti Peppol a zda má použitelný certifikát.POST /api/v1/documents/precheck se stejným tělem jako send ověří dokument (XSD, EN 16931, Peppol BIS), existenci příjemce i podporu typu dokumentu bez odeslání — výsledkem je networkReady: true nebo seznam chyb.
Všechny endpointy APEX API a SAPI: účel, kdy je volat, vstupy, výstupy, chování a typické chyby.
Cesty jsou relativní k základní URL prostředí (např. https://api.sandbox.apex.qasida.sk);
každý request kromě /sapi/v1/auth/token, /renew a /revoke vyžaduje Bearer token.
Odeslání jednoho dokumentu do sítě Peppol a sledování jeho osudu. Odesílání je asynchronní:
POST /send dokument zkontroluje, uloží a zařadí do fronty, AS4 přenos proběhne na pozadí.
Stav čtěte přes /status, historii přes /events a odpovědi protistrany přes
/responses — nebo si nechte posílat notifikace (záložka Webhooky & MQTT).
202 Accepted se stavem QUEUED.202 znamená převzetí, ne doručení./precheck, pokud chcete chyby zachytit ještě před odeslánímPOST /api/v1/batchesIdempotency-Key202 (původní documentId a submittedAt, status vždy QUEUED) s hlavičkou Idempotent-Replayed: true a nic nového nezařadí — opakování po timeoutu tak fakturu nikdy neodešle dvakrát. Klíče jsou oddělené pro každého tenanta; krátký a kanonický tvar účastníka se považují za stejný obsah. Stejný klíč s jiným obsahem (dokument nebo metadata) → 409 IDEMPOTENCY_CONFLICT; souběžný request se stejným klíčem → 409 IDEMPOTENCY_IN_PROGRESS. Odmítnutý request (400/403/500) klíč nespotřebuje.QUEUED → PROCESSING → DELIVERED. Pokud pokus o AS4 přenos selže, dokument přejde do RETRYING a další pokus přijde za 30, 60, 120 a 240 s; páté selhání (nebo trvalá chyba, např. certifikát příjemce nevydaný CA OpenPeppol) → DEAD_LETTER, zpravidla do 8 minut. Negativní Peppol MLS od přijímajícího AP přepne dokument na FAILED — i když už byl DELIVERED. Licence neplatná v době odesílání → REJECTED.400 — chybějící pole (např. Receiver participant ID is required), neúspěšná validace dokumentu nebo neshoda stran (tělo s validationErrors[])401 — chybějící nebo neplatný Bearer token403 — odesílatel chybí, není registrován nebo nepatří vašemu tenantovi; neplatná licence409 — IDEMPOTENCY_CONFLICT / IDEMPOTENCY_IN_PROGRESS500 — dokument se nepodařilo zařadit (Failed to queue document: …); sem patří i příjemce, který není v síti Peppol nebo nepřijímá daný typ dokumentu — proto ho ověřte přes /precheck nebo lookupublDocument je XML text (ne Base64) — holý UBL dokument nebo UBL v obálce SBDH; úvodní UTF-8 BOM APEX odstraní. Typ a proces musí odpovídat obsahu (cbc:CustomizationID, cbc:ProfileID). Odesílatel a příjemce musí odpovídat cbc:EndpointID stran dokladu: dodavatel → odběratel; samofakturu posílá odběratel a objednávku kupující. Neshoda vrátí SENDER_SUPPLIER_MISMATCH / RECEIVER_CUSTOMER_MISMATCH (resp. SENDER_CUSTOMER_MISMATCH / RECEIVER_SUPPLIER_MISMATCH). Schematron se u dokumentů nad 5 MB přeskočí.0245:2024000001) nebo kanonický tvar (iso6523-actorid-upis::0245:2024000001)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0/status, /events, /responses a notifikaceQUEUED/send, dávku nebo SAPI (SAPI providerDocumentId je stejné UUID). Notifikace nemají zaručené pořadí, proto je tento endpoint autoritativním zdrojem stavu.statusDELIVERED)PROCESSING do QUEUED (např. při přerušení odesílání na nedostupný cíl) bez notifikace a bez spotřebování pokusu.404 (prázdné tělo) — dokument neexistuje, nepatří vašemu tenantovi nebo jde o přijatý dokument (stav je jen pro odeslané)401 — neplatný token/send (path)200 — výsledek je v poli valid./send provádí stejnou validaci (navíc kontroluje strany, licenci a příjemce). Pokud documentTypeId nezadáte, odvodí se z kořenového elementu: CreditNote → BIS 3.0 dobropis, jinak BIS 3.0 faktura. Podporovány jsou faktury a dobropisy BIS Billing 3.0 (včetně samofakturace, PINT a XRechnung), objednávky, odpovědi na objednávky, dodací listy, katalogy, MLR, IMR a MLS; pro neznámý typ vrátí chybu SCHEMATRON_001.valid je true, jen pokud projdou všechny tři vrstvy; po vrstvách schemaValid, schematronValid, businessRulesValid. Každá chyba má level (ERROR/WARNING/INFO), code (např. BR-07, PEPPOL-EN16931-R004), message a location (XPath). Při úspěšném parsování vrátí i metadata dokladu.400 — chybí tělo nebo je ublDocument prázdný415 — tělo není application/json200 s valid: falselevel, code, message, location/send, ale bez uložení a zařazení: validace dokumentu, existence příjemce v síti Peppol a podpora typu dokumentu. Výsledek networkReady.valid (XSD, EN 16931, Peppol BIS)participantExists (SML/DNS najde SMP)canSend (SMP příjemce nabízí documentTypeId + processId, AS4 endpoint a platný certifikát)networkReady = valid && participantExists && canSendPARTICIPANT_NOT_FOUND; hlásí se i při dočasné nedostupnosti SML/SMP)DOCTYPE_NOT_SUPPORTED)CERT_EXPIRING_SOON (certifikát příjemce vyprší do 30 dní).participantExists a canSend jsou vždy true200 se vrací vždy, i když kontroly neprojdou; licenci precheck nekontroluje400 — chybí povinné pole; 403 — chybějící nebo cizí odesílatel/sendcategory, code, message, location (u PARTICIPANT/ROUTING null)createdAt.QUEUE_PROCESSING_STARTED / QUEUE_PROCESSING_FAILEDMESSAGE_RECEIVED → MESSAGE_VALIDATED → MESSAGE_ACKNOWLEDGED)eventType404 — dokument neexistuje[] — zatím bez událostídocumentId dokumentu, ke kterému událost patříEBMS-0010, BR-07)nulldocumentTypeId …urn:peppol:edec:mls…), IMR (Invoice Response 3.0 / T111), ORDER_RESPONSE (BIS 28a), RECEIPT_ADVICE (BIS 30a)RE a CA obsahuje issues[] jednotlivé důvody z odpovědi: type (kód důvodu, zpravidla BV business / SV syntax), code, description, severity (FATAL u RE, jinak WARNING) a xpath (zpravidla null). AP s prázdným seznamem = čisté přijetí.[] — zatím bez odpovědi (běžné hned po odeslání)[] — i když je documentId sám odpovědí404 — dokument není váš nebo neexistujeMLR, IMR, ORDER_RESPONSE, RECEIPT_ADVICEAP/RE/CA/UQ/IP a jeho popisApplicationResponse), Content-Type: application/xml./responses — obchodní odpovědi protistrany (IMR/MLR), odpovědi, kterou jste poslali vy, nebo MLR, které APEX vygeneroval a poslal AP odesílatele (C2).404 — responseId nepatří k danému dokumentu (i když jsou obě ID stejná)
Dokumenty, které vám přišly ze sítě Peppol přes AS4. Pull model: seznam → detail → potvrzení.
O novém dokumentu se dozvíte pollingem seznamu nebo notifikací DOCUMENTS_RECEIVED (webhook / MQTT).
Endpointy existují ve verzi v1 (identifikátory v kanonickém tvaru iso6523-actorid-upis::0245:…)
a v2 (krátké Peppol ID 0245:…). Pro nové integrace doporučujeme v2; potvrzení existuje jen ve v1.
receivedAt DESC). Odesílatel a příjemce v krátkém tvaru 0245:2024000001.ublDocument je prázdné) — obsah získáte z detailu. Čtení seznamu nemění stav dokumentů.status=VALIDATED — to jsou dokumenty, které čekají na staženíGET /api/v2/documents/inbox/{documentId}POST /api/v1/documents/inbox/{documentId}/acknowledged — z dalšího pollingu vypadneDOCUMENTS_RECEIVED)offset / limit (výchozí 0 / 20; doporučujeme nejvýše 100); odpověď nese total — počet záznamů odpovídajících filtru. status rozlišuje velká a malá písmena; neznámá hodnota vrátí 400.VALIDATED, ACKNOWLEDGED, REJECTED, FAILEDdocumentId, senderParticipantId, receiverParticipantId, documentTypeId, processId, receivedAt, statusStandardBusinessDocument (obálka SBDH s UBL dokumentem uvnitř).ublDocument obsahuje kompletní StandardBusinessDocument tak, jak přišel sítí Peppol — kořenem je obálka SBDH, ne faktura. Validace přímo vůči UBL Invoice XSD proto selže; business dokument najděte podle jmenného prostoru kdekoli ve stromu. Identifikátory uvnitř payloadu se nepřepisují, krátký tvar platí jen pro JSON pole.cac:, cbc:…) nejsou součástí kontraktu a mohou se měnit mezi verzemi i v rámci jednoho dokumentu. Važte se na URI jmenných prostorů a lokální názvy z UBL 2.1 a Peppol BIS Billing 3.0.POST /api/v1/documents/inbox/{documentId}/acknowledged. Stažení samo o sobě stav nemění. Pokud v odpovědi chybí pole ublDocument, payload se právě nepodařilo načíst — dokument nepotvrzujte a zkuste to později.404 (prázdné tělo) — dokument neexistuje, není adresován vašemu tenantovi nebo nejde o přijatý dokument401 — neplatný token0245:1234567890)StandardBusinessDocument (XML řetězec)senderParticipantId / receiverParticipantId v plném kanonickém tvaru ISO 6523 — iso6523-actorid-upis::0088:1234567890123.0088:1234567890123, tedy stejný tvar, jaký posíláte v requestech a jaký vrací /participants/lookup.ACKNOWLEDGED. Odpověď 204 No Content.204. Potvrdit lze přijatý dokument v jakémkoli stavu (i REJECTED, pokud ho chcete označit jako vyřízený); potvrzení se zapíše do událostí jako MESSAGE_ACKNOWLEDGED a platí i pro SAPI.404 — dokument neexistuje nebo nepatří vašemu tenantovi401 — neplatný token
Desítky až tisíce dokumentů jedním requestem (měsíční fakturace, migrace). Dávka přijme až 5 000 dokumentů
a hned odpoví 202. Každý dokument pak na pozadí projde přesně stejnými kontrolami jako
POST /api/v1/documents/send a zařadí se samostatně. Dokumenty dávky se odesílají až po dokumentech posílaných
jednotlivě a tenanti se ve frontě střídají, takže velká dávka nebrzdí běžný provoz.
202 s batchId a hlavičkou Location.202 znamená, že APEX dávku převzal, ne že jsou dokumenty platné. Dokumenty jsou nezávislé: neplatný dokument nezastaví ostatní, skončí REJECTED s důvodem. Výsledek sledujte přes GET /api/v1/batches/{batchId} (ne častěji než jednou za 10 s) nebo notifikaci BATCH_PROCESSED.RECEIVED/PROCESSING) na tenantaIdempotency-Key (1–200 znaků, např. ID běhu ERP). Stejný klíč a bajtově identické tělo → původní 202 s Idempotent-Replayed: true, nová dávka nevznikne. Jiné tělo → 409 IDEMPOTENCY_CONFLICT. Klíč dávky neexpiruje. Tělo si před odesláním uložte a při opakování pošlete stejné bajty (curl --data-binary).Content-Type: application/zip (i application/x-zip-compressed); každý soubor = jeden dokument v UTF-8 (holý UBL nebo UBL v SBDH). Cesta souboru v archivu je clientReference dokumentu (soubory pojmenujte číslem dokladu). Název dávky a režim notifikací jdou do query parametrů clientReference a notify. Metadata APEX odvodí z dokumentu: typ z kořenového elementu + cbc:CustomizationID, proces z cbc:ProfileID, strany z cbc:EndpointID (dodavatel → odběratel; u samofaktury naopak; u objednávky kupující → prodávající). Soubor bez odvoditelných metadat skončí REJECTED s INVALID_METADATA.400 BATCH_INVALID_REQUEST — nejde o JSON objekt/ZIP, chybí documents nebo povinné pole (zpráva uvádí cestu, např. documents[17].processId), duplicitní clientReference, neznámý notify400 INVALID_IDEMPOTENCY_KEY403 PARTICIPANT_NOT_AUTHORIZED / LICENCE_INVALID409 IDEMPOTENCY_CONFLICT / IDEMPOTENCY_IN_PROGRESS413 BATCH_TOO_LARGE429 TOO_MANY_OPEN_BATCHES / BATCH_INTAKE_BUSY (zopakujte po Retry-After)BATCH (výchozí), DOCUMENT, BOTH/documents/sendRECEIVEDExpect: 100-continue — odmítnutí (429, 403, 400) pak přijde ještě před nahráním těla. Dávky jednoho tenanta neposílejte paralelně a stejnou fakturu neposílejte zároveň v dávce i přes /documents/send — odešly by dvě.items) a živé počty doručování vzniklých zpráv (messages).ACCEPTED, REJECTED nebo CANCELLED; doručování přijatých pokračuje (viz messages)items = převzetí dokumentů: pending, processing, accepted, rejected, cancelled.messages = doručování zpráv z přijatých dokumentů, stejné stavy jako /documents/{id}/status: queued, processing, delivered (včetně přechodného SENT), retrying, failed, rejected, deadLetter. Součet messages = accepted.404 BATCH_NOT_FOUND — neexistuje nebo patří jinému tenantoviprocessedAt je null, dokud nejsou zpracovány všechny dokumentystatus=REJECTED pro to, co je třeba opravit.errorCode)errors[]DOCUMENT_NOT_UTF8, DOCUMENT_NOT_XML, DOCUMENT_TYPE_UNSUPPORTED, CUSTOMIZATION_ID_MISSING, PROFILE_ID_MISSING, SENDER_ENDPOINT_MISSING, RECEIVER_ENDPOINT_MISSING, METADATA_INVALID)errorMessage po dočasné chybě čeká na další pokus)documentId použijte pro /documents/{id}/status, /events, /responseserrorCodestatus (volitelné), page od 0, size výchozí 100, nejvýše 1 000. Chyby: 400 neplatný stav/stránkování, 404 BATCH_NOT_FOUND.ACCEPTEDerrors[] = code, message, location[from, to) nebo v jednom stavu.from, to (ISO 8601 date-time), status (RECEIVED, PROCESSING, PROCESSED, CANCELLED), page od 0, size výchozí 20, nejvýše 1 000.content[] s batchId, clientReference, status, notify, itemCount, receivedAt, processedAt, cancelledAt; dále page, size, totalElements. Počty dokumentů jsou v detailu dávky. Chyba 400 při neplatném stavu nebo stránkování.ACCEPTED) dokumenty jsou na cestě a nevolají se zpět.PENDING i dokument, který se právě validuje (za chvíli skončí CANCELLED, proto může být v odpovědi ještě processing > 0). Dávka přejde na CANCELLED, přestane se počítat do limitu 3 otevřených dávek a BATCH_PROCESSED se pro ni nepošle. Odpovědí je stav dávky (jako GET /batches/{batchId}).404 BATCH_NOT_FOUND409 BATCH_NOT_CANCELLABLE — dávka je už PROCESSED nebo CANCELLEDnotify. BATCH_PROCESSED přijde na každý aktivní webhook a MQTT queue tenanta; filtry webhooku se na něj neuplatňují. Nenese seznam dokumentů, pouze počty — dokumenty načtěte přes /items.notify | BATCH_PROCESSED | Notifikace jednotlivých dokumentů |
|---|---|---|
| BATCH (výchozí) | ano | pouze problémy: QUEUE_PROCESSING_FAILED, QUEUE_DEAD_LETTER, MLS_RECEIVED_NEGATIVE |
| DOCUMENT | ne | všechny, jako při jednotlivém odeslání |
| BOTH | ano | všechny |
Vyhledání obchodního partnera v síti Peppol podle DIČ (nebo jiného identifikátoru se schématem) či IČO.
Výsledek řekne, zda je partner v síti Peppol registrován, přes který AS4 endpoint přijímá a zda je certifikát jeho přístupového bodu použitelný.
Pro slovenské subjekty používejte schéma 0245 (SK:DIČ) — Peppol ID má tvar 0245:2024000001.
<schema>:<dic>, plný identifikátor iso6523-actorid-upis::<schema>:<dic>. Hodnoty se používají přesně tak, jak je pošlete — bez oříznutí, změny velikosti písmen, odstranění prefixu SK a bez kontroly formátu. 2024000001 a SK2024000001 jsou dva různé identifikátory.source=LOCAL), bez něj 404; SML/SMP se nevolá.source=LOCAL.404 (i když lokální záznam existuje)LOCAL), bez něj 503source=SMP s endpointem a certifikátemsource=SMP s uloženým endpointem nebo nullcertificate.validtrue — certifikát publikovaný v SMP prošel během requestu plnou kontrolou: platnost, řetěz vydavatele a stav odvolání, na který CRL nebo OCSP skutečně odpověděl.false — certifikát je s jistotou nepoužitelný, důvod v invalidReason: EXPIRED, NOT_YET_VALID, REVOKED, UNTRUSTED_ISSUER (nevydala ho CA OpenPeppol). Na takový endpoint nelze doručit.null — stav se v tomto requestu nezjistil (certifikát z lokálního záznamu nebo soft-fail při nedostupném CRL/OCSP). Soft-fail nikdy nedá true.valid a invalidReason jsou v JSON vždy, i s hodnotou null.400 — chybí schema nebo dic404 — není registrován v síti Peppol, nebo prázdná hodnota (bez těla)503 — SML/SMP neodpovídá a lokální záznam neexistuje — zopakujte později0245 (SK DIČ), 9950 (SK IČ DPH), 9929 (CZ VAT), 9914 (AT VAT), 0088 (GLN)SKLOCAL (lokální záznam) nebo SMP (živé vyhledání v tomto requestu)iso6523-actorid-upis::0245:…0245:2024000001null0245 → SK); ZZ = neznámánull, pokud záznam neexistujesubject, issuer, serial, fingerprint (SHA-256), notBefore, notAfter, expired, valid, invalidReason/lookup/dic.404.503.schema vznikne Peppol ID a vyhodnotí se stejně jako /lookup/dic.400 — chybí ico404 — IČO se nepodařilo převést na DIČ nebo účastník není v síti Peppol503 — registeruz.sk nebo SML/SMP nedostupné0245/lookup/dic
Push notifikace místo pollingu: o novém přijatém dokumentu a o událostech vašich odeslaných dokumentů.
Dva kanály — HTTPS webhook (filtrovatelný, více odběrů) a MQTT topic (jeden na tenanta, všechny notifikace).
Notifikace dokument pouze identifikuje, obsah si stáhnete přes API. Doručení je best-effort, nejvýše jednou a bez zaručeného pořadí:
stav dokumentu berte vždy z pole status, nikdy z eventType.
documentIds má vždy právě jeden prvek, tvar pole je zachován kvůli kompatibilitě). Pole s hodnotou null se v JSON vynechávají.| Pole | Význam |
|---|---|
| eventType | Co notifikaci vyvolalo — ne stav dokumentu |
| subscriptionId | Odběr, pro který se doručuje (u MQTT chybí) |
| documentId / documentIds | UUID dokumentu / totéž jako jednoprvkové pole |
| receivedCount | Vždy 1, jen u DOCUMENTS_RECEIVED |
| direction | IN přijatý, OUT odeslaný dokument |
| status | Stav dokumentu v okamžiku odeslání notifikace |
| messageId | ID zprávy; u přijatého dokumentu AS4 Message ID od odesílajícího AP |
| conversationId | Conversation ID dokumentu (pokud existuje) |
| senderParticipantId, receiverParticipantId | Peppol ID včetně schématu (iso6523-actorid-upis::…) |
| documentTypeId, processId | Peppol typ dokumentu a proces |
| eventMessage | Čitelný detail, neparsujte ho |
| notifiedAt | Kdy byla notifikace sestavena. Webhook: číslo, Unix epoch sekundy se zlomkem (1776168005.123456000); MQTT: ISO 8601 řetězec |
| batch | Jen u BATCH_PROCESSED: batchId, clientReference, status, itemCount, accepted, rejected, cancelled |
| eventType | Směr | Kdy |
|---|---|---|
| DOCUMENTS_RECEIVED | IN | Přijatý dokument prošel validací a je uložen (VALIDATED); u zamítnutého ani duplicitního dokumentu nepřijde |
| MESSAGE_QUEUED | OUT | Váš dokument byl přijat a zařazen |
| QUEUE_PROCESSING_STARTED | OUT | Začal pokus o odeslání (při každém pokusu; ne při self-send) |
| MESSAGE_DELIVERED | OUT | Doručeno přijímajícímu AP (nebo lokálně při self-send) |
| QUEUE_PROCESSING_FAILED | OUT | Pokus selhal, další je naplánovaný |
| QUEUE_DEAD_LETTER | OUT | Odesílání vzdáno, dokument je DEAD_LETTER |
| MLS_RECEIVED | OUT | Přišel pozitivní Peppol MLS |
| MLS_RECEIVED_NEGATIVE | OUT | Přišel negativní MLS; dokument je FAILED (i po DELIVERED) |
| BATCH_PROCESSED | — | Dávka je zpracována (podle notify) |
MESSAGE_DELIVERED může přijít před MESSAGE_QUEUED. status je stav přečtený při odeslání notifikace, může být novější než událost (např. MESSAGE_QUEUED se stavem DELIVERED) a notifikace se starším stavem může přijít po novější. Poslední přijatou notifikaci tedy neberte jako aktuální stav; v případě pochybnosti zavolejte GET /api/v1/documents/{documentId}/status. Ne každá změna stavu se notifikuje (např. REJECTED kvůli neplatné licenci)./inbox, /status).POST u každého dokumentu a události, které odpovídají filtrům. Odpověď 201 Created.https:// a dostupná ze serveru APEX (dostupnost se při registraci neověřuje, přesměrování se nenásledují). Timeout spojení 2 s a odpovědi 2 s — vraťte 2xx co nejdříve (ideálně < 500 ms) a náročné zpracování provádějte asynchronně. Odběry tenanta se pro jednu událost volají postupně, pomalý endpoint tedy zdrží ostatní. Request má Content-Type: application/json, Accept: application/json a User-Agent: Apex-Webhook/1.0. Tělo není podepsané — k ověření APEX použijte customHeaders (např. tajný token).documentTypeFilters — seznam typů dokumentů, přesná shoda; platí pro přijaté i odeslané dokumenty.senderParticipantFilters — seznam odesílatelů, přesná shoda na kanonický identifikátor tak, jak je v senderParticipantId notifikace (např. iso6523-actorid-upis::0245:1234567890; krátký tvar se neshoduje); jen pro přijaté dokumenty.BATCH_PROCESSED filtry ignoruje.[A-Za-z0-9-_], hodnota max 1 000 znaků bez zalomení řádků. Host, Content-Length, Content-Type a Transfer-Encoding nelze přepsat (Accept a User-Agent ano). Hlavička, která pravidla nesplní, se tiše vynechá — zkontrolujte customHeaders v odpovědi.400 — chybí name/url, URL není https://, příliš mnoho hlaviček (Problem Details s detail: "Invalid request content.")409 — tenant už má 3 webhooky401 — neplatný tokentrue)offset (výchozí 0), limit (výchozí 20, 1–100).items[] (objekty jako při vytvoření), total (všechny odběry tenanta bez ohledu na stránku), offset, limit. Chyby 400 (limit < 1), 401.404, pokud neexistuje nebo patří jinému tenantovi.POST; přepíší se všechna pole (ne PATCH). Pro dočasné pozastavení bez ztráty nastavení pošlete active: false. Změna platí pro notifikace odeslané po uložení. Odpověď 200 s aktualizovaným odběrem; 400 při neplatném těle, 404.204; 404, pokud neexistuje. Pokud chcete notifikace jen dočasně zastavit, použijte PUT s active: false.queueName, např. /apex/inbox/apex-sk2024000001) dostává notifikace přijatých i odeslaných dokumentů, přestože má v názvu inbox. Filtry a příznak active webhooků se na něj neuplatňují. Zpráva má stejný formát jako webhook, bez subscriptionId a s notifiedAt jako ISO 8601 řetězcem.host, port, username, password (nebo mqttUrl, které má vždy schéma mqtt:// — zda broker vyžaduje TLS, určuje prostředí). Přihlaste se k topicu queueName doslovně, včetně úvodního lomítka a bez zástupných znaků (#, +) — uživatel brokeru má oprávnění jen na přesně tento topic. APEX publikuje s QoS 1, bez retain; zda se vám uchovají zprávy publikované během výpadku spojení, závisí na brokeru a nastavení vaší MQTT session (clean / persistent session).password a úplné mqttUrl se vrátí jen v této odpovědi; na serveru je uložen pouze hash hesla. Při ztrátě hesla přístup smažte a vytvořte nový — vznikne nové heslo.409 — MQTT přístup pro tenanta už existuje (nejprve ho smažte)400 — přístup se na brokeru nepodařilo zřídit; zopakujte později401mqttUrl — nepoužívejte v nových integracích204; 404, pokud přístup neexistuje.Přehled provozu tenanta (statistiky odeslaných a přijatých dokumentů), historie statistických hlášení EUSR/TSR do OpenPeppol a stav licence s měsíčním čerpáním dokumentů.
/reporting/statistics jsou spolehlivé živé počty delivered, failed, topRecipients, topSenders a failedDocuments; agregované total, byDocumentType, byCountry a deliveryRate jsou zatím nulové nebo prázdné. /reporting/submissions zatím nevrací záznamy. Pro přesná čísla o vašich dokumentech použijte /api/v1/licenses/info (měsíční čerpání) a vlastní evidenci stavů.period=month / quarter / year — aktuální kalendářní měsíc, čtvrtletí, rok.from + to (oba, YYYY-MM-DD) — vlastní interval, period se ignoruje a v odpovědi je type=custom. Pokud pošlete jen jeden z nich, ignoruje se.period vždy uvádí přesně použitý rozsah.sent / received: total, delivered, failed (FAILED + DEAD_LETTER), deliveryRate (0.0–1.0, null při nule), byDocumentType (klíče INVOICE, CREDIT_NOTE, ORDER, ORDER_RESPONSE, DESPATCH_ADVICE…), byCountry (země protistrany).deliveryRate na nejvyšší úrovni počítá jen odeslané dokumenty.topRecipients / topSenders — nejvýše 10 partnerů (name, peppolId v kanonickém tvaru, countryCode, count).failedDocuments — dokumenty, které jsou právě v chybovém stavu (bez ohledu na období, oba směry): total, deadLetters, retrying, rejected.400 — from po to nebo neznámé period401 / 403errorMessage), zopakuje sereportType (EUSR/TSR), status, offset (výchozí 0), limit (výchozí 20, 1–100). Např. ?reportType=EUSR&status=FAILED.items[]: id, reportType, periodStart, periodEnd, reporterId, status, errorMessage, submittedAt, validatedAt, createdAt; dále total, offset, limit. Chyba 400 při neznámé hodnotě filtru.maxDocuments je měsíční (-1 = neomezený). Všechny počty v documentUsage se týkají aktuálního kalendářního měsíce v UTC (periodStart–periodEnd). usedDocuments = odeslané + přijaté, každá uložená zpráva bez ohledu na stav (i QUEUED a FAILED).limitExceeded: true odesílání i příjem fungují dál — je to signál k navýšení licence. Počítadla se vynulují začátkem dalšího měsíce. Neplatná licence (valid: false) však odesílání blokuje (REJECTED, resp. 403 LICENCE_INVALID).serialNumber, companyName, branchName, licenseTypeCode, validFrom, validTo (formát 2026-01-01T00:00:00.000+0000), valid, autoProlong a documentUsage: maxDocuments, usedDocuments, remainingDocuments (-1 = neomezeně), usagePercentage (null u neomezené), limitExceeded, sentDocuments, receivedDocuments, periodStart, periodEnd.404 (prázdné tělo) — tenant nemá aktivní licenci; licence po platnosti vrátí 200 s valid: false401
Autentizace podle SAPI-SK v1.0. APEX žádost přepošle do ASOL IAM (OAuth 2.0 client_credentials) a k IAM access tokenu
přidá vlastní refresh token (30 dní, rotace při každém použití), takže klient nemusí při každém obnovení posílat
client_secret. Access token ze SAPI platí i pro APEX API (/api/**) a naopak.
Pole těchto endpointů jsou ve snake_case; /token, /renew a /revoke jsou veřejné (bez Bearer tokenu).
client_id + client_secret za access token (JWT RS256 z ASOL IAM) a refresh token APEX.Content-Type: application/json; application/x-www-form-urlencoded vrátí 415). APEX přepošle údaje do IAM a vrátí jeho access token spolu s novým refresh tokenem. Platnost access tokenu udává pole expires_in./renewscope je volitelný a přepošle se do IAM; o přístupu k dokumentům a účastníkům rozhoduje tenant, ke kterému jsou údaje klienta vázané.400/401 SAPI-AUTH-001 — IAM odmítl údaje (stav vrací IAM)400 — nečitelné JSON tělo (Problem Details)415 — jiný Content-Type než JSON500 SAPI-AUTH-999 — IAM nedostupný nebo interní chyba; zopakujte pozdějiclient_credentialsAuthorization: BearerBearernullAuthorization: platnost, zbývající čas a doporučení obnovit.X-Peppol-Participant-Id není potřeba). should_refresh je true, když do vypršení zbývají méně než 3 minuty.expires_in401 SAPI-AUTH-002 — token chybí, je neplatný nebo vypršel200 vždy trueaccesssub; u klientského tokenu UUID)/token.401 SAPI-AUTH-006 a z bezpečnostních důvodů zneplatní všechny refresh tokeny daného klienta (již vydané access tokeny doběhnou do své expirace). Klient se pak musí přihlásit přes /token. U více instancí klienta proto refresh token sdílejte, nebo ať má každá instance vlastní.401 SAPI-AUTH-007 — refresh token je neplatný, poškozený nebo vypršel401 SAPI-AUTH-006 — refresh token už byl použit nebo zneplatněnSAPI-AUTH-001 — IAM odmítl uložené údaje klienta (např. změněné client_secret)500 SAPI-AUTH-999 — interní chyba nebo IAM nedostupný/token — nová dvojice tokenůclient_id/client_secret./renew s ním vrátí 401. Opakované zneplatnění již neplatného tokenu vrátí také 200 ("Token was already invalid or expired"). Jiný token APEX přepošle k revokaci do IAM.client_secret.SAPI-AUTH-001 — IAM odmítl revokaci jiného tokenu500 SAPI-AUTH-999 — IAM nedostupnýrefresh_token200 vždy trueRefresh token revoked successfully
Tři operace podle SAPI-SK v1.0: odeslat, přijmout, potvrdit. Každý request nese hlavičku
X-Peppol-Participant-Id (organizační kontext — účastník vašeho tenanta; krátký i kanonický tvar).
Pole dokumentových endpointů jsou v camelCase; neznámá pole se tiše ignorují, proto dodržte přesné názvy.
200 ACCEPTED = převzetí do úschovy, 4xx/5xx REJECTED = nic se nezařadilo.ACCEPTEDmetadata, payload, payloadFormat (jen XML), payloadEncoding (jen UTF-8), volitelný checksum.metadata.senderParticipantId patří vašemu tenantovi a jsou totožní; tenant má platnou licenci.documentTypeId.documentTypeId + processId přes AS4.providerDocumentId — je to UUID dokumentu v APEX, takže se stejným tokenem můžete sledovat doručení přes GET /api/v1/documents/{providerDocumentId}/status, /events nebo webhooky.Idempotency-Key, povinná)ACCEPTED (stejné providerDocumentId a receivedAt), nic se nezařadí podruhé. Jiný request → 409 IDEMPOTENCY_CONFLICT. První request ještě běží → 409 IDEMPOTENCY_IN_PROGRESS (opakujte se stejným klíčem). Odmítnutý request klíč nespotřebuje. Po 24 h se klíč chová jako nový — neopakujte tedy staré requesty po dni.error.retryable true (409 IDEMPOTENCY_IN_PROGRESS, 503, 500, 429), s exponenciálním odstupem a stejným Idempotency-Key. Při kontaktu s podporou uveďte error.correlation_id.metadata.senderParticipantId0245:1234567890 nebo kanonický tvar)XMLUTF-8 (výchozí)payload, hex (64 znaků)ACCEPTED — převzetí, ne doručeníREJECTEDcategory, code, message, details[], retryable, correlation_id| HTTP | errorCode | error.code | retryable | Příčina |
|---|---|---|---|---|
| 400 | INVALID_REQUEST | SAPI-VAL-001 | ne | chybí/prázdná hlavička Idempotency-Key (nebo > 200 znaků) či X-Peppol-Participant-Id; tělo není platný JSON; neplatné creationDateTime |
| 400 | INVALID_METADATA | SAPI-VAL-001 | ne | chybí metadata nebo některý z identifikátorů, případně obsahuje řídicí znaky |
| 400 | PAYLOAD_MISSING | SAPI-VAL-001 | ne | chybí payload (např. tělo podle specifikace document{content}) |
| 400 | INVALID_DOCUMENT_FORMAT | SAPI-VAL-001 | ne | payloadFormat není XML, payloadEncoding není UTF-8, nesedí checksum |
| 400 | INVALID_DOCUMENT_FORMAT | SAPI-VAL-002 | ne | payload není well-formed XML |
| 400 | UNSUPPORTED_DOCUMENT_TYPE | SAPI-VAL-002 | ne | pro documentTypeId neexistují validační pravidla |
| 400 | DOCUMENT_VALIDATION_FAILED | SAPI-VAL-002 | ne | chyby XSD, Schematronu, business pravidel nebo stran; seznam v error.details[] (field = umístění, issue = popis, value = kód pravidla) |
| 400 | RECEIVER_NOT_FOUND | SAPI-VAL-021 | ne | příjemce není v síti Peppol (v sandboxu není účastníkem sandboxu) |
| 400 | UNSUPPORTED_DOCUMENT_TYPE | SAPI-VAL-021 | ne | příjemce nenabízí typ dokumentu a proces přes AS4 |
| 403 | AUTHORIZATION_FAILED | SAPI-AUTH-007 | ne | účastník z hlavičky nebo odesílatel nepatří vašemu tenantovi, nebo se navzájem liší |
| 403 | AUTHORIZATION_FAILED | SAPI-AUTH-008 | ne | tenant nemá platnou licenci |
| 409 | IDEMPOTENCY_CONFLICT | SAPI-VAL-010 | ne | klíč použitý pro jiný request — použijte nový klíč |
| 409 | IDEMPOTENCY_IN_PROGRESS | SAPI-VAL-010 | ano | request se stejným klíčem se právě zpracovává |
| 503 | SERVICE_UNAVAILABLE | SAPI-PROC-002 | ano | dočasně nedostupné SML/SMP, validace nebo úložiště |
| 500 | PROCESSING_ERROR | SAPI-PROC-001 | ano | neočekávaná chyba |
/sapi/v1/document/send (specifikace: /sapi/v1/documents), identifikátor providerDocumentId (specifikace: apDocumentId), dokument v plochých polích payload, payloadFormat, payloadEncoding (specifikace: document{content, format, encoding} — takové tělo skončí PAYLOAD_MISSING), navíc povinné hlavičky X-Peppol-Participant-Id a Idempotency-Key a kontroly 3–5 nad rámec minima specifikace. Odpovědi 401 a 429 mají pouze obálku error (bez status); 415, 405 a 406 mají formát Problem Details (RFC 9457) — rozhodujte podle HTTP kódu.pageToken. Hodnotu nextPageToken z odpovědi pošlete jako query parametr pageToken dalšího volání; nextPageToken: null = poslední stránka. Kurzor je neprůhledný řetězec — neparsujte ho ani neskládejte. Pro všechny stránky jednoho průchodu zachovejte status, limit a hlavičku. Parametr nextPageToken se přijme jako alias pageToken (pokud pošlete oba, musí být stejné).status=RECEIVED400 SAPI-VAL-001 — neplatný pageToken, rozdílné pageToken/nextPageToken, záporný limit400 (Problem Details) — chybí hlavička nebo limit není číslo401 SAPI-AUTH-002, 403 SAPI-AUTH-007 — účastník nepatří vašemu tenantovi429 SAPI-RATE-001nextPageToken předchozí odpovědiRECEIVED nebo ACKNOWLEDGEDiso6523-actorid-upis::…nullStandardBusinessDocument (obálka SBDH s business dokumentem) jako XML řetězec.payload je StandardBusinessDocument tak, jak přišel sítí Peppol, znovu serializovaný — prefixy jmenných prostorů a formátování se mohou lišit od originálu. Business dokument najděte podle jmenného prostoru, parsujte s ohledem na jmenné prostory a nevalidujte kořen přímo vůči UBL XSD. Stažení stav nemění.404 (prázdné tělo) — ID není UUID nebo dokument neexistuje403 SAPI-AUTH-009 — dokument není adresován účastníkovi z hlavičky400 SAPI-DOC-002 — nejde o přijatý dokument vašeho tenanta401 SAPI-AUTH-002, 429 SAPI-RATE-001documentId, documentTypeId, processId, senderParticipantId, receiverParticipantId, creationDateTime)StandardBusinessDocument jako UTF-8 XML řetězecXMLACKNOWLEDGED. Idempotentní.status=RECEIVED200 s původním časem potvrzení404 (prázdné tělo) — dokument neexistuje nebo není váš403 SAPI-AUTH-009 — dokument není adresován účastníkovi z hlavičky409 SAPI-DOC-002 — jde o odeslaný, ne přijatý dokumentdocumentId ze seznamu (path); tělo se neposíláACKNOWLEDGED/api/v1, /api/v2) je plné REST API: odesílání (i hromadné), příjem, validace, precheck, stav, události, odpovědi (MLR/IMR/MLS), webhooky a MQTT, vyhledání účastníků, statistiky a licence. Token z ASOL IAM (client_credentials)./sapi/v1) je zjednodušené rozhraní podle slovenské specifikace SAPI-SK v1.0: odeslat, přijmout, potvrdit. Odesílání je také asynchronní — ACCEPTED znamená převzetí, ne doručení — ale všechny kontroly (dokument, příjemce v síti Peppol) proběhnou synchronně v rámci requestu. Vlastní auth endpointy s refresh tokenem; stejný access token funguje i na APEX API./api/v1/documents/{id}/status nebo webhooky.<ICD>:<hodnota> (např. 0245:2024000001) a kanonický tvar iso6523-actorid-upis::0245:2024000001 jsou v requestech zaměnitelné. Odpovědi v1 inboxu a notifikace používají kanonický tvar, v2 inbox a lookup krátký.0245 (SK:DIČ) — slovenské DIČ má 10 číslic bez prefixu SK. Další běžná schémata: 9950 SK IČ DPH, 9929 CZ VAT, 9914 AT VAT, 9919 AT register, 9930 DE VAT, 9910 HU VAT, 0088 GLN, 0007 SE org. číslo, 0200 LT kód./participants/lookup/ico ho přes slovenský Registr účetních závěrek převede na DIČ.QUEUED → PROCESSING → DELIVERED (→ případně FAILED po negativním MLS)PROCESSING → RETRYING → PROCESSING → … → DELIVERED nebo DEAD_LETTERSENT je v číselníku, při odesílání se však nepoužívá.DELIVERED znamená doručení do přístupového bodu příjemce (Peppol corner 3), ne zpracování v jeho ERP — to signalizují až aplikační odpovědi (IMR) a MLS.VALIDATED (validace prošla, čeká na stažení, notifikace DOCUMENTS_RECEIVED) → ACKNOWLEDGED (váš systém potvrdil). REJECTED = dokument neprošel validací (je v seznamu, notifikace nepřijde), FAILED = chyba zpracování. RECEIVED je jen vnitřní mezistav během příjmu.RECEIVED (přijaté a zvalidované, čeká na potvrzení) → ACKNOWLEDGED; zamítnuté dokumenty SAPI nezobrazuje. Potvrzení je společné pro APEX API i SAPI.PEPPOL-EN16931-R*)documentTypeId a cbc:CustomizationID: Peppol BIS Billing 3.0 (faktura, dobropis, samofakturace), národní varianty PINT, německá XRechnung, objednávky (Order, Order Response) a další Peppol BIS dokumenty. Při více verzích stejné sady se použije nejvyšší. Stejná validace běží v /validate, /precheck, /send, dávkách i SAPI.urn:peppol:edec:mls) — technický stav zprávy, který posílá přijímající přístupový bod odesílajícímu. APEX při odesílání žádá MLS pro každý dokument; pozitivní (AP/AB) → notifikace MLS_RECEIVED, negativní (RE) → dokument přejde na FAILED a přijde MLS_RECEIVED_NEGATIVE. Příjem MLS je v síti Peppol povinný od 28. 2. 2027 a odesílání od 31. 3. 2027 — do té doby ho některé přístupové body ještě nevracejí, chybějící MLS tedy není chyba.GET /api/v1/documents/{id}/responses.ublDocument, SAPI payload) je celý StandardBusinessDocument — obálka SBDH (http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader) s UBL dokumentem uvnitř, přesně jak přišel sítí. Business dokument hledejte podle jmenného prostoru (např. urn:oasis:names:specification:ubl:schema:xsd:Invoice-2), ne jako kořen.cac:, cbc: ani jiné prefixy se nemusí shodovat mezi verzemi ani v rámci jednoho dokumentu — používejte namespace-aware parser (XPath s registrovanými jmennými prostory, JAXB, XmlReader s NamespaceURI…).POST /api/v1/documents/send — hlavička Idempotency-Key volitelná; klíč platí 24 h; porovnává se obsah (dokument a směrovací metadata).POST /api/v1/batches — volitelná, doporučená; klíč neexpiruje; porovnávají se bajty těla (SHA-256).POST /sapi/v1/document/send — povinná; klíč platí 24 h; porovnává se payload a metadata (odesílatel, příjemce, typ, proces).409 IDEMPOTENCY_CONFLICT; souběžně běžící request se stejným klíčem → 409 IDEMPOTENCY_IN_PROGRESS (zopakujte později). Odmítnutý request klíč nespotřebuje. Při timeoutu vždy opakujte se stejným klíčem.RETRYING a worker ho zkusí znovu. Dokument má 5 pokusů; po 1. až 4. selhání přijde další pokus za 30, 60, 120 a 240 s, páté selhání znamená DEAD_LETTER — celkem zhruba 7,5 minuty plus čas přenosů (AS4 timeout je 120 s). Trvalé chyby (např. certifikát příjemce nevydaný CA OpenPeppol) jdou do DEAD_LETTER hned. Každý pokus vytvoří události QUEUE_PROCESSING_STARTED a při selhání QUEUE_PROCESSING_FAILED (Attempt n/5 failed, retry in …s: <příčina>). Dokument v DEAD_LETTER vyžaduje zásah — kontaktujte podporu s documentId; po nápravě ho může zařadit znovu (událost QUEUE_MANUAL_REQUEUE, bez notifikace)./api/v1, /api/v2). Publikovaná verze se nikdy nemění zpětně nekompatibilně — nový formát vzniká pod novou verzí a předchozí funguje dál. Dnes má verzi v2 jen příjem (GET /api/v2/documents/inbox a detail) — liší se pouze krátkým tvarem identifikátorů. Všechny ostatní endpointy jsou jen ve v1. Klienti mají ignorovat neznámá pole v odpovědích a neznámé hodnoty eventType.| Dokument | documentTypeId | processId |
|---|---|---|
| Faktura (BIS Billing 3.0) | 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 | urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 |
| Dobropis (BIS Billing 3.0) | urn:oasis:names:specification:ubl:schema:xsd:CreditNote-2::CreditNote##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0::2.1 | urn:fdc:peppol.eu:2017:poacc:billing:01:1.0 |
| Samofaktura (Self-billing 3.0) | urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:selfbilling:3.0::2.1 | urn:fdc:peppol.eu:2017:poacc:selfbilling:01:1.0 |
| Objednávka (BIS Order Only 3) | urn:oasis:names:specification:ubl:schema:xsd:Order-2::Order##urn:fdc:peppol.eu:poacc:trns:order:3::2.1 | urn:fdc:peppol.eu:poacc:bis:order_only:3 |
| Odpověď na objednávku (BIS Ordering 3) | urn:oasis:names:specification:ubl:schema:xsd:OrderResponse-2::OrderResponse##urn:fdc:peppol.eu:poacc:trns:order_response:3::2.1 | urn:fdc:peppol.eu:poacc:bis:ordering:3 |
| Odpověď na fakturu (IMR, Invoice Response 3) | urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:fdc:peppol.eu:poacc:trns:invoice_response:3::2.1 | urn:fdc:peppol.eu:poacc:bis:invoice_response:3 |
| MLR (Message Level Response 3) | urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:fdc:peppol.eu:poacc:trns:mlr:3::2.1 | urn:fdc:peppol.eu:poacc:bis:mlr:3 |
| MLS (Message Level Status) — posílá APEX | urn:oasis:names:specification:ubl:schema:xsd:ApplicationResponse-2::ApplicationResponse##urn:peppol:edec:mls:1.0::2.1 | urn:peppol:edec:mls |
Všechny endpointy kromě /sapi/v1/auth/token, /renew a /revoke vyžadují hlavičku
Authorization: Bearer <access_token>. Access token je JWT podepsaný (RS256) serverem ASOL IAM a získáte ho
grantem client_credentials (server-to-server, bez přihlášení uživatele) — přímo z IAM, nebo přes SAPI endpoint,
který navíc vydá refresh token. Výsledný token je stejný a platí pro APEX API i SAPI.
| A) Přímo z ASOL IAM | B) Přes SAPI | |
|---|---|---|
| Endpoint | POST https://iam.qasida.sk/oauth2/token | POST /sapi/v1/auth/token |
| Formát | application/x-www-form-urlencoded | application/json |
| Access token | JWT, platnost podle expires_in | stejný JWT z IAM |
| Refresh token | ne — nový token vždy přes client_credentials | ano, 30 dní, rotace přes /sapi/v1/auth/renew |
| Doporučeno pro | APEX API, Swagger UI (Authorize) | SAPI integrace podle SAPI-SK v1.0 |
client_credentials z IAM nebo /sapi/v1/auth/token
Authorization: Bearer <token> v každém requestu
před vypršením nový client_credentials nebo /renew
/sapi/v1/auth/revoke pro refresh token
clientId, clientSecret) jsou vázané na jednu organizaci (tenanta) v APEX — token určuje, ke kterým dokumentům a účastníkům máte přístup. Access token obnovujte s rezervou (např. 1–3 min před expires_in), jeden token používejte pro všechny requesty po dobu jeho platnosti a při 401 si vyžádejte nový. APEX ověřuje token lokálně (podpis a platnost), revokace access tokenu ho proto před vypršením nezruší. Parametr scope není potřeba — přístup určuje tenant.POST https://iam.qasida.sk/oauth2/token
Content-Type: application/x-www-form-urlencoded
grant_type=client_credentials
&client_id=your-client-id
&client_secret=your-client-secret
HTTP/1.1 200 OK
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900
}
POST /sapi/v1/auth/token
Content-Type: application/json
{
"client_id": "your-client-id",
"client_secret": "your-client-secret",
"grant_type": "client_credentials"
}
HTTP/1.1 200 OK
{
"access_token": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"token_type": "Bearer",
"expires_in": 900,
"scope": null,
"refresh_token": "eyJhbGciOiJIUzI1NiJ9..."
}
POST /sapi/v1/auth/renew
Content-Type: application/json
{ "refresh_token": "eyJhbGciOiJIUzI1NiJ9..." }
GET /api/v2/documents/inbox?status=VALIDATED Authorization: Bearer eyJhbGciOiJSUzI1NiIs... Accept: application/json
Jak vypadají chybové odpovědi, které chyby má smysl opakovat, jaké limity platí a na co si dát pozor při návrhu klienta. Rozhodujte vždy podle HTTP kódu a strojového kódu chyby, ne podle textu zprávy.
/api/**timestamp, status, error, message a zpravidla path. Strojový code mají dávky a idempotence (INVALID_IDEMPOTENCY_KEY, IDEMPOTENCY_CONFLICT, IDEMPOTENCY_IN_PROGRESS, BATCH_*, PARTICIPANT_NOT_AUTHORIZED, LICENCE_INVALID, TOO_MANY_OPEN_BATCHES); u ostatních chyb je message jen informativní text. /documents/send při neúspěšné validaci vrací error: "Validation Error" s validationErrors[] a validationWarnings[] (code, message, location). Chyby frameworku (nečitelný JSON, špatný typ parametru, chybějící parametr, 405/415) mají formát Problem Details (type, title, status, detail, instance). 404 pro neexistující nebo cizí zdroj má prázdné tělo. timestamp je bez časové zóny (UTC).{
"timestamp": "2026-10-09T10:15:00.123",
"status": 409,
"error": "Conflict",
"code": "IDEMPOTENCY_CONFLICT",
"message": "Idempotency-Key 'FA2026-0001' was already used for a different request (document or routing metadata)",
"path": "/api/v1/documents/send"
}
{
"timestamp": "2026-10-09T19:31:24.544",
"status": 401,
"error": "Unauthorized",
"message": "Missing or malformed Authorization: Bearer header",
"path": "/api/v1/documents/send"
}
/sapi/**error: category (AUTH, VALIDATION, PROCESSING, TEMPORARY), code (SAPI-…), message, details[] (nebo null), retryable a correlation_id (uveďte ho podpoře). Odmítnutí odeslání ho obaluje do status: REJECTED s errorCode. Odpovědi 415, 405, 406 a chybějící hlavička při příjmu mají formát Problem Details (RFC 9457); 404 u detailu a potvrzení má prázdné tělo.{
"error": {
"category": "AUTH",
"code": "SAPI-AUTH-002",
"message": "Access token is invalid or has expired",
"details": null,
"retryable": false,
"correlation_id": "c3d4e5f6-a7b8-9012-cdef-345678901234"
}
}
| HTTP | Význam | Co udělat |
|---|---|---|
| 200 / 201 / 202 / 204 | Úspěch; 202 = převzato k asynchronnímu zpracování | U 202 sledujte stav (/status, notifikace) |
| 400 | Neplatný request nebo dokument. Zvláštní případ: Invalid UUID string: anonymousUser znamená token bez tenanta (např. token uživatele místo integračního klienta) | Opravte request; neopakujte bez změny |
| 401 | Chybějící, neplatný nebo expirovaný token (hlavička musí začínat přesně Bearer ) | Získejte nový token a request zopakujte jednou |
| 403 | Účastník nepatří vašemu tenantovi, neplatná licence, tenant z tokenu není v APEX založen (Authenticated tenant not found) | Zkontrolujte Peppol ID, licenci (/api/v1/licenses/info) a přístupové údaje |
| 404 | Zdroj neexistuje nebo patří jinému tenantovi (záměrně nerozlišeno) | Zkontrolujte ID a prostředí |
| 409 | Konflikt idempotence, stav neumožňuje operaci | IDEMPOTENCY_IN_PROGRESS zopakujte později; ostatní řešte |
| 413 | Příliš velká dávka | Rozdělte dávku |
| 415 | Nesprávný Content-Type | Posílejte application/json (ZIP dávka application/zip) |
| 429 | Překročený rate limit nebo kapacita příjmu dávek | Počkejte podle Retry-After, pak exponenciální odstup |
| 500 / 503 | Neočekávaná nebo dočasná chyba | Opakujte s exponenciálním odstupem a stejným Idempotency-Key |
| Endpointy | Limit |
|---|---|
| POST /sapi/v1/document/send | 100 requestů / min / IP (vlastní limit) |
| všechny ostatní /api/** a /sapi/** (včetně /sapi/v1/auth/*) | 200 requestů / min / IP (společný limit) |
X-RateLimit-Limit a X-RateLimit-Remaining; při 429 i Retry-After (sekundy do dalšího volného requestu). Rate limit se vyhodnocuje před autentizací, takže se počítají i neúspěšné requesty. Hromadné odesílání má navíc vlastní limity (3 otevřené dávky, BATCH_INTAKE_BUSY).HTTP/1.1 429 Too Many Requests
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 0
Retry-After: 1
{
"error": {
"category": "TEMPORARY",
"code": "SAPI-RATE-001",
"message": "Rate limit exceeded. Maximum 100 requests per minute per IP address.",
"retryable": true,
"correlation_id": "f1a2b3c4-d5e6-7890-abcd-ef1234567890"
}
}
/api/** má tělo 429 tvar chyby APEX API: {"timestamp", "status": 429, "error": "Too Many Requests", "message", "path"}. Limity se uplatňují pro každou instanci služby samostatně — berte je jako horní orientační limit, ne jako garantovanou kapacitu.429, 500, 503 a timeoutu opakujte s exponenciálním odstupem (např. 2, 4, 8, 16 s + náhodný jitter). Odesílací requesty posílejte vždy s Idempotency-Key a při opakování se stejným klíčem — tak fakturu nikdy neodešlete dvakrát.eventType či stavů — API se rozšiřuje zpětně kompatibilně. Časy parsujte jako ISO 8601 s posunem a porovnávejte okamžiky, ne řetězce (počet desetinných míst se liší). XML payload parsujte s ohledem na jmenné prostory.clientSecret, refresh token a MQTT heslo ukládejte v trezoru tajemství, ne v kódu ani v lozích. Webhooky nejsou podepsané — ověřujte je tajemstvím v customHeaders a obsah si vždy načtěte z API podle documentId. Notifikace berte jako signál, ne jako zdroj pravdy.
Konkrétní requesty a odpovědi pro klíčové scénáře. $APEX je základní URL prostředí
(např. https://api.sandbox.apex.qasida.sk), $TOKEN access token.
XML dokumenty jsou v příkladech zkrácené.
curl -X POST "$APEX/api/v1/documents/send" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: FA2026-0001" \
-d @faktura.json
{
"senderParticipantId": "0245:2024000001",
"receiverParticipantId": "0245:1234567890",
"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",
"ublDocument": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" ...>...</Invoice>"
}
{
"documentId": "550e8400-e29b-41d4-a716-446655440000",
"status": "QUEUED",
"submittedAt": "2026-10-09T10:30:00"
}
{
"timestamp": "2026-10-09T10:30:00",
"status": 400,
"error": "Validation Error",
"message": "Document validation failed: 1 error(s)",
"validationErrors": [
{
"code": "BR-02",
"message": "An Invoice shall have an Invoice number (BT-1).",
"location": "/Invoice/cbc:ID"
}
],
"validationWarnings": []
}
{
"networkReady": true,
"valid": true,
"participantExists": true,
"canSend": true,
"errors": [],
"warnings": [
{
"category": "ROUTING",
"code": "CERT_EXPIRING_SOON",
"message": "Recipient AP certificate expires in 18 days (2026-10-27). Sending is still possible.",
"location": null
}
],
"checkedAt": "2026-10-09T11:00:00+02:00"
}
{
"networkReady": false,
"valid": true,
"participantExists": false,
"canSend": false,
"errors": [
{
"category": "PARTICIPANT",
"code": "PARTICIPANT_NOT_FOUND",
"message": "Participant '0245:9999999999' was not found in the Peppol network.",
"location": null
}
],
"warnings": [],
"checkedAt": "2026-10-09T11:00:00+02:00"
}
{
"source": "SMP",
"participantId": "iso6523-actorid-upis::0245:2024000001",
"peppolId": "0245:2024000001",
"organizationName": null,
"countryCode": "SK",
"endpointUrl": "https://ap.partner.example.com/as4/receive",
"smpUrl": "https://smp.partner.example.com/",
"enabled": true,
"certificate": {
"subject": "CN=PSK000202,OU=PEPPOL PRODUCTION AP,O=Partner SK s.r.o.,C=SK",
"issuer": "CN=PEPPOL ACCESS POINT CA - G2,O=OpenPEPPOL AISBL,C=BE",
"serial": "7f3a1b2c9d0e4f56",
"fingerprint": "FF:EE:DD:CC:...:00",
"notBefore": "2025-03-01T00:00:00Z",
"notAfter": "2027-03-01T23:59:59Z",
"expired": false,
"valid": true,
"invalidReason": null
},
"smpMetadataUpdatedAt": "2026-10-09T10:15:30Z"
}
[
{
"id": "d3a1e2f0-11aa-42bb-9c3d-000000000003",
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "MESSAGE_QUEUED",
"eventCode": null,
"eventMessage": "Document queued for async AS4 sending to https://receiver.example.com/as4",
"technicalDetails": null,
"stacktrace": null,
"createdAt": "2026-10-09T10:30:01+02:00"
},
{
"id": "d3a1e2f0-11aa-42bb-9c3d-000000000004",
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "QUEUE_PROCESSING_FAILED",
"eventCode": null,
"eventMessage": "Attempt 1/5 failed, retry in 30s: AS4 send returned failure",
"technicalDetails": null,
"stacktrace": null,
"createdAt": "2026-10-09T10:30:04+02:00"
},
{
"id": "d3a1e2f0-11aa-42bb-9c3d-000000000006",
"messageId": "550e8400-e29b-41d4-a716-446655440000",
"eventType": "MESSAGE_DELIVERED",
"eventCode": null,
"eventMessage": "Message delivered successfully",
"technicalDetails": null,
"stacktrace": null,
"createdAt": "2026-10-09T10:30:40+02:00"
}
]
{
"name": "ERP Invoice Inbox",
"description": "Notifikace o nových fakturách",
"url": "https://erp.example.com/webhooks/peppol",
"active": true,
"documentTypeFilters": [
"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"
],
"senderParticipantFilters": [],
"customHeaders": { "X-Webhook-Secret": "sdilene-tajemstvi" }
}
POST https://erp.example.com/webhooks/peppol
Content-Type: application/json
User-Agent: Apex-Webhook/1.0
X-Webhook-Secret: sdilene-tajemstvi
{
"eventType": "DOCUMENTS_RECEIVED",
"subscriptionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"documentId": "550e8400-e29b-41d4-a716-446655440001",
"documentIds": ["550e8400-e29b-41d4-a716-446655440001"],
"receivedCount": 1,
"direction": "IN",
"status": "VALIDATED",
"messageId": "c3a1e7f2-5b9d-4d2e-8f41-2a6b9e0d7c15@sender-ap.example.com",
"senderParticipantId": "iso6523-actorid-upis::0245:1234567890",
"receiverParticipantId": "iso6523-actorid-upis::0245:2024000001",
"documentTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##...::2.1",
"processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"eventMessage": "Incoming Peppol document received",
"notifiedAt": 1791282005.123456000
}
{
"documentId": "550e8400-e29b-41d4-a716-446655440001",
"senderParticipantId": "0245:1234567890",
"receiverParticipantId": "0245:2024000001",
"documentTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##...::2.1",
"processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"receivedAt": "2026-10-09T09:15:00",
"status": "VALIDATED",
"ublDocument": "<StandardBusinessDocument xmlns=\"http://www.unece.org/cefact/namespaces/StandardBusinessDocumentHeader\"><StandardBusinessDocumentHeader>...</StandardBusinessDocumentHeader><Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\">...</Invoice></StandardBusinessDocument>"
}
curl -X POST "$APEX/api/v1/documents/inbox/550e8400-e29b-41d4-a716-446655440001/acknowledged" \ -H "Authorization: Bearer $TOKEN" HTTP/1.1 204 No Content
curl -X POST "$APEX/api/v1/batches" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: ERP-run-2026-10-09-17" \
-H "Expect: 100-continue" \
--data-binary @davka.json
{
"clientReference": "ERP-run-2026-10-09-17",
"notify": "BATCH",
"documents": [
{
"clientReference": "FA2026-0001",
"senderParticipantId": "0245:2024000001",
"receiverParticipantId": "0245:1234567890",
"documentTypeId": "urn:oasis:names:specification:ubl:schema:xsd:Invoice-2::Invoice##...::2.1",
"processId": "urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
"ublDocument": "<Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\">...</Invoice>"
}
]
}
{
"batchId": "6f1c2a9e-0b7d-4f3a-9c55-2b8e1f0d4a11",
"clientReference": "ERP-run-2026-10-09-17",
"status": "RECEIVED",
"itemCount": 1000,
"receivedAt": "2026-10-09T10:15:00Z"
}
{
"eventType": "BATCH_PROCESSED",
"subscriptionId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
"eventMessage": "Batch processed: 990 accepted, 10 rejected, 0 cancelled",
"notifiedAt": 1791281700.482913000,
"batch": {
"batchId": "6f1c2a9e-0b7d-4f3a-9c55-2b8e1f0d4a11",
"clientReference": "ERP-run-2026-10-09-17",
"status": "PROCESSED",
"itemCount": 1000,
"accepted": 990,
"rejected": 10,
"cancelled": 0
}
}
POST /sapi/v1/document/send
Authorization: Bearer eyJhbGciOiJSUzI1NiIs...
Content-Type: application/json
Idempotency-Key: 3f6c1d2e-8a4b-4c5d-9e0f-112233445566
X-Peppol-Participant-Id: 0245:2024000001
{
"metadata": {
"documentId": "FA2026-0001",
"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:2024000001",
"receiverParticipantId": "0245:1234567890",
"creationDateTime": "2026-10-09T10:30:00Z"
},
"payload": "<?xml version=\"1.0\" encoding=\"UTF-8\"?><Invoice xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Invoice-2\" ...>...</Invoice>",
"payloadFormat": "XML",
"payloadEncoding": "UTF-8",
"checksum": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"
}
{
"providerDocumentId": "7c9d0e1f-2a3b-4c5d-8e6f-0a1b2c3d4e5f",
"status": "ACCEPTED",
"receivedAt": "2026-10-09T08:30:05.123456Z",
"timestamp": "2026-10-09T08:30:05.130Z"
}
{
"status": "REJECTED",
"timestamp": "2026-10-09T08:30:05Z",
"errorCode": "RECEIVER_NOT_FOUND",
"errorMessage": "The receiver is not registered in the Peppol network for this document type (The SML has no SMP address for the participant)",
"error": {
"category": "VALIDATION",
"code": "SAPI-VAL-021",
"message": "The receiver is not registered in the Peppol network for this document type (The SML has no SMP address for the participant)",
"details": null,
"retryable": false,
"correlation_id": "e5f6a7b8-c9d0-1234-ef01-567890123456"
}
}