Pro SaaS, ERP a platformy

Vestavte Peppol e-fakturaci do svého produktu

Integrujete se jednou a obsluhujete neomezeně mnoho svých zákazníků. Vlastní certifikovaný slovenský Peppol Access Point, REST API, podepsané webhooky, veřejný sandbox a white-label v ceně. Tato stránka je kompletní technický návod: od registrace přes onboarding firem až po odesílání a příjem dokladů.

Certifikovaný PA SK · EFSK000031Vlastní Peppol AP · Seat PSK001128OpenAPI 3.1 + veřejný sandboxNárodní rozhraní SAPI-SK

Architektura

Model integrace: jeden token, N vašich zákazníků

Model je proxy / multi-tenant: váš backend drží jeden API token (vpt_…) výhradně na serveru a každý váš zákazník je u nás jedna firma (tenant). Všechna volání dělá váš server. Token nikdy nepatří do prohlížeče ani do mobilní aplikace. Kterou firmu volání obsluhuje, určíte u dokladů hlavičkou X-Peppol-Participant-Id, u správy firem přímo ID firmy v cestě.

1 · Portálové REST API

Správa tenantů: založení firmy, ověření odesílání, webhooky, seznamy dokladů, stahování XML/PDF/doručenek, exporty. Auth: Authorization: Bearer vpt_… přímo.

2 · SAPI-SK 1.0

Národní standardizované rozhraní na samotné doklady: odesílání (i dávkové), příjem, stav doručení. Auth: OAuth2 client_credentials (client_id = UUID tokenu, client_secret = vpt_… token).

3 · Webhooky k vám

Při přijaté / odeslané faktuře voláme vaši URL podepsaným HMAC POSTem s retry a dead-letter frontou (per tenant, s vlastním secretem).

váš SaaS (backend)                      Verteco Peppol AP                      svět
──────────────────                      ─────────────────                      ────
POST /api/v1/companies  ──────────────▶ založení tenanta
                                        zákazník: výběr na FS (eID) ─────────▶ Finanční správa SR
                                        ◀── FS webhook: firma active + SMP reg.
POST /sapi/document/send ─────────────▶ validace → AS4 ──────────────────────▶ síť Peppol (příjemce)
                                        ◀── doručenka MLS (delivered/rejected)
◀── webhook invoice.received ────────── přijatá faktura ze sítě Peppol ◀────── odesílatel
Dvě nezávislé „brány“ pro každou firmu: příjem: zapne se po výběru Verteco na portálu Finanční správy (tehdy firmu automaticky registrujeme do centrálního SK SMP a dostane peppolParticipantId); odesílání: po ověření Verifikačního údaje (firma je sending-verified). Odesílání je u nás fail-closed (doporučení Finanční správy poskytovatelům, § 76a odst. 2 zákona o DPH): bez ověřeného Verifikačního údaje API vrátí 403 sending_not_verified. Detaily v kroku 2.

Krok 0

Účet a API klíč: registrace na naše endpointy

  1. 1. Vytvořte si účet na /register (e-mail + heslo, zdarma, bez vázanosti).
  2. 2. V dashboardu otevřete API tokeny (/dashboard/tokens) a vytvořte token. Formát je vpt_ + 40 hex znaků; plaintext se zobrazí pouze jednou při vytvoření (my ukládáme jen SHA-256 hash). Spolu s tokenem si poznamenejte i jeho UUID. Je to zároveň OAuth2 client_id pro SAPI-SK.
  3. 3. Token má přístup jako váš účet: funguje pro všechny firmy, které spravujete (multi-tenant bez dalších klíčů). Zrušení tokenu v portálu okamžitě zastaví portálová volání i vydávání nových SAPI tokenů.

Ověření, že klíč funguje:

bash
curl https://peppol.verteco.digital/api/v1/auth/me -H 'Authorization: Bearer vpt_8f2a…'
# → 200 { "id": "…", "email": "dev@vase-saas.cz", … }
Rotace klíče = vytvořit nový token a starý zrušit (POST /api/v1/tokens → DELETE /api/v1/tokens/{id}). Už vydané SAPI access tokeny doběhnou do expirace (max 15 minut).

Krok 1

Onboarding zákazníka = založení firmy přes API

Pro každého zákazníka založte firmu jedním voláním. Vrácené id si uložte ke svému tenantovi. Je to klíč pro všechna další volání.

bash
curl -X POST https://peppol.verteco.digital/api/v1/companies \
  -H 'Authorization: Bearer vpt_8f2a…' \
  -H 'Content-Type: application/json' \
  -d '{
    "ico": "12345678",
    "dic": "SK1234567890",
    "legalName": "Firma zákazníka s.r.o.",
    "street": "Príkladná 12",
    "postalCode": "010 01",
    "city": "Žilina",
    "iban": "SK31 1200 0000 1987 4263 7541"
  }'
# → 201 { "id": "9fa8fd81-…", "status": "pending_verification", "peppolParticipantId": null, … }
# (IČO/DIČ výše jsou ukázkové, použijte reálné údaje zákazníka)
PolePravidla
ico8 číslic; povinné při založení; neměnné, jakmile je jednou nastaveno (400 ico_immutable); duplicita → 409 ico_taken
dicIČ DPH / DIČ ve formátu SK + 10 číslic (u neplátců DPH „SK“ + DIČ); povinné; neměnné po nastavení (je to Peppol identita firmy)
legalNamepovinné, max 500 znaků; po ověření Finanční správou se zamkne (400 company_verified_locked)
street / city / postalCodevolitelné (max 255 / 128 / 16 znaků)
countryvolitelné, 2 znaky, default „SK“
ibanvolitelné, max 34 znaků; předvyplní se do faktur vytvářených v našem webovém rozhraní
registeredAddressvolitelné, max 1000 znaků (alternativa ke strukturované adrese)

