Für SaaS, ERP und Plattformen

Bauen Sie die Peppol-E-Rechnung in Ihr Produkt ein

Sie integrieren einmal und bedienen unbegrenzt viele Ihrer Kunden. Eigener zertifizierter slowakischer Peppol Access Point, REST-API, signierte Webhooks, öffentliche Sandbox und White-Label inklusive. Diese Seite ist die vollständige technische Anleitung: von der Registrierung über das Onboarding von Firmen bis zum Senden und Empfangen von Belegen.

Zertifiziert von PA SK · EFSK000031Eigener Peppol AP · Seat PSK001128OpenAPI 3.1 + öffentliche SandboxNationale Schnittstelle SAPI-SK

Architektur

Integrationsmodell: ein Token, N Ihrer Kunden

Das Modell ist Proxy / Multi-Tenant: Ihr Backend hält einen API-Token (vpt_…) ausschließlich auf dem Server, und jeder Ihrer Kunden ist bei uns eine Firma (Tenant). Alle Aufrufe macht Ihr Server. Der Token gehört nie in den Browser oder in eine mobile App. Welche Firma ein Aufruf bedient, legen Sie bei Belegen mit dem Header X-Peppol-Participant-Id fest, bei der Verwaltung von Firmen direkt über die Firmen-ID im Pfad.

1 · Portal-REST-API

Verwaltung der Tenants: Anlegen der Firma, Sendeverifizierung, Webhooks, Beleglisten, Download von XML/PDF/Zustellnachweisen, Exporte. Auth: Authorization: Bearer vpt_… direkt.

2 · SAPI-SK 1.0

Nationale standardisierte Schnittstelle für die Belege selbst: Senden (auch im Stapel), Empfang, Zustellstatus. Auth: OAuth2 client_credentials (client_id = UUID des Tokens, client_secret = vpt_…-Token).

3 · Webhooks zu Ihnen

Bei einer empfangenen / gesendeten Rechnung rufen wir Ihre URL mit einem HMAC-signierten POST auf, mit Retry und Dead-Letter-Queue (pro Tenant, mit eigenem Secret).

Ihr SaaS (Backend)                      Verteco Peppol AP                      Welt
──────────────────                      ─────────────────                      ────
POST /api/v1/companies  ──────────────▶ Tenant angelegt
                                        Kunde: Auswahl im FS-Portal (eID) ────▶ Finanzverwaltung der SR
                                        ◀── FS-Webhook: Firma active + SMP-Reg.
POST /sapi/document/send ─────────────▶ Validierung → AS4 ───────────────────▶ Peppol-Netzwerk (Empfänger)
                                        ◀── MLS-Zustellnachweis (delivered/rejected)
◀── Webhook invoice.received ────────── empfangene Rechnung aus dem Peppol-Netzwerk ◀── Absender
Zwei unabhängige „Gates“ für jede Firma: Empfang: wird nach der Auswahl von Verteco im Portal der Finanzverwaltung aktiviert (dann registrieren wir die Firma automatisch im zentralen SK SMP, und sie erhält eine peppolParticipantId); Senden: nach der Prüfung des Verifizierungsmerkmals (die Firma ist sending-verified). Das Senden ist bei uns fail-closed (Empfehlung der Finanzverwaltung an die Anbieter, § 76a Abs. 2 des Mehrwertsteuergesetzes): Ohne geprüftes Verifizierungsmerkmal gibt die API 403 sending_not_verified zurück. Details in Schritt 2.

Schritt 0

Konto und API-Schlüssel: Registrierung für unsere Endpunkte

  1. 1. Erstellen Sie ein Konto unter /register (E-Mail + Passwort, kostenlos, ohne Bindung).
  2. 2. Öffnen Sie im Dashboard API-Tokens (/dashboard/tokens) und erstellen Sie einen Token. Das Format ist vpt_ + 40 Hex-Zeichen; der Klartext wird nur einmal beim Erstellen angezeigt (wir speichern nur den SHA-256-Hash). Notieren Sie sich zusammen mit dem Token auch dessen UUID. Sie ist zugleich die OAuth2- client_id für SAPI-SK.
  3. 3. Der Token hat denselben Zugriff wie Ihr Konto: Er funktioniert für alle Firmen, die Sie verwalten (Multi-Tenant ohne weitere Schlüssel). Der Widerruf des Tokens im Portal stoppt sofort die Portalaufrufe sowie die Ausgabe neuer SAPI-Tokens.

Prüfen, dass der Schlüssel funktioniert:

bash
curl https://peppol.verteco.digital/api/v1/auth/me -H 'Authorization: Bearer vpt_8f2a…'
# → 200 { "id": "…", "email": "dev@vasa-saas.sk", … }
Schlüsselrotation = neuen Token erstellen und den alten widerrufen (POST /api/v1/tokens → DELETE /api/v1/tokens/{id}). Bereits ausgegebene SAPI-Access-Tokens laufen bis zu ihrem Ablauf weiter (max. 15 Minuten).

Schritt 1

Onboarding des Kunden = Anlegen der Firma über die API

