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.
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 ◀── AbsenderpeppolParticipantId); 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. Erstellen Sie ein Konto unter /register (E-Mail + Passwort, kostenlos, ohne Bindung).
- 2. Öffnen Sie im Dashboard API-Tokens (
/dashboard/tokens) und erstellen Sie einen Token. Das Format istvpt_+ 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_idfür SAPI-SK. - 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:
curl https://peppol.verteco.digital/api/v1/auth/me -H 'Authorization: Bearer vpt_8f2a…'
# → 200 { "id": "…", "email": "dev@vasa-saas.sk", … }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.
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)| Feld | Regeln |
|---|---|
| ico | 8 Ziffern; beim Anlegen Pflicht; unveränderlich, sobald gesetzt (400 ico_immutable); Duplikat → 409 ico_taken |
| dic | USt-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) |
| legalName | Pflicht, max. 500 Zeichen; nach der Prüfung durch die Finanzverwaltung gesperrt (400 company_verified_locked) |
| street / city / postalCode | optional (max. 255 / 128 / 16 Zeichen) |
| country | optional, 2 Zeichen, Standard „SK“ |
| iban | optional, max. 34 Zeichen; wird in Rechnungen vorausgefüllt, die in unserer Weboberfläche erstellt werden |
| registeredAddress | optional, 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):
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" }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)
- 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.
- Die Finanzverwaltung sendet uns einen Webhook mit kryptografisch signierter Zustimmung; wir prüfen sie automatisch.
- Die Firma wechselt auf
status: "active", erhält einepeppolParticipantId(Format0245:<Ziffern der Steuernummer>), und wir registrieren sie automatisch im zentralen SK SMP; ab diesem Moment empfängt sie E-Rechnungen. - Sie tun nichts: Den Abschluss erfassen Sie mit dem Webhook
company.activatedoder per Polling vonGET /companies/{id}, bispeppolParticipantIdbefü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:
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.
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):
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 angezeigtBei einer empfangenen Rechnung senden wir an Ihre URL einen POST (Ereignis invoice.received; bei einer gesendeten invoice.sent):
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):
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.| Zustelleigenschaft | Wert |
|---|---|
| Erfolg | jede 2xx-Antwort von Ihrer Seite |
| Retry | bis zu 8 Versuche, exponentielles Backoff 30 s → max. 1 h, danach Dead-Letter |
| Timeout | 15 s pro Versuch; Weiterleitungen werden nicht gefolgt |
| URL | öffentliche http(s)-Adresse; interne/private IPs blockieren wir (SSRF-Guard) |
| Deduplizierung | Retry sendet einen identischen Body; deduplizieren Sie nach documentId |
| Test | POST /companies/{id}/webhook/test (sendet ein signiertes Ereignis webhook.test mit "test": true) |
B · Pull: SAPI-SK receive (Alternative oder Ergänzung)
# 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)
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ück2 · Senden eines Belegs (UBL 2.1, Peppol BIS Billing 3.0)
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, …)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)
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 nicht4 · 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:
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…'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):
| Bereich | Endpunkte |
|---|---|
| Firmen (Tenants) | GET/POST /companies · GET/PUT /companies/{id} · Paginierung ?page&limit + X-Total-Count |
| Sendeverifizierung | POST /companies/{id}/verification (Verifizierungsmerkmal) |
| Vorausfüllen aus dem Register | GET /lookup/company?ico= → Name + Adresse aus dem RPO |
| Belege | GET /companies/{id}/documents?direction=received|sent · GET …/documents/{docId} · POST …/documents/send · POST …/documents/send-test |
| Download und Exporte | GET …/documents/{docId}/download?format=xml|html|mls · GET …/documents/export.csv · GET …/documents/export.zip (?direction&from&to) |
| Rechnungseinstellungen | GET/PUT /companies/{id}/invoice-settings: Nummerierung ({YYYY}{NNNN}), Fälligkeit, Standard-IBAN und Anmerkung |
| Kundenadressbuch | GET/POST /companies/{id}/address-book · DELETE …/address-book/{entryId} (automatisch gespeichert nach erfolgreichem Versand) |
| Benachrichtigungen und Webhooks | GET/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-Modus | PUT /companies/{id} mit { "whiteLabel": true }; die Plattform sendet dem Tenant keine eigenen E-Mails |
| Team | GET /account/team · POST /account/team/invite · POST /account/team/accept |
| API-Schlüssel | GET/POST /tokens · DELETE /tokens/{id} |
| Belege (SAPI-SK) | POST /sapi/document/send · POST …/batch · GET …/receive (+Detail, acknowledge) · GET …/sent |
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 · Schalten Sie den White-Label-Modus bei der Firma ein
Mit
whiteLabel: truesendet 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.bashcurl -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öscht2 · 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
notificationEmailwird ignoriert). Richten Sie einen Webhook ein, und von einer empfangenen Rechnung erfahren Sie überinvoice.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 · 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):
httpPOST 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 Feldstatusim Body (wir senden es nur für tatsächlich aktivierte Firmen; eine vom Administrator pausierte Firma erhält es nicht).
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
| Anforderung | So 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 Anbieter | Auswahl 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 Daten | Rechnungsdaten in der EU (Frankfurt); Verarbeitung gemäß AGB und Datenschutzgrundsätzen (Links unten); Webhooks HMAC-signiert, Secrets lassen sich nicht zurücklesen |
| Zustellnachweis | MLS-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 Tenants | Zugriff 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 27001 | das 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.
# 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:
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:
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)Robustheit
Rate-Limits, Fehlerantworten und Größenlimits
Rate-Limits (festes 60-Sekunden-Fenster)
| Bereich | Limit | Schlüssel |
|---|---|---|
| /api/v1/** (Portal) und /sapi/document/* | dynamisch, mit großer Reserve | pro API-Token |
| /sapi/auth/* und /api/v1/auth/* | strenger (gegen Brute-Force) | pro IP-Adresse |
| /api/v1/public/** (Checker, Validator) | strenger | pro 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/**)
{ "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/**)
{ "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-Code | HTTP | Bedeutung |
|---|---|---|
| SAPI-AUTH-001 | 401 | ungültige / widerrufene Client-Credentials |
| SAPI-AUTH-002 | 401 | fehlender / ungültiger / abgelaufener Bearer-Token |
| SAPI-AUTH-003 | 403 / 401 | die 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 / 002 | 400 | ungültige Felder / fehlender Header X-Peppol-Participant-Id |
| SAPI-RES-001 / 002 | 404 | Beleg existiert nicht / Original-Payload ist nicht archiviert |
| SAPI-PROC-001 | 502 | vorübergehender Fehler (retryable: true); wiederholen Sie mit demselben Idempotency-Key |
| SAPI-PROC-002 | 503 | vorübergehender Infrastrukturfehler (retryable: true); wiederholen Sie mit demselben Idempotency-Key |
| SAPI-PROC-500 | 500 | unerwarteter Fehler (retryable: false); nicht wiederholen, melden Sie uns die correlation_id |
Größenlimits
| Wo | Limit |
|---|---|
| SAPI-Payload (send / Batch-Position) | 10 MB pro Beleg; Batch max. 100 Positionen |
| Portal-Send (Feld xml) | 2 MB |
| Öffentlicher Validator | 3 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.
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