Tip: údaje firmy předvyplníte z Registru právnických osob (stejné API používá náš vlastní onboardingový formulář):

bash
curl "https://peppol.verteco.digital/api/v1/lookup/company?ico=53412834" -H 'Authorization: Bearer vpt_8f2a…'
# → 200 { "name": "Verteco digital services, s. r. o.",
#         "street": "Daniela Dlabača 21", "city": "Žilina", "zip": "010 01" }
Limity účtu: počet ověřených firem na účet není omezen; ochrana proti zneužití omezuje jen firmy, které ještě neprošly ověřením na portálu Finanční správy (překročení vrátí 409 company_limit). Tým má standardně 25 členů, SaaS partnerům ho bezplatně rozšíříme, stačí napsat. Členy týmu (např. kolegy ze supportu) přidáte přes POST /api/v1/account/team/invite. Seznamy stránkujte: GET /companies?page=0&limit=100 (hlavičky X-Total-Count, X-Total-Pages).

Krok 2

Aktivace u Finanční správy: příjem a odesílání

pending_verification ≠ živé v Peppolu. Podle výkladu Finanční správy (FAQ k eFaktúre, příklady 36 a 73) si firma poskytovatele pro příjem zvolí sama na portálu FS (jeden přijímací pošťák na DIČ); pro odesílání výběr slouží k získání verifikačního údaje a firma smí odesílat i přes více pošťáků. Jsou to dva nezávislé kroky:

Příjem faktur → status active

Zákazník vybere Verteco na portálu FS (jednorázově, přihlášením přes eID nebo přihlašovacími údaji PFS)

  1. Pošlete zákazníka na vpds.financnasprava.sk (výběr poskytovatele: Verteco), kde se přihlásí eID (slovensko.sk) a potvrdí výběr.
  2. Finanční správa nám pošle webhook s kryptograficky podepsaným souhlasem; ověříme ho automaticky.
  3. Firma se přepne na status: "active", dostane peppolParticipantId (formát 0245:<číslice DIČ>) a automaticky ji zaregistrujeme do centrálního SK SMP; od té chvíle přijímá e-faktury.
  4. Vy neděláte nic: dokončení zachytíte webhookem company.activated, nebo pollingem GET /companies/{id}, dokud se nevyplní peppolParticipantId (nastavuje se výhradně touto cestou).

Odesílání → sending-verified

Doložte Verifikační údaj přes API

Verifikační údaj (VÚ) je podepsaný řetězec, který firma dostane od Finanční správy při výběru poskytovatele (e-mailem / v portálu PDS). Zákazník vám ho vloží do vašeho UI a vy ho doložíte jedním voláním; my ověříme RSA podpis FS:

bash
curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/verification \
  -H 'Authorization: Bearer vpt_8f2a…' \
  -H 'Content-Type: application/json' \
  -d '{"token": "<verifikační údaj, 1024 hex znaků>"}'
# → 200 { "companyId": "…", "status": "active",
#         "sendingVerified": true,
#         "verificationMethod": "self", "verifiedAt": "…" }

Neplatný podpis → 400 token_invalid. Chybějící DIČ → 400 company_dic_missing.

Pokud zákazník udělá výběr na portálu FS, oba kroky se vyřídí najednou: webhook od FS nese i Verifikační údaj, takže firma je hned active i sending-verified a zaregistrovaná pro příjem. Samostatné doložení VÚ přes API zpřístupní pouze odesílání; registraci pro příjem (SMP) spouští až výběr na portálu FS. Doporučený flow pro SaaS: založit firmu přes API → poslat zákazníka na výběr na FS → hotovo.

Krok 3

Příjem faktur: webhooky s podpisem HMAC nebo pull přes API

A · Push: webhook per tenant (doporučeno)

Každé firmě nastavte webhook URL (a volitelně notifikační e-mail) a vyzvedněte podpisový secret (vrátí se pouze jednou):

bash
curl -X PUT https://peppol.verteco.digital/api/v1/companies/{id}/notifications \
  -H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
  -d '{"webhookUrl": "https://vase-saas.cz/peppol/webhook", "notificationEmail": "zakaznik@firma.sk"}'

curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/webhook/secret -H 'Authorization: Bearer vpt_8f2a…'
# → 200 { "secret": "vpt_…" }   ← uložte, zobrazí se pouze jednou

Při přijaté faktuře pošleme na vaši URL POST (event invoice.received; při odeslané invoice.sent):

http
POST https://vase-saas.cz/peppol/webhook
Content-Type: application/json
X-Verteco-Event: invoice.received
X-Verteco-Signature: sha256=3f1a9c…   ← HMAC-SHA256 nad surovým tělem

{
  "event": "invoice.received",
  "companyId": "9fa8fd81-…",
  "companyDic": "SK2121358349",
  "peppolParticipantId": "0245:2121358349",
  "documentId": "574d4e52-…",
  "invoiceNumber": "2027-0142",
  "senderId": "0245:2120433843",
  "supplierName": "Dodávateľ s.r.o.",
  "receiverId": "0245:2121358349",
  "issueDate": "2027-01-15",
  "dueDate": "2027-01-29",
  "deliveryDate": "2027-01-15",
  "currency": "EUR",
  "totalAmount": "1234.56",
  "peppolMessageId": "a0b1c2d3-…"
}