Legen Sie für jeden Kunden mit einem einzigen Aufruf eine Firma an. Speichern Sie die zurückgegebene id bei Ihrem Tenant. Sie ist der Schlüssel für alle weiteren Aufrufe.

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": "Kundenfirma s.r.o.",
    "street": "Musterstraße 12",
    "postalCode": "010 01",
    "city": "Žilina",
    "iban": "SK31 1200 0000 1987 4263 7541"
  }'
# → 201 { "id": "9fa8fd81-…", "status": "pending_verification", "peppolParticipantId": null, … }
# (IČO/DIČ oben sind Beispiele; verwenden Sie die echten Daten des Kunden)
FeldRegeln
ico8 Ziffern; beim Anlegen Pflicht; unveränderlich, sobald gesetzt (400 ico_immutable); Duplikat → 409 ico_taken
dicUSt-IdNr. / Steuernummer im Format SK + 10 Ziffern (bei Nicht-Umsatzsteuerzahlern „SK“ + Steuernummer); Pflicht; nach dem Setzen unveränderlich (es ist die Peppol-Identität der Firma)
legalNamePflicht, max. 500 Zeichen; nach der Prüfung durch die Finanzverwaltung gesperrt (400 company_verified_locked)
street / city / postalCodeoptional (max. 255 / 128 / 16 Zeichen)
countryoptional, 2 Zeichen, Standard „SK“
ibanoptional, max. 34 Zeichen; wird in Rechnungen vorausgefüllt, die in unserer Weboberfläche erstellt werden
registeredAddressoptional, max. 1000 Zeichen (Alternative zur strukturierten Adresse)

Tipp: Die Firmendaten füllen Sie aus dem Register der juristischen Personen vor (dieselbe API nutzt unser eigenes Onboarding-Formular):

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" }
Kontolimits: standardmäßig 100 Firmen pro Konto und 25 Teammitglieder; SaaS-Partnern erhöhen wir das Limit kostenlos nach Bedarf, es genügt, uns zu schreiben. Eine Überschreitung gibt 409 company_limit zurück. Teammitglieder (z. B. Kollegen aus dem Support) fügen Sie über POST /api/v1/account/team/invite hinzu. Listen paginieren Sie: GET /companies?page=0&limit=100 (Header X-Total-Count, X-Total-Pages).

Schritt 2

Aktivierung bei der Finanzverwaltung: Empfang und Versand

pending_verification ≠ live im Peppol-Netzwerk. Nach der Auslegung der Finanzverwaltung (FAQ zur E-Rechnung, Beispiele 36 und 73) wählt die Firma den Anbieter für den Empfang selbst im FS-Portal (ein empfangender Zustelldienst je Steuernummer); für das Senden dient die Auswahl der Beschaffung des Verifizierungsmerkmals, und die Firma darf auch über mehrere Zustelldienste senden. Es sind zwei unabhängige Schritte:

Rechnungsempfang → Status active

Der Kunde wählt Verteco im FS-Portal (einmalig, Anmeldung per eID oder mit den Zugangsdaten des PFS-Portals)

  1. Schicken Sie den Kunden zu vpds.financnasprava.sk (Auswahl des Anbieters: Verteco), wo er sich per eID (slovensko.sk) anmeldet und die Auswahl bestätigt.
  2. Die Finanzverwaltung sendet uns einen Webhook mit kryptografisch signierter Zustimmung; wir prüfen sie automatisch.
  3. Die Firma wechselt auf status: "active", erhält eine peppolParticipantId (Format 0245:<Ziffern der Steuernummer>), und wir registrieren sie automatisch im zentralen SK SMP; ab diesem Moment empfängt sie E-Rechnungen.
  4. Sie tun nichts: Den Abschluss erfassen Sie mit dem Webhook company.activatedoder per Polling von GET /companies/{id}, bis peppolParticipantId befüllt ist (wird ausschließlich auf diesem Weg gesetzt).

Versand → sending-verified

Weisen Sie das Verifizierungsmerkmal über die API nach

Das Verifizierungsmerkmal (Verifikačný údaj, VÚ) ist eine signierte Zeichenkette, die die Firma bei der Auswahl des Anbieters von der Finanzverwaltung erhält (per E-Mail / im PDS-Portal). Der Kunde gibt es in Ihrer Oberfläche ein, und Sie weisen es mit einem einzigen Aufruf nach; wir prüfen die RSA-Signatur der 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": "<Verifizierungsmerkmal, 1024 Hex-Zeichen>"}'
# → 200 { "companyId": "…", "status": "active",
#         "sendingVerified": true,
#         "verificationMethod": "self", "verifiedAt": "…" }

Ungültige Signatur → 400 token_invalid. Fehlende Steuernummer → 400 company_dic_missing.

Nimmt der Kunde die Auswahl im FS-Portal vor, werden beide Schritte auf einmal erledigt: Der Webhook der FS trägt auch das Verifizierungsmerkmal, sodass die Firma sofort active und sending-verified sowie für den Empfang registriert ist. Der eigenständige Nachweis des VÚ über die API schaltet nur das Senden frei; die Registrierung für den Empfang (SMP) löst erst die Auswahl im FS-Portal aus. Empfohlener Ablauf für SaaS: Firma über die API anlegen → Kunden zur Auswahl bei der FS schicken → fertig.

Schritt 3

Rechnungsempfang: Webhooks mit HMAC-Signatur oder Pull über die API

A · Push: Webhook pro Tenant (empfohlen)