Partnerský podpisový klíč si nastavíte sami (zprostředkovatelé): PUT /api/v1/resellers/me/notification-webhook s tělem { "url": "https://…" } uloží URL, na kterou budeme události všech vašich zákaznických firem posílat, a při prvním nastavení vrátí podpisový klíč (secret); zobrazí se pouze jednou. Pozdější zobrazení vyžaduje heslo účtu (v portálu v detailu firmy, nebo POST …/notification-webhook/reveal s tělem { "password": "…" }); každé zobrazení se zapisuje do bezpečnostního logu s IP a časem a poslední vidíte v odpovědi GET. Autentizace je vaším portálovým účtem (session nebo Bearer token); klíč nikdy neposíláme e-mailem. To, že je firma zprostředkovatel, vidíte v API na jejím záznamu jako reseller: true (příznak whiteLabel označuje až firmy vašich zákazníků).

Ověření podpisu (Node.js):

javascript
import crypto from 'node:crypto';

function verifyVertecoWebhook(rawBody, signatureHeader, secret) {
  // podpis = "sha256=" + hex( HMAC-SHA256(secret, surové tělo requestu) )
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return signatureHeader?.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}
// Důležité: počítejte HMAC nad SUROVÝM tělem (raw bytes), ne nad re-serializovaným JSONem.
Vlastnost doručováníHodnota
Úspěchjakákoli odpověď 2xx z vaší strany
Retry12 pokusů s odstupem od 30 sekund do 8 hodin (celkem přibližně 16 hodin), potom dead-letter s možností opakovaného doručení z portálu
Timeout15 s na pokus; přesměrování se nenásledují
URLveřejná http(s) adresa; interní/privátní IP blokujeme (SSRF guard)
Deduplikaceretry posílá identické tělo; deduplikujte podle documentId
TestPOST /companies/{id}/webhook/test (pošle podepsaný event webhook.test s "test": true)

B · Pull: SAPI-SK receive (alternativa nebo doplněk)

bash
# seznam přijatých dokladů (inkrementálně přes ?since=)
curl "https://peppol.verteco.digital/sapi/document/receive?since=2027-01-01T00:00:00Z&limit=200" \
  -H 'Authorization: Bearer <sapi_access_token>' \
  -H 'X-Peppol-Participant-Id: 0245:2121358349'
# → { "documents": [ { "documentId": "…", "documentTypeId": "…",
#       "senderParticipantId": "…", "receiverParticipantId": "…", … } ],
#     "nextPageToken": "50" }

# detail včetně originálního XML přesně tak, jak přišlo ze sítě
curl https://peppol.verteco.digital/sapi/document/receive/{documentId} \
  -H 'Authorization: Bearer <sapi_access_token>' -H 'X-Peppol-Participant-Id: 0245:2121358349'
# → { "metadata": { … }, "payload": "<Invoice …>", "payloadFormat": "XML" }

# potvrzení zpracování (idempotentní)
curl -X POST https://peppol.verteco.digital/sapi/document/receive/{documentId}/acknowledge \
  -H 'Authorization: Bearer <sapi_access_token>' -H 'X-Peppol-Participant-Id: 0245:2121358349'

K dokladům se dostanete i přes portálové API: GET /companies/{id}/documents?direction=received, stahování …/documents/{docId}/download?format=xml|html|mls, hromadné exporty …/documents/export.csv a …/documents/export.zip (originály XML). E-mailová notifikace firmě (pokud ji zapnete) nese fakturu jako PDF + originál XML v příloze, odesílatel nese jméno firmy a Reply-To směřuje na majitele účtu (chování připravené na white-label).

Krok 4

Odesílání faktur přes SAPI-SK: OAuth2, idempotence, doručenky

1 · Výměna tokenu (OAuth2 client_credentials)

bash
curl -X POST https://peppol.verteco.digital/sapi/auth/token -H 'Content-Type: application/json' \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "<UUID vašeho API tokenu>",
    "client_secret": "vpt_8f2a…"
  }'
# → 200 { "access_token": "eyJ…", "token_type": "Bearer",
#         "expires_in": 900, "refresh_token": "eyJ…" }
# access token platí 15 min (obnova přes POST /sapi/auth/renew, refresh 30 dní);
# GET /sapi/auth/token/status vrátí should_refresh: true < 3 min před expirací

2 · Odeslání dokladu (UBL 2.1, Peppol BIS Billing 3.0)

bash
curl -X POST https://peppol.verteco.digital/sapi/document/send \
  -H 'Authorization: Bearer <sapi_access_token>' \
  -H 'X-Peppol-Participant-Id: 0245:2121358349' \
  -H 'Idempotency-Key: fa-2027-0142' \
  -H 'Content-Type: application/json' \
  -d '{
    "metadata": {
      "documentId": "FA-2027-0142",
      "documentTypeId": "busdox-docid-qns::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": "cenbii-procid-ubl::urn:fdc:peppol.eu:2017:poacc:billing:01:1.0",
      "senderParticipantId": "0245:2121358349",
      "receiverParticipantId": "0245:2120433843"
    },
    "payload": "<?xml version=\"1.0\"?><Invoice …>…</Invoice>",
    "payloadFormat": "XML",
    "checksum": "<volitelné: SHA-256 hex payloadu>"
  }'
# → 202 { "providerDocumentId": "<UUID u nás>", "status": "ACCEPTED", "receivedAt": "…", "timestamp": "…" }
# při "REJECTED" (neprošel validací / síť odmítla) nese odpověď i pole
# "detail" s konkrétním důvodem (např. porušená pravidla BR-CO-15, …)
Idempotence: hlavička Idempotency-Key (doporučujeme číslo faktury nebo interní ID) chrání před duplicitním odesláním: opakované volání se stejným klíčem vrátí původní výsledek, nový klíč pro tutéž fakturu ji může poslat dvakrát. Probíhající send se stejným klíčem → 502 SAPI-PROC-001 (retryable: true, zkuste za chvíli); po transportním selhání (failed) retry se stejným klíčem doklad reálně pošle znovu. Stejný klíč pošle doklad znovu i tehdy, když ho odmítla naše kontrola před odesláním (REJECTED, do sítě nic neodešlo) nebo když skončil jako undeliverable (po opravě identifikátoru příjemce nebo po jeho registraci); postup včetně data vystavení opravené faktury je v dokumentaci pro vývojáře. Limit payloadu: 10 MB. Doklady před odesláním validujeme stejným rulesetem EN 16931 + Peppol BIS jako při příjmu; nevalidní doklad vrátí REJECTED s konkrétními pravidly (např. BR-CO-15).

3 · Dávkové odesílání (až 100 dokladů)

bash
curl -X POST https://peppol.verteco.digital/sapi/document/batch \
  -H 'Authorization: Bearer <sapi_access_token>' -H 'X-Peppol-Participant-Id: 0245:2121358349' \
  -H 'Content-Type: application/json' \
  -d '{ "documents": [
        { "itemId": "fa-2027-0142", "idempotencyKey": "fa-2027-0142", "metadata": { … }, "payload": "…", "payloadFormat": "XML" },
        …
      ] }'
# (schematický příklad: metadata má stejná pole jako při jednotlivém sendu)
# → 202 { "total": 100, "accepted": 98, "rejected": 1, "failed": 1,
#         "results": [ { "itemId": "…", "ok": true, "providerDocumentId": "…", "status": "ACCEPTED" }, … ] }
# položky se zpracovávají sekvenčně; selhání jedné neovlivní ostatní

4 · Stav doručení a doručenky (MLS)

Životní cyklus odeslaného dokladu: pending → submitted → delivered / rejected (potvrzené doručenkou MLS od Access Pointu příjemce) nebo failed (transportní selhání; retry se stejným Idempotency-Key), případně undeliverable (příjemce nemá adresu v síti Peppol: doklad jsme převzali a nahlásíme Finanční správě, nikomu se nedoručí). Stavy sledujte inkrementálně:

bash
curl "https://peppol.verteco.digital/sapi/document/sent?since=2027-01-15T00:00:00Z" \
  -H 'Authorization: Bearer <sapi_access_token>' -H 'X-Peppol-Participant-Id: 0245:2121358349'
# → { "documents": [ { "documentId": "574d4e52-…", "peppolMessageId": "a0b1c2d3-…",
#       "status": "delivered", "statusDateTime": "…", … } ], … }
# documentId = providerDocumentId ze send odpovědi (UUID u nás); párujte podle něj
# nebo podle peppolMessageId; při "rejected" řádek nese i statusDetail s důvodem.
# ?since= zachytává i ZMĚNY STAVU (ne jen nové doklady); ideální pro polling každých pár minut

# doručenka (MLS ApplicationResponse XML), právní důkaz o doručení:
curl "https://peppol.verteco.digital/api/v1/companies/{id}/documents/{documentId}/download?format=mls" \
  -H 'Authorization: Bearer vpt_8f2a…'
Slovenské daňové hlášení (TDD) k přijatým i odeslaným dokladům obstaráváme automaticky podle harmonogramu zpřístupnění produkčního rozhraní C5 Finanční správy; vy jako partner nic navíc neimplementujete. Jednodušší alternativa k SAPI pro odesílání: portálový endpoint POST /companies/{id}/documents/send s tělem { "xml": "…", "receiverParticipantId": "0245:…" } (beta: tvar odpovědi se ještě může měnit).

Plná parita

Všechno, co má přímý zákazník, obsloužíte přes API

Váš tenant nemusí nikdy otevřít náš portál: každá funkce, kterou má přímý zákazník v dashboardu, existuje jako REST endpoint pod vaším tokenem. Přehled celé správcovské plochy (všechno Authorization: Bearer vpt_…, base /api/v1):

OblastEndpointy
Firmy (tenanti)GET/POST /companies · GET/PUT /companies/{id} · stránkování ?page&limit + X-Total-Count
Ověření odesíláníPOST /companies/{id}/verification (Verifikační údaj)
Předvyplnění z registruGET /lookup/company?ico= → název + adresa z RPO
DokladyGET /companies/{id}/documents?direction=received|sent · GET …/documents/{docId} · POST …/documents/send · POST …/documents/send-test
Stahování a exportyGET …/documents/{docId}/download?format=xml|html|mls · GET …/documents/export.csv · GET …/documents/export.zip (?direction&from&to)
Nastavení fakturGET/PUT /companies/{id}/invoice-settings: číslování ({YYYY}{NNNN}), splatnost, předvolený IBAN a poznámka
Adresář odběratelůGET/POST /companies/{id}/address-book · DELETE …/address-book/{entryId} (auto-save po úspěšném sendu)
Notifikace a webhookyGET/PUT /companies/{id}/notifications · POST …/webhook/secret · POST …/webhook/test · události invoice.received / invoice.sent / invoice.delivered / invoice.rejected / company.activated / company.deactivated / company.smp_registered_elsewhere
Režim white-labelPUT /companies/{id} s { "whiteLabel": true }; platforma neposílá tenantovi žádné vlastní e-maily
Odregistrace white-label firmyPOST /companies/{id}/deregister s hlavičkami X-Company-Proof-Timestamp a X-Company-Proof (HMAC-SHA256 webhook secretem firmy, viz krok 4 níže); samoobslužnou firmu odregistruje jen přihlášený vlastník
TýmGET /account/team · POST /account/team/invite · POST /account/team/accept
API klíčeGET/POST /tokens · DELETE /tokens/{id}
Doklady (SAPI-SK)POST /sapi/document/send · POST …/batch · GET …/receive (+detail, acknowledge) · GET …/sent
Jediné, co za tenanta udělat nemůžete, je jednorázový výběr poskytovatele na portálu Finanční správy (eID nebo přihlašovací údaje PFS). Podle výkladu FS je to podmínka příjmu platná stejně pro přímé zákazníky; pro odesílání jím tenant dodá verifikační údaj. Všechno ostatní běží programově. Volitelný bonus: po výběru na FS tenant dostane magic-link do našeho portálu; může, ale nemusí ho nikdy použít.