Richten Sie für jede Firma eine Webhook-URL (und optional eine Benachrichtigungs-E-Mail) ein und holen Sie das Signatur-Secret ab (es wird nur einmal zurückgegeben):

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://vasa-saas.sk/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_…" }   ← speichern, wird nur einmal angezeigt

Bei einer empfangenen Rechnung senden wir an Ihre URL einen POST (Ereignis invoice.received; bei einer gesendeten invoice.sent):

http
POST https://vasa-saas.sk/peppol/webhook
Content-Type: application/json
X-Verteco-Event: invoice.received
X-Verteco-Signature: sha256=3f1a9c…   ← HMAC-SHA256 über den rohen Body

{
  "event": "invoice.received",
  "companyId": "9fa8fd81-…",
  "companyDic": "SK2121358349",
  "peppolParticipantId": "0245:2121358349",
  "documentId": "574d4e52-…",
  "invoiceNumber": "2027-0142",
  "senderId": "0245:2120433843",
  "supplierName": "Lieferant 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-…"
}

Den Partner-Signaturschlüssel richten Sie selbst ein (Vermittler): PUT /api/v1/resellers/me/notification-webhook mit dem Body { "url": "https://…" } speichert die URL, an die wir die Ereignisse aller Ihrer Kundenfirmen senden, und gibt beim ersten Einrichten den Signaturschlüssel (secret) zurück; er wird nur einmal angezeigt. Eine spätere Anzeige verlangt das Kontopasswort (im Portal in den Firmendetails oder POST …/notification-webhook/reveal mit dem Body { "password": "…" }); jede Anzeige wird mit IP und Zeit im Sicherheitsprotokoll vermerkt, und die letzte sehen Sie in der GET-Antwort. Die Authentifizierung erfolgt über Ihr Portalkonto (Session oder Bearer-Token); den Schlüssel senden wir nie per E-Mail. Dass eine Firma Vermittler ist, sehen Sie in der API an ihrem Datensatz als reseller: true (das Kennzeichen whiteLabel markiert erst die Firmen Ihrer Kunden).

Prüfung der Signatur (Node.js):

javascript
import crypto from 'node:crypto';

function verifyVertecoWebhook(rawBody, signatureHeader, secret) {
  // Signatur = "sha256=" + hex( HMAC-SHA256(secret, roher Request-Body) )
  const expected = 'sha256=' + crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
  return signatureHeader?.length === expected.length
    && crypto.timingSafeEqual(Buffer.from(signatureHeader), Buffer.from(expected));
}
// Wichtig: Berechnen Sie den HMAC über den ROHEN Body (raw bytes), nicht über neu serialisiertes JSON.
ZustelleigenschaftWert
Erfolgjede 2xx-Antwort von Ihrer Seite
Retrybis zu 8 Versuche, exponentielles Backoff 30 s → max. 1 h, danach Dead-Letter
Timeout15 s pro Versuch; Weiterleitungen werden nicht gefolgt
URLöffentliche http(s)-Adresse; interne/private IPs blockieren wir (SSRF-Guard)
DeduplizierungRetry sendet einen identischen Body; deduplizieren Sie nach documentId
TestPOST /companies/{id}/webhook/test (sendet ein signiertes Ereignis webhook.test mit "test": true)

B · Pull: SAPI-SK receive (Alternative oder Ergänzung)

bash
# Liste der empfangenen Belege (inkrementell über ?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 einschließlich des Original-XML genau so, wie es aus dem Netzwerk kam
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" }

# Bestätigung der Verarbeitung (idempotent)
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'

An die Belege kommen Sie auch über die Portal-API: GET /companies/{id}/documents?direction=received, Download …/documents/{docId}/download?format=xml|html|mls, Sammelexporte …/documents/export.csv und …/documents/export.zip (Original-XML). Die E-Mail-Benachrichtigung an die Firma (wenn Sie sie einschalten) trägt die Rechnung als PDF + Original-XML im Anhang, der Absender trägt den Namen der Firma, und Reply-To zeigt auf den Kontoinhaber (Verhalten für White-Label vorbereitet).

Schritt 4

Rechnungsversand über SAPI-SK: OAuth2, Idempotenz, Zustellnachweise

1 · Token-Austausch (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 Ihres API-Tokens>",
    "client_secret": "vpt_8f2a…"
  }'
# → 200 { "access_token": "eyJ…", "token_type": "Bearer",
#         "expires_in": 900, "refresh_token": "eyJ…" }
# der Access-Token gilt 15 min (Erneuerung über POST /sapi/auth/renew, Refresh 30 Tage);
# GET /sapi/auth/token/status gibt should_refresh: true < 3 min vor Ablauf zurück

2 · Senden eines Belegs (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": "<optional: SHA-256 hex des Payloads>"
  }'