Neviditelná infrastruktura

Provoz white-label: tenant komunikuje jen s vámi

Cílový stav: váš zákazník používá váš produkt, vaši značku a váš support; my jsme neviditelná infrastruktura. Tři kroky, které to zajistí:

  1. 1 · Zapněte režim white-label na firmě

    S whiteLabel: true platforma neposílá tenantovi žádné vlastní e-maily (např. potvrzení výběru poskytovatele) a nepřebírá si jeho kontaktní adresu z výběru na FS. Komunikaci vedete vy, pod vlastní značkou.

    bash
    curl -X PUT https://peppol.verteco.digital/api/v1/companies/{id} -H 'Authorization: Bearer vpt_8f2a…' \
      -H 'Content-Type: application/json' \
      -d '{"ico":"12345678","dic":"SK1234567890","legalName":"Firma zákazníka s.r.o.",
           "street":"Príkladná 12","postalCode":"010 01","city":"Žilina",
           "iban":"SK31 1200 0000 1987 4263 7541","whiteLabel":true}'
    # nejjednodušší je poslat whiteLabel už při POST /companies (založení firmy);
    # POZOR: PUT je plná aktualizace; pošlete všechna volitelná pole (adresa, IBAN),
    # vynechaná se vymažou
  2. 2 · Notifikace řešte webhooky, ne našimi e-maily

    V režimu white-label platforma neposílá e-maily o fakturách vůbec (pole notificationEmail se ignoruje). Nastavte webhook a o přijaté faktuře se dozvíte přes invoice.received. Obsah si stáhnete přes API (XML / tisknutelné HTML) a zákazníkovi pošlete vlastní e-mail z vlastní domény.

  3. 3 · Dokončení výběru na FS zachytíte webhookem company.activated

    Když zákazník dokončí výběr poskytovatele na portálu Finanční správy, pošleme na webhook firmy událost (nemusíte pollovat):

    http
    POST https://vase-saas.cz/peppol/webhook
    X-Verteco-Event: company.activated
    X-Verteco-Signature: sha256=…
    
    {
      "event": "company.activated",
      "companyId": "9fa8fd81-…",
      "companyDic": "SK2121358349",
      "peppolParticipantId": "0245:2121358349",
      "status": "active",
      "verifiedAt": "2027-01-05T09:12:33Z"
    }

    Událost znamená: výběr kryptograficky ověřen, firma přepnuta na status: "active", registrace do SK SMP odeslána; tenant je připraven přijímat i odesílat (Verifikační údaj přišel spolu s výběrem). Událost je at-least-once; zpracujte ji idempotentně a vždy se řiďte polem status v těle (posíláme ji jen pro reálně aktivované firmy; firma pozastavená administrátorem ji nedostane).

  4. 4 · Když tenant firmu zruší: odregistrace přes API s důkazem webhook secretem

    Odregistrace ze sítě je nevratná pro doručování faktur firmě, proto ji samotný API klíč nikdy neprovede (403 token_not_allowed). U white-label firmy, kterou jste založili vy, přidáte druhý faktor, který máte jen vy: aktuální webhook secret firmy (odpověď na POST …/webhook/secret). Časové razítko platí ±300 s, companyId je malými písmeny tak, jak ho vrací API. Nesprávný, expirovaný nebo neuplatnitelný důkaz vrátí 403 company_proof_invalid bez bližšího důvodu; samoobslužnou firmu (bez whiteLabel) odregistruje nadále jen přihlášený vlastník.

    bash
    # secret    = vpt_0123456789abcdef0123456789abcdef01234567   (webhook secret firmy)
    # companyId = 9fa8fd81-2c4e-4b7a-9d3e-5f6a7b8c9d0e
    # timestamp = 1760000000                                      (unix sekundy, ±300 s)
    # message   = deregister:9fa8fd81-2c4e-4b7a-9d3e-5f6a7b8c9d0e:1760000000
    # proof     = hex(HMAC-SHA256(secret, message))
    #           = e7e21ebd72506453b95c4cbb87c5556a21d93a5539cc7de6b32a29b9d7090901
    TS=$(date +%s)
    PROOF=$(printf '%s' "deregister:{id}:$TS" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | awk '{print $NF}')
    curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/deregister \
      -H 'Authorization: Bearer vpt_8f2a…' \
      -H "X-Company-Proof-Timestamp: $TS" \
      -H "X-Company-Proof: $PROOF"
    # 200 → firma ve stavu pending_verification + webhook company.deactivated; 403 company_proof_invalid → důkaz nesedí,
    # vypršel, firma není white-label nebo nemá webhook secret (důvod se nevrací)
Důležité pořadí: firmu založte přes API dřív, než zákazníka pošlete na výběr na portál FS. Pokud by výběr proběhl pro DIČ, které u nás ještě neexistuje, systém firmu automaticky vytvoří jako samoobslužnou, včetně uvítacího e-mailu zákazníkovi (mimo režim white-label). Při dodržení pořadí „nejprve firma, potom výběr“ žádný náš e-mail tenantovi neodejde.

Co tenant uvidí a co ne (upřímně)

Neviditelné pro tenanta

  • · celé API, portál, dashboard (tenant je nikdy nepotřebuje)
  • · e-maily: v režimu white-label od nás žádné nechodí
  • · technická identita v síti (náš certifikát Access Pointu); vidí ji jen jiné Access Pointy

Krok, který zůstává na firmě

  • · jednorázový výběr poskytovatele na portálu Finanční správy: zákazník tam vybírá „Verteco digital services“ ze státního seznamu certifikovaných poskytovatelů. Platí to stejně pro každého poskytovatele na trhu; pro příjem je to podle výkladu Finanční správy povinnost, pro odesílání tím firma získá verifikační údaj (FAQ FS, příklad 73).
  • · Verifikační údaj od FS, který nám (přes vás) firma dokládá před odesíláním

I toto poslední okno se dá přebrandovat: Finanční správa umožňuje certifikovaným poskytovatelům registrovat partnery jako zprostředkovatele doručovací služby. Po zápisu si zákazník na vpds.financnasprava.sk vybírá přímo vaši značku ze seznamu. Žádost o zápis vygenerujete za pár minut na /sprostredkovatel.

Bezpečnost a zákonné požadavky

PožadavekJak je splněn
Oprávnění odesílat (§ 76a odst. 2 písm. b zák. 222/2004)fail-closed gate: bez kryptograficky ověřeného Verifikačního údaje od FS vrátí každý send 403; nedá se obejít ani přes API, ani přes batch
Souhlas firmy s poskytovatelemvýběr na portálu FS (přihlášení přes eID nebo přihlašovacími údaji PFS); FS nám ho doručí podepsaný (RSA-PSS); ověřujeme podpis, ne tvrzení
Ochrana osobních údajůdata faktur v EU (Frankfurt); zpracování podle VOP a zásad ochrany údajů (odkazy níže); webhooky podepisované HMAC, secrety se nedají zpětně přečíst
Důkaz o doručenídoručenka MLS (ApplicationResponse) přijatá ověřeným kanálem AS4 od Access Pointu příjemce, stažitelná přes API jako právní doklad o doručení
Daňové hlášení (TDD)obstaráváme automaticky podle harmonogramu zpřístupnění rozhraní C5 FS; partner nic neimplementuje
Izolace tenantůpřístup jen přes členství ve firmě; API token má přísně stejná práva jako váš účet; SAPI kontroluje shodu odesílatele s autorizovaným participantem
ISO/IEC 27001certifikát zatím nemusí mít žádný poskytovatel (OpenPeppol ho vyžaduje od všech od 1. 10. 2027); naše certifikace ISO/IEC 27001:2022 probíhá u akreditovaného orgánu SKQS, s. r. o., Žilina (SNAS), vybraného v září 2026, certifikát plánujeme do 1. 7. 2027

Právní dokumenty: obchodní podmínky · ochrana osobních údajů. Smluvní vztah máte s námi vy jako partner; vůči svým zákazníkům vystupujete podle vlastních podmínek.

Vývoj a testování

Sandbox: veřejný, bez registrace

Celý kontrakt SAPI-SK si vyzkoušíte okamžitě s veřejnými přihlašovacími údaji client_id = sandbox / client_secret = sandbox. Sandbox validuje požadavky přesně jako produkce, ale nikdy nic nedoručí a nevidí reálná data; izolace je vynucená přímo v podepsaném tokenu.

bash
# 1 · sandbox token
curl -X POST https://peppol.verteco.digital/sapi/auth/token -H 'Content-Type: application/json' \
  -d '{"grant_type":"client_credentials","client_id":"sandbox","client_secret":"sandbox"}'

# 2 · mock send: plná validace kontraktu, nic se nedoručí
curl -X POST https://peppol.verteco.digital/sapi/document/send \
  -H 'Authorization: Bearer <sandbox_token>' -H 'X-Peppol-Participant-Id: 0245:0000000000' \
  -H 'Content-Type: application/json' \
  -d '{"metadata":{"documentId":"TEST-1","documentTypeId":"…","senderParticipantId":"0088:sandbox-sender","receiverParticipantId":"0088:sandbox-receiver"},"payload":"<Invoice/>","payloadFormat":"XML"}'
# → 202 { "providerDocumentId": "sandbox-…", "status": "ACCEPTED", … }

# 3 · vzorový přijatý doklad
curl "https://peppol.verteco.digital/sapi/document/receive" -H 'Authorization: Bearer <sandbox_token>' -H 'X-Peppol-Participant-Id: 0245:0000000000'
curl "https://peppol.verteco.digital/sapi/document/receive/sandbox-doc-0001" -H 'Authorization: Bearer <sandbox_token>' -H 'X-Peppol-Participant-Id: 0245:0000000000'