# → 202 { "providerDocumentId": "<UUID bei uns>", "status": "ACCEPTED", "receivedAt": "…", "timestamp": "…" }
# bei "REJECTED" (Validierung nicht bestanden / vom Netzwerk abgelehnt) trägt die Antwort auch das Feld
# "detail" mit dem konkreten Grund (z. B. verletzte Regeln BR-CO-15, …)
Idempotenz: Der Header Idempotency-Key (wir empfehlen die Rechnungsnummer oder eine interne ID) schützt vor doppeltem Versand: Ein wiederholter Aufruf mit demselben Schlüssel gibt das ursprüngliche Ergebnis zurück, ein neuer Schlüssel für dieselbe Rechnung kann sie zweimal senden. Laufender Versand mit demselben Schlüssel → 502 SAPI-PROC-001 (retryable: true, versuchen Sie es in Kürze erneut); nach einem Transportfehler (failed) sendet ein Retry mit demselben Schlüssel den Beleg tatsächlich erneut. Derselbe Schlüssel sendet den Beleg auch dann erneut, wenn unsere Prüfung vor dem Versand ihn abgelehnt hat (REJECTED, nichts ging ins Netzwerk) oder wenn er als undeliverable endete (nach Korrektur der Empfängerkennung oder nach dessen Registrierung); das Vorgehen einschließlich des Ausstellungsdatums der korrigierten Rechnung steht in der Dokumentation für Entwickler. Payload-Limit: 10 MB. Belege validieren wir vor dem Versand mit demselben EN 16931 + Peppol BIS Regelwerk wie beim Empfang; ein ungültiger Beleg gibt REJECTED mit den konkreten Regeln zurück (z. B. BR-CO-15).

3 · Stapelversand (bis zu 100 Belege)

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" },
        …
      ] }'
# (schematisches Beispiel: metadata hat dieselben Felder wie beim Einzelversand)
# → 202 { "total": 100, "accepted": 98, "rejected": 1, "failed": 1,
#         "results": [ { "itemId": "…", "ok": true, "providerDocumentId": "…", "status": "ACCEPTED" }, … ] }
# die Positionen werden sequenziell verarbeitet; das Scheitern einer beeinflusst die anderen nicht

4 · Zustellstatus und Zustellnachweise (MLS)

Lebenszyklus eines gesendeten Belegs: pending → submitted → delivered / rejected (bestätigt durch den MLS-Zustellnachweis des Access Points des Empfängers) oder failed (Transportfehler; Retry mit demselben Idempotency-Key), gegebenenfalls undeliverable (der Empfänger hat keine Adresse im Peppol-Netzwerk: Den Beleg haben wir übernommen und melden ihn der Finanzverwaltung, zugestellt wird er niemandem). Verfolgen Sie die Status inkrementell:

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 aus der Send-Antwort (UUID bei uns); ordnen Sie danach zu
# oder nach peppolMessageId; bei "rejected" trägt die Zeile auch statusDetail mit dem Grund.
# ?since= erfasst auch STATUSÄNDERUNGEN (nicht nur neue Belege); ideal für Polling alle paar Minuten

# Zustellnachweis (MLS ApplicationResponse XML), der rechtliche Nachweis der Zustellung:
curl "https://peppol.verteco.digital/api/v1/companies/{id}/documents/{documentId}/download?format=mls" \
  -H 'Authorization: Bearer vpt_8f2a…'
Die slowakische Steuermeldung (TDD) zu empfangenen wie gesendeten Belegen übernehmen wir automatisch nach dem Zeitplan, zu dem die Finanzverwaltung die produktive C5-Schnittstelle bereitstellt; Sie als Partner implementieren nichts zusätzlich. Einfachere Alternative zu SAPI für den Versand: der Portal-Endpunkt POST /companies/{id}/documents/send mit dem Body { "xml": "…", "receiverParticipantId": "0245:…" } (Beta: Die Form der Antwort kann sich noch ändern).

Volle Parität

Alles, was ein Direktkunde hat, bedienen Sie über die API

Ihr Tenant muss unser Portal nie öffnen: Jede Funktion, die ein Direktkunde im Dashboard hat, existiert als REST-Endpunkt unter Ihrem Token. Übersicht der gesamten Verwaltungsfläche (alles Authorization: Bearer vpt_…, Basis /api/v1):

BereichEndpunkte
Firmen (Tenants)GET/POST /companies · GET/PUT /companies/{id} · Paginierung ?page&limit + X-Total-Count
SendeverifizierungPOST /companies/{id}/verification (Verifizierungsmerkmal)
Vorausfüllen aus dem RegisterGET /lookup/company?ico= → Name + Adresse aus dem RPO
BelegeGET /companies/{id}/documents?direction=received|sent · GET …/documents/{docId} · POST …/documents/send · POST …/documents/send-test
Download und ExporteGET …/documents/{docId}/download?format=xml|html|mls · GET …/documents/export.csv · GET …/documents/export.zip (?direction&from&to)
RechnungseinstellungenGET/PUT /companies/{id}/invoice-settings: Nummerierung ({YYYY}{NNNN}), Fälligkeit, Standard-IBAN und Anmerkung
KundenadressbuchGET/POST /companies/{id}/address-book · DELETE …/address-book/{entryId} (automatisch gespeichert nach erfolgreichem Versand)
Benachrichtigungen und WebhooksGET/PUT /companies/{id}/notifications · POST …/webhook/secret · POST …/webhook/test · Ereignisse invoice.received / invoice.sent / invoice.delivered / invoice.rejected / company.activated / company.deactivated / company.smp_registered_elsewhere
White-Label-ModusPUT /companies/{id} mit { "whiteLabel": true }; die Plattform sendet dem Tenant keine eigenen E-Mails
TeamGET /account/team · POST /account/team/invite · POST /account/team/accept
API-SchlüsselGET/POST /tokens · DELETE /tokens/{id}
Belege (SAPI-SK)POST /sapi/document/send · POST …/batch · GET …/receive (+Detail, acknowledge) · GET …/sent
Das Einzige, was Sie für den Tenant nicht erledigen können, ist die einmalige Auswahl des Anbieters im Portal der Finanzverwaltung (eID oder Zugangsdaten des PFS-Portals). Nach der Auslegung der FS ist sie eine Bedingung des Empfangs, die gleichermaßen für Direktkunden gilt; für das Senden liefert der Tenant damit das Verifizierungsmerkmal. Alles andere läuft programmatisch. Optionaler Bonus: Nach der Auswahl bei der FS erhält der Tenant einen Magic-Link in unser Portal; er kann ihn nutzen, muss es aber nie.