Doplňky k sandboxu: veřejný validátor e-faktur (stejná pravidla jako produkční AP), testovací webhook (POST /companies/{id}/webhook/test) a zkušební faktura přes reálnou síť na vlastní firmu (POST /companies/{id}/documents/send-test).

Bez autentizace

Veřejné API: ověření příjemce a validace dokladu

Ověření příjemce v síti Peppol

Před odesláním si ověřte, zda je příjemce registrovaný (živý lookup SML/SMP). Bere SK IČ DPH, DIČ i plné Peppol ID:

bash
curl "https://peppol.verteco.digital/api/v1/public/peppol-check?id=SK2121358349"
# → { "registered": true, "participantId": "0245:2121358349",
#     "smp": "…", "capabilities": ["Faktúra (BIS Billing)", …],
#     "lastCheckedAt": "…" }

Validace e-faktury (EN 16931 + Peppol BIS)

Stejný ruleset, jakým prochází každý doklad v našem Access Pointu, ideálně do CI nebo do vývoje mapování:

bash
curl -X POST "https://peppol.verteco.digital/api/v1/public/peppol-validate" \
  -H 'Content-Type: application/xml' --data-binary @faktura.xml
# → { "valid": false,
#     "errors": ["BR-CO-15: Invoice total amount with VAT …"],
#     "warnings": [] }     (limit 3 MB)
Veřejné endpointy mají přísnější rate limit (15 volání/min na IP); jsou určeny pro jednotlivá ověření, ne hromadné skenování. Při integraci volejte před odesláním; výsledky pozitivních ověření krátkodobě cachujeme.

Robustnost

Rate limity, chybové odpovědi a velikostní limity

Rate limity (pevné 60sekundové okno)