Unsichtbare Infrastruktur

White-Label-Betrieb: Der Tenant kommuniziert nur mit Ihnen

Zielzustand: Ihr Kunde nutzt Ihr Produkt, Ihre Marke und Ihren Support; wir sind die unsichtbare Infrastruktur. Drei Schritte, die das sicherstellen:

  1. 1 · Schalten Sie den White-Label-Modus bei der Firma ein

    Mit whiteLabel: true sendet die Plattform dem Tenant keine eigenen E-Mails (z. B. die Bestätigung der Anbieterauswahl) und übernimmt seine Kontaktadresse nicht aus der Auswahl bei der FS. Die Kommunikation führen Sie, unter eigener Marke.

    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":"Kundenfirma s.r.o.",
           "street":"Musterstraße 12","postalCode":"010 01","city":"Žilina",
           "iban":"SK31 1200 0000 1987 4263 7541","whiteLabel":true}'
    # am einfachsten senden Sie whiteLabel bereits beim POST /companies (Anlegen der Firma);
    # ACHTUNG: PUT ist eine vollständige Aktualisierung; senden Sie alle optionalen Felder (Adresse, IBAN),
    # ausgelassene werden gelöscht
  2. 2 · Benachrichtigungen über Webhooks lösen, nicht über unsere E-Mails

    Im White-Label-Modus sendet die Plattform überhaupt keine E-Mails zu Rechnungen (das Feld notificationEmail wird ignoriert). Richten Sie einen Webhook ein, und von einer empfangenen Rechnung erfahren Sie über invoice.received. Den Inhalt laden Sie über die API herunter (XML / druckbares HTML) und senden dem Kunden eine eigene E-Mail von Ihrer eigenen Domain.

  3. 3 · Den Abschluss der Auswahl bei der FS erfassen Sie mit dem Webhook company.activated

    Schließt der Kunde die Auswahl des Anbieters im Portal der Finanzverwaltung ab, senden wir an den Webhook der Firma ein Ereignis (Sie müssen nicht pollen):

    http
    POST https://vasa-saas.sk/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"
    }

    Das Ereignis bedeutet: Auswahl kryptografisch geprüft, Firma auf status: "active" umgestellt, Registrierung im SK SMP abgeschickt; der Tenant ist bereit, zu empfangen und zu senden (das Verifizierungsmerkmal kam zusammen mit der Auswahl). Das Ereignis ist at-least-once; verarbeiten Sie es idempotent und richten Sie sich immer nach dem Feld status im Body (wir senden es nur für tatsächlich aktivierte Firmen; eine vom Administrator pausierte Firma erhält es nicht).

Wichtige Reihenfolge: Legen Sie die Firma über die API an, bevor Sie den Kunden zur Auswahl in das FS-Portal schicken. Erfolgte die Auswahl für eine Steuernummer, die bei uns noch nicht existiert, würde das System die Firma automatisch als Selbstbedienungsfirma anlegen, einschließlich einer Willkommens-E-Mail an den Kunden (außerhalb des White-Label-Modus). Bei Einhaltung der Reihenfolge „zuerst die Firma, dann die Auswahl“ geht keine E-Mail von uns an den Tenant.

Was der Tenant sieht und was nicht (ehrlich)

Für den Tenant unsichtbar

  • · die gesamte API, das Portal, das Dashboard (der Tenant braucht sie nie)
  • · E-Mails: Im White-Label-Modus kommen von uns keine
  • · die technische Identität im Netzwerk (unser Access-Point-Zertifikat); nur andere Access Points sehen sie

Der Schritt, der bei der Firma bleibt

  • · die einmalige Auswahl des Anbieters im Portal der Finanzverwaltung: Dort wählt der Kunde „Verteco digital services“ aus der staatlichen Liste der zertifizierten Anbieter. Das gilt gleichermaßen für jeden Anbieter am Markt; für den Empfang ist es nach der Auslegung der Finanzverwaltung eine Pflicht, für das Senden erhält die Firma damit das Verifizierungsmerkmal (FAQ der FS, Beispiel 73).
  • · das Verifizierungsmerkmal der FS, das die Firma uns (über Sie) vor dem Senden nachweist

Auch dieses letzte Fenster lässt sich umbranden: Die Finanzverwaltung erlaubt zertifizierten Anbietern, Partner als Vermittler des Zustelldienstes zu registrieren. Nach der Eintragung wählt der Kunde auf vpds.financnasprava.sk direkt Ihre Marke aus der Liste. Den Antrag auf Eintragung erzeugen Sie in wenigen Minuten unter /sprostredkovatel.

Sicherheit und gesetzliche Anforderungen

AnforderungSo wird sie erfüllt
Berechtigung zum Senden (§ 76a Abs. 2 Buchst. b) Gesetz Nr. 222/2004)fail-closed Gate: Ohne kryptografisch geprüftes Verifizierungsmerkmal der FS gibt jeder Send 403 zurück; nicht zu umgehen, weder über die API noch über Batch
Zustimmung der Firma zum AnbieterAuswahl im FS-Portal (Anmeldung per eID oder mit den Zugangsdaten des PFS-Portals); die FS stellt sie uns signiert zu (RSA-PSS); wir prüfen die Signatur, nicht die Behauptung
Schutz personenbezogener DatenRechnungsdaten in der EU (Frankfurt); Verarbeitung gemäß AGB und Datenschutzgrundsätzen (Links unten); Webhooks HMAC-signiert, Secrets lassen sich nicht zurücklesen
ZustellnachweisMLS-Zustellnachweis (ApplicationResponse), empfangen über den geprüften AS4-Kanal vom Access Point des Empfängers, über die API herunterladbar als rechtlicher Nachweis der Zustellung
Steuermeldung (TDD)übernehmen wir automatisch nach dem Zeitplan der Bereitstellung der C5-Schnittstelle der FS; der Partner implementiert nichts
Isolation der TenantsZugriff nur über die Mitgliedschaft in der Firma; der API-Token hat strikt dieselben Rechte wie Ihr Konto; SAPI prüft die Übereinstimmung des Absenders mit dem autorisierten Teilnehmer
ISO/IEC 27001das Zertifikat muss bisher kein Anbieter haben (OpenPeppol verlangt es von allen ab dem 1. 10. 2027); unsere Zertifizierung nach ISO/IEC 27001:2022 läuft bei der akkreditierten Stelle SKQS, s. r. o., Žilina (SNAS), ausgewählt im September 2026, das Zertifikat planen wir bis zum 1. 7. 2027

Rechtsdokumente: Allgemeine Geschäftsbedingungen · Schutz personenbezogener Daten. Das Vertragsverhältnis mit uns haben Sie als Partner; gegenüber Ihren Kunden treten Sie nach eigenen Bedingungen auf.

Entwicklung und Test

Sandbox: öffentlich, ohne Registrierung

Den gesamten SAPI-SK-Vertrag probieren Sie sofort mit den öffentlichen Zugangsdaten client_id = sandbox / client_secret = sandbox aus. Die Sandbox validiert Anfragen genau wie die Produktion, stellt aber nie etwas zu und sieht keine echten Daten; die Isolation ist direkt im signierten Token erzwungen.

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: vollständige Vertragsvalidierung, nichts wird zugestellt
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 · Muster eines empfangenen Belegs
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'

Ergänzungen zur Sandbox: öffentlicher E-Rechnungs-Validator (dieselben Regeln wie der produktive AP), Test-Webhook (POST /companies/{id}/webhook/test) und eine Testrechnung über das echte Netzwerk an die eigene Firma (POST /companies/{id}/documents/send-test).

Ohne Authentifizierung

Öffentliche API: Empfängerprüfung und Belegvalidierung

Prüfung des Empfängers im Peppol-Netzwerk

Prüfen Sie vor dem Versand, ob der Empfänger registriert ist (Live-SML/SMP-Lookup). Akzeptiert die SK USt-IdNr., die Steuernummer und die vollständige 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": "…" }

Validierung der E-Rechnung (EN 16931 + Peppol BIS)

Dasselbe Regelwerk, das jeder Beleg in unserem Access Point durchläuft, ideal für die CI oder für die Entwicklung des Mappings:

bash
curl -X POST "https://peppol.verteco.digital/api/v1/public/peppol-validate" \
  -H 'Content-Type: application/xml' --data-binary @rechnung.xml
# → { "valid": false,
#     "errors": ["BR-CO-15: Invoice total amount with VAT …"],
#     "warnings": [] }     (Limit 3 MB)
Öffentliche Endpunkte haben ein strengeres Rate-Limit (15 Aufrufe/min pro IP); sie sind für einzelne Prüfungen bestimmt, nicht für Massenscans. Rufen Sie sie in der Integration vor dem Versand auf; die Ergebnisse positiver Prüfungen cachen wir kurzzeitig.

Robustheit

Rate-Limits, Fehlerantworten und Größenlimits

Rate-Limits (festes 60-Sekunden-Fenster)