RozsahLimitKlíč
/api/v1/** (portál) a /sapi/document/*dynamický, s velkou rezervouna API token
/sapi/auth/* a /api/v1/auth/*přísnější (anti brute-force)na IP adresu
/api/v1/public/** (checker, validátor)přísnějšína IP adresu

Každá odpověď nese hlavičky RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset; při překročení přijde 429 s hlavičkou Retry-After a tělem { "error": "rate_limited", "message": "Too many requests. Slow down." }. (Výjimka: /auth/me a /auth/logout jdou v běžném bucketu na token.) Aktuální hodnoty limitů čtěte vždy z hlaviček; jsou nastavené tak, aby jich běžný provoz včetně špiček nikdy nedosáhl. Při hromadném onboardingu / batch odesílání dávkujte s backoffem na 429. Potřebujete vyšší limit? Napište nám.

Dva tvary chyb

Portálové API (/api/v1/**)

jsonc
{ "error": "ico_taken",
  "message": "A company with this IČO already exists" }

// při validaci polí navíc:
{ "error": "validation_failed", "message": "Some fields are invalid",
  "fields": { "dic": "IČ DPH musí byť 'SK' a 10 číslic" } }

SAPI-SK (/sapi/**)

json
{ "error": {
    "category": "AUTH",
    "code": "SAPI-AUTH-003",
    "message": "Sending is not enabled for this participant: a verified Verifikačný údaj is required.",
    "retryable": false,
    "correlation_id": "b4191dfc-…"
} }
Kód SAPIHTTPVýznam
SAPI-AUTH-001401neplatné / zrušené client credentials
SAPI-AUTH-002401chybějící / neplatný / expirovaný Bearer token
SAPI-AUTH-003403 / 401firma pro participanta neexistuje, nemáte k ní přístup, sender nesedí, chybí ověřený Verifikační údaj; nebo (při /auth/token a /auth/renew, 401) volající IP není na allowlistu API klíče nastaveném v portálu
SAPI-VAL-001 / 002400neplatná pole / chybějící hlavička X-Peppol-Participant-Id
SAPI-RES-001 / 002404doklad neexistuje / originál payload není archivován
SAPI-PROC-001502dočasné selhání (retryable: true); zopakujte se stejným Idempotency-Key
SAPI-PROC-002503dočasná infrastrukturní chyba (retryable: true); zopakujte se stejným Idempotency-Key
SAPI-PROC-500500neočekávaná chyba (retryable: false); neopakujte, nahlaste nám correlation_id

Velikostní limity

KdeLimit
SAPI payload (send / položka batch)10 MB na doklad; batch max 100 položek
Portálový send (pole xml)2 MB
Veřejný validátor3 MB
Seznamy (receive / sent / documents)limit max 200 na stránku, default 50

Obchodní model

Přeprodej a white-label: jak se to počítá

Příjem bez archivu zdarma

Firma s vypnutým Archivem dat přijímá e-faktury zdarma do 1 000 faktur měsíčně, včetně daňového hlášení; obsah dokladů se u nás maže 14 dní po doručení. Firmy pod vaší značkou (white-label) se zakládají bez archivu.

Odesílání a Archiv dat od 2 €/měs

Platí se za IČO, které v měsíci odeslalo fakturu nebo mělo zapnutý Archiv dat (u nových firem v portálu předvoleně): 2 €/měs + DPH, strhává se z vašeho předplaceného kreditu vždy 1. den měsíce za ukončený měsíc (první čerpání 1. 2. 2027 za leden 2027). V ceně je archiv originálů v EU (1 GB), REST API, webhooky, konektory, více IČO, B2G i white-label.

0,01 € nad limit

Každá faktura (přijatá nebo odeslaná) nad 1 000 faktur měsíčně; žádný tvrdý strop, doručení nikdy neblokujeme.

Vaše marže = vaše věc

Svým zákazníkům fakturujete vy, podle vlastního ceníku. Nám platíte podle veřejného ceníku, bez skrytých partnerských poplatků.

White-label v ceně

Řešení pod vlastní značkou je součást balíčku: e-maily o fakturách nesou jméno firmy zákazníka, vaše UI je vaše.

Objemová dohoda

Při desítkách a stovkách firem připravíme objemovou dohodu a bezplatně zvýšíme limity účtu. Napište nám.

Během dobrovolného období (do 1. 1. 2027) je všechno zdarma; ceny podle ceníku platí od mandátu. Nechcete integrovat sami? Řízené napojení vašeho systému uděláme my, cena podle rozsahu bez DPH jednorázově. Jedna věc se přenést nedá: každá firma musí mít před odesíláním u nás ověřený Verifikační údaj (fail-closed gate podle doporučení FS, § 76a odst. 2 zák. 222/2004) a výběr poskytovatele na portálu FS dělá firma sama (eID nebo přihlašovací údaje PFS).

Go-live

Checklist před spuštěním

  • ✓Účet + API token vytvořen, token bezpečně uložen na serveru (nikdy ve frontendu).
  • ✓Onboarding flow: POST /companies + přesměrování zákazníka na výběr poskytovatele na portálu FS (eID).
  • ✓Stavový polling: sledujete peppolParticipantId (signál, že firma přijímá) a příznak verified + status active před prvním odesláním.
  • ✓Webhook endpoint: ověřuje X-Verteco-Signature (HMAC-SHA256 nad surovým tělem), odpovídá 2xx do 15 s, deduplikuje podle documentId.
  • ✓Odesílání: Idempotency-Key na každém sendu, backoff na 429 a SAPI-PROC-001, polling /sapi/document/sent?since= na stavy doručení.
  • ✓Mapování dokladů otestováno přes veřejný validátor a sandbox; první ostrý test přes send-test.
  • ✓Ošetřené chybové stavy: 403 sending_not_verified, 409 ico_taken, verdikt REJECTED s důvodem.
  • ✓Limity účtu navýšené podle počtu firem (napište nám při >10 firmách).

Otázky partnerů

Časté otázky SaaS a platforem

Musí mít každý náš zákazník účet ve vašem portálu?
Ne. Model je proxy: váš backend drží jeden API token a firmy zákazníků zakládáte a obsluhujete přes API ve svém účtu. Zákazník dělá jediný krok mimo váš produkt: jednorázový výběr poskytovatele na portálu Finanční správy (eID nebo přihlašovací údaje PFS). Podle výkladu FS je výběr povinný pro příjem; pro odesílání jím firma dodá verifikační údaj, který před odesláním vyžadujeme. Portálový účet u nás je pro ni volitelný bonus, ne podmínka.
Jak zjistíme, že zákazník dokončil výběr na Finanční správě?
Nejjednodušeji: nastavte firmě webhook a poslouchejte událost company.activated. Pošleme ji hned po kryptografickém ověření výběru, spolu s přiděleným peppolParticipantId. Alternativně polling: GET /api/v1/companies/{id}, kde spolehlivý signál dokončeného výběru (a tedy schopnosti přijímat) je vyplněné pole peppolParticipantId (nastavuje se výhradně po výběru na portálu FS). Samotný status active nestačí: nastaví ho i doložení Verifikačního údaje přes API, které zpřístupňuje pouze odesílání.
Můžeme službu prodávat pod vlastní značkou (white-label)?
Ano. Řešení pod vlastní značkou je součástí balíčku Odesílání a příjem, bez zvláštních partnerských poplatků. Firmě nastavíte whiteLabel: true a platforma jí neposílá žádné vlastní e-maily; notifikace odebíráte webhooky a komunikujete pod vlastní značkou. Vy určujete cenu pro své zákazníky a fakturujete jim sami; nám platíte podle veřejného ceníku.
Jak otestujeme integraci bez reálných dokladů?
Tři nástroje: veřejný SAPI sandbox (client_id i client_secret = "sandbox") s plnou validací kontraktu, který nikdy nic nedoručí; veřejný validátor e-faktur (POST /api/v1/public/peppol-validate) se stejnými pravidly EN 16931 + Peppol BIS jako produkční Access Point; a testovací webhook (POST /companies/{id}/webhook/test), který pošle podepsanou vzorovou událost na vaši URL.
Co když zákazník posílá tisíce faktur měsíčně?
Žádný tvrdý strop: nad 1 000 faktur měsíčně je každá další faktura 0,01 €. API podporuje dávkové odesílání (batch až 100 dokladů na volání) a inkrementální stahování přes parametr since. Při velkém objemu firem nebo dokladů připravíme objemovou dohodu.
Jaké typy dokladů umíte přijímat a odesílat?
Faktury a dobropisy Peppol BIS Billing 3.0 (UBL 2.1) včetně pravidel SK Billing, self-billing faktury a dobropisy a doručenky MLS. Slovenské daňové hlášení (TDD) k dokladům obstaráváme automaticky podle harmonogramu zpřístupnění rozhraní Finanční správy.
Je API verzované a stabilní?
Ano. Strojově čitelná specifikace OpenAPI 3.1 je na /api/v1/openapi.json a pokrývá portálové API i SAPI-SK. SAPI-SK je národní standardizované rozhraní, ne proprietární kontrakt, takže integrace není vendor lock-in. Změny děláme zpětně kompatibilně.

Začněte se sandboxem ještě dnes · ostrý účet máte za minutu

Související: kompletní dokumentace API · OpenAPI 3.1 · hotové e-shopové pluginy · pro účetní · ceník