BereichLimitSchlüssel
/api/v1/** (Portal) und /sapi/document/*dynamisch, mit großer Reservepro API-Token
/sapi/auth/* und /api/v1/auth/*strenger (gegen Brute-Force)pro IP-Adresse
/api/v1/public/** (Checker, Validator)strengerpro IP-Adresse

Jede Antwort trägt die Header RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset; bei Überschreitung kommt 429 mit dem Header Retry-After und dem Body { "error": "rate_limited", "message": "Too many requests. Slow down." }. (Ausnahme: /auth/me und /auth/logout laufen im regulären Token-Bucket.) Lesen Sie die aktuellen Limitwerte immer aus den Headern; sie sind so gesetzt, dass der normale Betrieb einschließlich Spitzen sie nie erreicht. Bei Massen-Onboarding / Stapelversand dosieren Sie mit Backoff auf 429. Brauchen Sie ein höheres Limit? Schreiben Sie uns.

Zwei Fehlerformen

Portal-API (/api/v1/**)

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

// bei der Feldvalidierung zusätzlich:
{ "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-…"
} }
SAPI-CodeHTTPBedeutung
SAPI-AUTH-001401ungültige / widerrufene Client-Credentials
SAPI-AUTH-002401fehlender / ungültiger / abgelaufener Bearer-Token
SAPI-AUTH-003403 / 401die Firma für den Teilnehmer existiert nicht, Sie haben keinen Zugriff auf sie, der Absender stimmt nicht, das geprüfte Verifizierungsmerkmal fehlt; oder (bei /auth/token und /auth/renew, 401) die aufrufende IP steht nicht auf der im Portal gesetzten Allowlist des API-Schlüssels
SAPI-VAL-001 / 002400ungültige Felder / fehlender Header X-Peppol-Participant-Id
SAPI-RES-001 / 002404Beleg existiert nicht / Original-Payload ist nicht archiviert
SAPI-PROC-001502vorübergehender Fehler (retryable: true); wiederholen Sie mit demselben Idempotency-Key
SAPI-PROC-002503vorübergehender Infrastrukturfehler (retryable: true); wiederholen Sie mit demselben Idempotency-Key
SAPI-PROC-500500unerwarteter Fehler (retryable: false); nicht wiederholen, melden Sie uns die correlation_id

Größenlimits

WoLimit
SAPI-Payload (send / Batch-Position)10 MB pro Beleg; Batch max. 100 Positionen
Portal-Send (Feld xml)2 MB
Öffentlicher Validator3 MB
Listen (receive / sent / documents)limit max. 200 pro Seite, Standard 50

Geschäftsmodell

Wiederverkauf und White-Label: So wird gerechnet

Empfang ohne Archiv kostenlos

Eine Firma mit ausgeschaltetem Datenarchiv empfängt E-Rechnungen kostenlos bis zu 1 000 Rechnungen pro Monat (gesendete und empfangene zusammen), einschließlich der Steuermeldung; der Beleginhalt wird bei uns 14 Tage nach der Zustellung gelöscht. Firmen unter Ihrer Marke (White-Label) werden ohne Archiv angelegt.

Versand und Datenarchiv ab 2 €/Monat

Bezahlt wird für jede Firmen-ID (IČO), die im Monat eine Rechnung gesendet oder das Datenarchiv eingeschaltet hatte (bei neuen Firmen im Portal standardmäßig): 2 € pro Monat zzgl. MwSt., abgezogen von Ihrem vorausbezahlten Guthaben immer am 1. Tag des Monats für den abgeschlossenen Monat (erste Abbuchung am 1. 2. 2027 für Januar 2027). Im Preis enthalten sind das Archiv der Originale in der EU (1 GB), REST-API, Webhooks, Konnektoren, mehrere Firmen-IDs, B2G und White-Label.

0,01 € über dem Limit

Jede Rechnung (empfangene oder gesendete) über 1 000 Rechnungen pro Monat (gesendete und empfangene zusammen) hinaus; keine harte Obergrenze, die Zustellung blockieren wir nie.

Ihre Marge ist Ihre Sache

Ihren Kunden stellen Sie selbst Rechnungen, nach eigener Preisliste. Uns zahlen Sie nach der öffentlichen Preisliste, ohne versteckte Partnergebühren.

White-Label inklusive

Die Lösung unter eigener Marke ist Bestandteil des Pakets: E-Mails zu Rechnungen tragen den Namen der Kundenfirma, Ihre Oberfläche bleibt Ihre.

Mengenvereinbarung

Bei Dutzenden und Hunderten Firmen bereiten wir eine Mengenvereinbarung vor und erhöhen die Kontolimits kostenlos. Schreiben Sie uns.

Während der freiwilligen Phase (bis zum 1. 1. 2027) ist alles kostenlos; die Preise laut Preisliste gelten ab der Pflicht. Möchten Sie nicht selbst integrieren? Die betreute Anbindung Ihres Systems übernehmen wir, Preis nach Umfang zzgl. MwSt. einmalig. Eines lässt sich nicht übertragen: Jede Firma muss vor dem Senden bei uns ein geprüftes Verifizierungsmerkmal haben (fail-closed Gate gemäß Empfehlung der FS, § 76a Abs. 2 Gesetz Nr. 222/2004), und die Auswahl des Anbieters im FS-Portal nimmt die Firma selbst vor (eID oder Zugangsdaten des PFS-Portals).

Go-live

Checkliste vor dem Start

  • ✓Konto + API-Token erstellt, Token sicher auf dem Server gespeichert (nie im Frontend).
  • ✓Onboarding-Ablauf: POST /companies + Weiterleitung des Kunden zur Auswahl des Anbieters im FS-Portal (eID).
  • ✓Status-Polling: Sie verfolgen peppolParticipantId (Signal, dass die Firma empfängt) sowie das Kennzeichen verified + status active vor dem ersten Versand.
  • ✓Webhook-Endpunkt: prüft X-Verteco-Signature (HMAC-SHA256 über den rohen Body), antwortet 2xx innerhalb von 15 s, dedupliziert nach documentId.
  • ✓Versand: Idempotency-Key bei jedem Send, Backoff auf 429 und SAPI-PROC-001, Polling von /sapi/document/sent?since= für Zustellstatus.
  • ✓Belegmapping über den öffentlichen Validator und die Sandbox getestet; erster scharfer Test über send-test.
  • ✓Fehlerzustände behandelt: 403 sending_not_verified, 409 ico_taken, REJECTED-Verdikt mit Grund.
  • ✓Kontolimits entsprechend der Anzahl Firmen erhöht (schreiben Sie uns bei >10 Firmen).

Fragen von Partnern

Häufige Fragen von SaaS und Plattformen

Muss jeder unserer Kunden ein Konto in Ihrem Portal haben?
Nein. Das Modell ist ein Proxy: Ihr Backend hält einen einzigen API-Token, und die Firmen Ihrer Kunden legen Sie über die API in Ihrem eigenen Konto an und verwalten sie dort. Der Kunde macht genau einen Schritt außerhalb Ihres Produkts: die einmalige Auswahl des Anbieters im Portal der Finanzverwaltung (eID oder Zugangsdaten des PFS-Portals). Nach der Auslegung der FS ist die Auswahl für den Empfang verpflichtend; für das Senden liefert die Firma damit das Verifizierungsmerkmal (Verifikačný údaj), das wir vor dem Senden verlangen. Ein Portalkonto bei uns ist für ihn ein optionaler Bonus, keine Bedingung.
Wie erfahren wir, dass der Kunde die Auswahl bei der Finanzverwaltung abgeschlossen hat?
Am einfachsten: Richten Sie für die Firma einen Webhook ein und hören Sie auf das Ereignis company.activated. Wir senden es unmittelbar nach der kryptografischen Prüfung der Auswahl, zusammen mit der zugewiesenen peppolParticipantId. Alternativ Polling: GET /api/v1/companies/{id}, wobei das verlässliche Signal einer abgeschlossenen Auswahl (und damit der Empfangsfähigkeit) das befüllte Feld peppolParticipantId ist (es wird ausschließlich nach der Auswahl im FS-Portal gesetzt). Der Status active allein genügt nicht: Er wird auch gesetzt, wenn das Verifizierungsmerkmal über die API nachgewiesen wird, was nur das Senden freischaltet.
Können wir den Dienst unter eigener Marke (White-Label) verkaufen?
Ja. Die White-Label-Lösung ist Bestandteil des Pakets Senden und Empfangen, ohne gesonderte Partnergebühren. Sie setzen bei der Firma whiteLabel: true, und die Plattform sendet ihr keine eigenen E-Mails; Benachrichtigungen beziehen Sie über Webhooks und kommunizieren unter eigener Marke. Den Preis für Ihre Kunden bestimmen Sie und stellen ihn selbst in Rechnung; uns zahlen Sie nach der öffentlichen Preisliste.
Wie testen wir die Integration ohne echte Belege?
Drei Werkzeuge: die öffentliche SAPI-Sandbox (client_id und client_secret = „sandbox“) mit vollständiger Vertragsvalidierung, die nie etwas zustellt; der öffentliche E-Rechnungs-Validator (POST /api/v1/public/peppol-validate) mit denselben EN 16931 + Peppol BIS Regeln wie der produktive Access Point; und der Test-Webhook (POST /companies/{id}/webhook/test), der ein signiertes Musterereignis an Ihre URL sendet.
Was, wenn ein Kunde Tausende Rechnungen pro Monat sendet?
Keine harte Obergrenze: über 1 000 Rechnungen pro Monat (gesendete und empfangene zusammen) hinaus kostet jede weitere Rechnung 0,01 €. Die API unterstützt den Stapelversand (Batch bis zu 100 Belege pro Aufruf) und den inkrementellen Abruf über den Parameter since. Bei großen Mengen an Firmen oder Belegen bereiten wir eine Mengenvereinbarung vor.
Welche Belegarten können Sie empfangen und senden?
Peppol BIS Billing 3.0 Rechnungen und Gutschriften (UBL 2.1) einschließlich der SK-Billing-Regeln, Self-Billing-Rechnungen und -Gutschriften sowie MLS-Zustellnachweise. Die slowakische Steuermeldung (TDD) zu den Belegen übernehmen wir automatisch nach dem Zeitplan, zu dem die Finanzverwaltung ihre Schnittstelle bereitstellt.
Ist die API versioniert und stabil?
Ja. Die maschinenlesbare OpenAPI-3.1-Spezifikation liegt unter /api/v1/openapi.json und deckt sowohl die Portal-API als auch SAPI-SK ab. SAPI-SK ist eine nationale standardisierte Schnittstelle, kein proprietärer Vertrag, die Integration ist also kein Vendor-Lock-in. Änderungen nehmen wir abwärtskompatibel vor.

Starten Sie noch heute mit der Sandbox · ein produktives Konto haben Sie in einer Minute

Verwandt: vollständige API-Dokumentation · OpenAPI 3.1 · fertige E-Shop-Plugins · für Buchhalter · Preisliste