Einführung
Die Verteco API ist REST über HTTPS. Request und Response sind JSON (UTF-8). Beginnen Sie mit dem Anlegen eines Kontos, dann eines API-Tokens, und führen Sie den ersten Aufruf innerhalb einer Minute aus. Alle Pfade sind relativ zur unten angegebenen Basis-URL.
Die komplette Testumgebung (Sandbox) finden Sie auf test.peppol.verteco.digital. Sie verhält sich genauso wie die Produktion und bietet zusätzlich Testwerkzeuge (FS-Webhook, Verifizierungsmerkmal (Verifikačný údaj), Löschen einer Firma) und eine simulierte Anbieterauswahl anstelle des Portals der Finanzverwaltung der Slowakischen Republik (Finančná správa, FS).
- Base URL
https://peppol.verteco.digital/api/v1- Version
- v1 (im Pfad). Rückwärtsinkompatible Änderungen erscheinen unter einer neuen Version.
- Protokoll
- nur HTTPS · TLS 1.2+ · TLS A+
- Format
- application/json (UTF-8)
- Auth
- Cookie-Session (Portal) oder Bearer-Token (Server-to-Server)
- Zeitangaben
- ISO-8601 (UTC), z. B. 2026-06-03T09:40:27Z
Zertifizierter AP
Ein echter Peppol Access Point (Seat ID PSK001128), kein Reseller. Wir haben die OpenPeppol-Conformance bestanden (19/19), im Produktivbetrieb.
Valide Belege
Serverseitige Validierung nach EN 16931 + Peppol BIS 3.0 Schematron bei jedem empfangenen UND gesendeten Beleg. Sie können einen Beleg auch vorab prüfen: der öffentliche Validator läuft unter /validator (und als API unter POST /api/v1/public/peppol-validate); Fehler geben wir mit der konkreten Regel zurück (z. B. BR-CO-15). Validierte Muster für slowakische Fälle (Nichtzahler, Fremdwährung, Reverse Charge, Gutschrift, Anzahlungen, eingebettetes PDF) finden Sie unter /de/vzory.
Multi-tenant
Ein Konto und ein Token für N Firmen, ideal für SaaS, ERP und Buchhalter.
SK TDD automatisch
Die Steuermeldung (corner-5 / TDD) an die Finanzverwaltung erzeugen und senden wir für Sie.
openapi-generator einen typisierten Client in einer beliebigen Sprache (TS, Java, PHP, Python…). Sie deckt sowohl die Portal-API als auch SAPI-SK ab.Schnellstart
Welche Schnittstelle passt zu Ihnen
SAPI-SK 1.0 (/sapi)
Buchhaltungs- oder Rechnungssoftware, ERP, Plattformen für mehrere Firmen: die nationale Schnittstelle für Versand, Empfang, Status, Empfangsbestätigungen und FS-Meldungen. Empfohlen für jede Integration, die Belege sendet oder liest.
OAuth2 Client Credentials: client_id = UUID des API-Schlüssels, client_secret = der vpt_-Schlüssel, 15-Minuten-Access-Token.
Portal API (/api/v1)
Firmen, Webhooks, Benachrichtigungen, Exporte und Downloads; Partnerkonsole (/resellers/me). Ergänzt SAPI, ersetzt es nicht.
Authorization: Bearer vpt_… (API-Schlüssel des Kontos).
MCP-Server (/api/mcp)
Ein KI-Assistent (Claude Code, Cursor, Claude Desktop) soll Belege lesen, Empfänger prüfen und nach ausdrücklicher Bestätigung senden.
Bearer vpt_… über den MCP-Client.
E-Mail an das Firmenpostfach
Ohne Programmierung: die XML-Rechnung als Anhang an die geheime Adresse der Firma; wird validiert und wie aus dem Portal gesendet.
Absenderadresse auf der Freigabeliste + SPF/DKIM.
Konto und API-Token legen Sie im Portal an (über den Browser). Die Integration läuft danach ausschließlich über den API-Token. Registrierung, Anmeldung und Passwörter muss Ihre App nicht behandeln.
- 1
Legen Sie ein Konto im Portal an
Registrieren Sie sich per E-Mail und bestätigen Sie es über den Link in der E-Mail. - 2
Generieren Sie einen API-Token
Im Portal API tokeny → Vytvoriť (API-Tokens → Erstellen). Der Tokenvpt_…wird nur einmal angezeigt. Bewahren Sie ihn sicher auf. - 3
Führen Sie den ersten Aufruf aus
Verwenden Sie den Token im HeaderAuthorization:javascriptconst res = await fetch('https://peppol.verteco.digital/api/v1/companies', { headers: { Authorization: 'Bearer vpt_8f2a…' }, }); const companies = await res.json(); - 4
Anbieterauswahl im Portal der Finanzverwaltung
In der Produktion ist die Auswahl von Verteco im FS-Portal (vpds.financnasprava.sk) auch bei reinem Versand nötig: sie schaltet das Senden frei (Verifizierungsmerkmal) und aktiviert die Firma. Der Empfang kann beim Anbieter Ihres Buchhaltungsprogramms bleiben: eine Firma hat im Netz genau einen Empfänger, aber beliebig viele Sender.
Schnellstart mit curl (zuerst in der Testumgebung)
Sechs Aufrufe vom Konto bis zur ersten zugestellten Rechnung, alle gegen test.peppol.verteco.digital, wo eine Firma sofort aktiv ist und Belege ins Peppol-Testnetz gehen. Erwartete Antworten sind gekürzt.
export BASE=https://test.peppol.verteco.digital # production: https://peppol.verteco.digital
export KEY=vpt_… # step 1- 1
Konto und API-Schlüssel
Registrieren Sie sich auf test.peppol.verteco.digital/register (in der Testumgebung ohne Bestätigungs-E-Mail) und erstellen Sie auf der Seite API-Schlüssel einen Schlüssel. Er wird einmal angezeigt; unten $KEY.
- 2
Schlüssel prüfen
shellcurl -s $BASE/api/v1/auth/me -H "Authorization: Bearer $KEY"json{ "id": "7f1d…", "email": "dev@firma.sk", "emailVerified": true, "persona": "developer" } - 3
Firma anlegen
shellcurl -s -X POST $BASE/api/v1/companies -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"ico":"12345678","dic":"SK2120000001","legalName":"Test s. r. o.","street":"Hlavná 1","city":"Žilina","postalCode":"01001"}'json{ "id": "5c0e…", "legalName": "Test s. r. o.", "dic": "SK2120000001", "status": "active", "peppolParticipantId": "0245:2120000001", "verified": true } - 4
SAPI-Access-Token
shellcurl -s -X POST $BASE/sapi/auth/token -H "Content-Type: application/json" -d '{"grant_type":"client_credentials","client_id":"<Schlüssel-UUID von der Seite API-Schlüssel>","client_secret":"'$KEY'"}'json{ "access_token": "eyJhbGciOiJIUzI1NiJ9…", "token_type": "Bearer", "expires_in": 900, "refresh_token": "eyJhbGciOiJIUzI1NiJ9…" } - 5
Ohne Versand validieren
shellcurl -s -X POST $BASE/sapi/document/validate -H "Authorization: Bearer $ACCESS" -H "Content-Type: application/json" -d '{"payload":"<Invoice …>","payloadFormat":"XML"}'json{ "valid": true, "errors": [], "warnings": [] } - 6
Senden und Status verfolgen
shellcurl -s -X POST $BASE/sapi/document/send -H "Authorization: Bearer $ACCESS" -H "X-Peppol-Participant-Id: 0245:2120000001" -H "Idempotency-Key: FA-2026-0001" -H "Content-Type: application/json" -d @send.json, danach curl -s "$BASE/sapi/document/sent?since=2026-10-01T00:00:00Z" -H "Authorization: Bearer $ACCESS" -H "X-Peppol-Participant-Id: 0245:2120000001"jsonHTTP/2 202 { "providerDocumentId": "6a3f…", "status": "ACCEPTED", "peppolMessageId": "f1c7…", "receivedAt": "2026-10-03T12:00:01Z" } { "documents": [ { "documentId": "6a3f…", "status": "delivered", "sentAt": "2026-10-03T12:00:01Z", "deliveredAt": "2026-10-03T12:00:14Z", "hasMls": true, "fsReport": { "state": "reported" } } ] }
Testumgebung (Sandbox)
Neben der SAPI-Mock-Sandbox (unten) betreiben wir auch eine vollwertige Testumgebung, eine vollständige Kopie dieses Portals mit getrennten Daten, in der Sie den gesamten Ablauf (Registrierung → Firma → Senden → Empfangen → Benachrichtigungen) end-to-end ausprobieren können, ohne jegliche Auswirkung auf den Produktivbetrieb.
- Registrierung
- ohne Bestätigungs-E-Mail; das Konto ist sofort nutzbar
- Genehmigung der Firma
- automatisch, direkt in der Oberfläche oder über die API; ohne Auswahl des Anbieters im Portal der Finanzverwaltung der Slowakischen Republik (Finančná správa, FS) und ohne Anmeldung im FS-Portal; unmittelbar nach dem Anlegen einer Firma mit USt-IdNr. (IČ DPH) können Sie sowohl senden als auch empfangen
- Registrierung im Netzwerk
- automatisch in das Peppol-Testnetzwerk. Beachten Sie die zwei Ebenen des Identifikators: API und Portal verwenden dasselbe Format wie die Produktion (
peppolParticipantId = 0245:<DIČ-Ziffern>, DIČ = slowakische Steuernummer; Ihr Integrationscode ändert sich nicht); im Test-SMP/SML wird die Firma technisch als9950:SK<DIČ>eingetragen, weil das Schema 0245 einen Verifizierungscode der Finanzverwaltung verlangt, der im Test nicht existiert. In der Produktion wird0245:<DIČ-Ziffern>erst nach der Auswahl des Anbieters im FS-Portal (Anmeldung per eID oder mit den Zugangsdaten) in das produktive Netzwerk registriert - Validierung
- real: Regeln nach EN 16931 + Peppol BIS 3.0, dieselben wie im Produktivbetrieb
- Zustellung
- real über das Peppol-Testnetzwerk (AS4, Testzertifikat, Test-SML/SMP): ein im Testnetzwerk registrierter Empfänger erhält die Rechnung als empfangene Rechnung (inklusive E-Mail, PDF und Webhook); in das produktive Netzwerk geht nichts hinaus
- Zustellnachweis (MLS)
- echter MLS-Zustellnachweis aus dem Testnetzwerk
- E-Mails
- werden real versendet (an die Adressen, die Sie angeben), mit dem Präfix
[TEST] - Fehlersimulation
- der Header
X-Sandbox-Simulate: 503(oder502,500,429) auf einem beliebigen/sapi/document/*-Aufruf mit gültigem Token liefert den passenden Fehler; nichts wird verarbeitet oder gespeichert. Bei500(SAPI-PROC-500) und429(SAPI-SYS-003 mitRetry-After) erhalten Sie den SAPI-Fehlerumschlag;503und502kommen über den Netzwerkrand (DigitalOcean, Cloudflare) alsHTTP 504mit HTML-Body ohne Umschlag an, genau so sieht ein echter Ausfall von außen aus, sodass Sie auch die Verarbeitung einer Nicht-JSON-Antwort testen. Validierungsfehler erzeugen Sie mit ungültigem XML, 429 auch durch mehr als 300 Aufrufe pro Minute. Die Produktion ignoriert den Header - Preis
- kostenlos, ohne Limits zum Ausprobieren
Dort funktioniert alles wie hier: Portal, REST API, SAPI-SK 1.0, E-Shop-Plugins und Webhooks. Es genügt, in Ihrer Integration die Domain durch test.peppol.verteco.digital zu ersetzen und die in der Testumgebung erstellten Token zu verwenden. Ideal für die Entwicklung der Integration, CI-Tests und die Schulung von Buchhaltern vor dem Produktivstart. Testbelege gehören nur dorthin: In der Produktion wird jeder inländische Beleg zwischen Umsatzsteuerzahlern an die Finanzverwaltung gemeldet, und die Meldung lässt sich nicht zurückziehen. Im Produktivportal testen Sie nur mit der Schaltfläche „Poslať skúšobnú faktúru“ (Testrechnung senden, 0,00 €); ab dem 1. 1. 2027 lehnt die Produktion Nummern TEST-/VITAJTE-ab (test_document_in_production).
Hinweis: Der Edge-Schutz der Testdomain blockiert die generischen Header User-Agent: Python-urllib und User-Agent: Java/1.8.x (der Standard-User-Agent von HttpsURLConnection in Java 8) mit HTTP 403 "error code: 1010" noch vor unserer API; die Produktivdomain peppol.verteco.digital lässt sie durch. Setzen Sie einen eigenen User-Agent: in Java entweder per JVM-Parameter -Dhttp.agent=meine-app/1.0(ohne Codeänderung; Java hängt "Java/1.8" an, das resultierende "meine-app/1.0 Java/1.8.0_xxx" wird durchgelassen, blockiert wird nur ein Header, der direkt mit "Java/1.8" beginnt) oder auf der Verbindung mit conn.setRequestProperty("User-Agent", "meine-app/1.0"). Gängige Clients (requests, httpx, Java 11+, Apache HttpClient, okhttp, axios, Go, PHP, curl) funktionieren unverändert.
Warum Firmen automatisch genehmigt werden
Die Finanzverwaltung hat keine Testumgebung des VPDS-Portals: Die Auswahl des Anbieters auf vpds.financnasprava.sk läuft nur in der Produktion und wird durch Anmeldung im FS-Portal (eID oder FS-Zugangsdaten) verifiziert, sodass Sie im Produktivbetrieb keine beliebige fremde Firma „auswählen" können. Damit Sie Ihre Integration trotzdem testen können, simulieren wir diesen Schritt in der Testumgebung: Jede Firma, die Sie anlegen, wird automatisch genehmigt (ohne Auswahl bei der FS), sodass Sie Absender und Empfänger anlegen und den gesamten Ablauf durchlaufen können.
Zum Testen der FS-Webhooks (Auswahl des Anbieters) haben wir ein eigenes Gegenstück zum Werkzeug der Finanzverwaltung: test.peppol.verteco.digital/sandbox-nastroje. Dort erzeugen Sie ein gültiges Verifizierungs-Token (Verifizierungsmerkmal, Verifikačný údaj) im Stil der FS und senden einen vollständigen Webhook an Ihren Endpoint, genau so, wie es das FS-Portal bei einer realen Auswahl tut. Zu Testzwecken angelegte Firmen können Sie wiederum deregistrieren (aus dem Portal und aus dem Test-SMP), gerade weil es auf Seiten der Finanzverwaltung keinen Testmodus gibt.
Authentifizierung
Die Integration authentifiziert sich mit einem API-Token im Header Authorization: Bearer vpt_…. Den Token erstellen Sie im Portal (API-Tokens); er hat das Format vpt_ + 40 Hex-Zeichen, wir speichern nur seinen SHA-256-Hash und er hat dieselben Zugriffsrechte wie Ihr Konto. Testen Sie ihn über /auth/me:
curl https://peppol.verteco.digital/api/v1/auth/me -H 'Authorization: Bearer vpt_8f2a…'
# 200 → { "id": "…", "email": "vy(at)firma.sk" } (Token funktioniert)Bei fehlendem oder ungültigem Token gibt die API zurück:
// 401 Unauthorized
{ "error": "unauthorized", "message": "Authentication required" }portal_session, JWT, 7 Tage); bei einer Server-to-Server-Integration benötigen Sie es nicht. Öffentlich ohne Auth sind /ping, /openapi.json und die Endpoints unter /public/* (Prüfung peppol-check, Validator peppol-validate, Details dazu im Abschnitt Öffentliche Werkzeuge, sowie der Dienststatus status); alles andere erfordert eine Session oder einen Bearer-Token.Konventionen & Formate
| Typ | Format | Beispiel |
|---|---|---|
id | UUID (String) | 08dd6c1e-… |
Zeitstempel | ISO-8601 Instant (UTC) | 2026-06-03T09:40:27Z |
issueDate | Datum (YYYY-MM-DD) | 2026-06-03 |
totalAmount | Dezimalzahl | 120.00 |
fehlende Werte | null (Feld ist vorhanden, wird nicht weggelassen) | "dic": null |
Paginierung & Idempotenz
/companies und /companies/{id}/documents unterstützen optional ?page&limit (die Response bleibt ein JSON-Array; die Gesamtzahl finden Sie in den Headern X-Total-Count / X-Total-Pages). Ohne Parameter geben sie das gesamte Array zurück, Belege nach createdAt absteigend sortiert; /tokens gibt immer das gesamte Array zurück. Den Header Idempotency-Key unterstützt die nationale Schnittstelle SAPI-SK auf POST /sapi/document/send; für den programmatischen Versand verwenden Sie genau diese.Versionierung und Abwärtskompatibilität
- Der Vertrag wächst nur: neue Felder (bei null weggelassen), neue optionale Parameter, neue Endpunkte und Ereignisse. Bestehende Feldnamen, Enum-Werte und Statuscodes ändern sich nicht.
- Ein neuer Enum-Wert oder ein neues Webhook-Ereignis kann jederzeit erscheinen; ignorieren Sie Unbekanntes und beantworten Sie ein unbekanntes Ereignis mit 2xx.
- Zeitstempel sind ISO 8601 UTC mit variabler Anzahl Nachkommastellen; parsen, nie als Text vergleichen. Beträge kommen als Zeichenketten mit zwei Dezimalstellen.
- Sollte eine Änderung je nicht additiv sein, kündigen wir sie im Changelog (E-Mail-Abo verfügbar) mindestens 90 Tage vorher an und behalten die alte Form während einer Übergangszeit.
- Sicherheitsmodell des API-Schlüssels (seit 3. Oktober 2026): ein Schlüssel liest und sendet Belege und verwaltet Firmen, Benachrichtigungen und Webhooks. Konto- und Schlüsselverwaltung (Schlüssel erstellen, einschränken oder widerrufen, MFA, Passwort, Sitzungen, Einladungen, Firmenübertragung, Vertragsunterschriften) erledigt nur eine angemeldete Person; ein Schlüssel erhält dort 403 token_not_allowed. GET /api/v1/tokens bleibt für Schlüssel offen.
- Die Vertragsversion steht in info.version von openapi.json, jede Änderung hat eine Changelog-Zeile mit Tag API oder Webhooks.
Fehler
statusReason-Codes von GET /sapi/document/sent), steht als JSON unter /docs/peppol-errors.json bereit (sk, en, de, hu). Geeignet für eine Tabelle häufiger Fehler in der Buchhaltungssoftware: die Regel-ID irgendwo im Detail suchen, unbekannte Regeln samt ID anzeigen. Seit dem 7. 10. 2026 trägt jede JSON-Antwort Content-Type: application/json;charset=UTF-8.Fehler haben eine einheitliche Form mit einem maschinenlesbaren error-Code. Validierungsfehler ergänzen eine Map fields (erster Fehler pro Feld).
// Business-Fehler
{ "error": "invalid_credentials", "message": "Invalid email or password" }
// Validierungsfehler (400); die Texte in "fields" liefert die API auf Slowakisch
{ "error": "validation_failed", "message": "Some fields are invalid",
"fields": { "ico": "IČO musí byť 8 číslic" } }HTTP-Status
- 200 / 201 / 204
- Erfolg (OK / erstellt / kein Inhalt)
- 400
- ungültige Eingabe (siehe error / fields)
- 401
- fehlende oder ungültige Authentifizierung
- 403
- unzureichende Berechtigung (Rolle)
- 404
- Ressource existiert nicht oder Sie haben keinen Zugriff darauf
- 405
- HTTP-Methode für diesen Pfad nicht unterstützt
- 409
- Konflikt (Handelsregisternummer IČO / E-Mail existiert bereits)
- 415
- nicht unterstützter Content-Type (XML-Endpoints erwarten application/xml)
- 429
- Rate-Limit überschritten (Header RateLimit-* und Retry-After, JSON-Body rate_limited)
error. Eine Antwort ohne JSON-Body (HTML oder Text wie error code: 1010 mit Status 403, oder 502/504 während eines Deployments) kam nicht von der API, sondern von der davor liegenden Infrastruktur (Edge-Schutz, Gateway). Typische Ursache von 403/1010 ist ein generischer Bibliotheks-User-Agent (Python-urllib, Java/1.8.x auf der Testdomain); die Lösung steht im Abschnitt Testumgebung.Häufigste Fehlercodes
| Code | HTTP | Wann |
|---|---|---|
validation_failed | 400 | Body hat die Validierung nicht bestanden (siehe fields) |
unauthorized | 401 | API-Token fehlt oder ist ungültig |
forbidden | 403 | Aktion erfordert die Rolle owner/admin |
company_not_found | 404 | Firma existiert nicht oder Sie sind nicht Mitglied |
ico_taken | 409 | eine Firma mit diesem IČO existiert bereits |
ico_immutable | 400 | IČO kann nicht geändert werden |
company_dic_missing | 400 | Verifizierung des Versands ohne DIČ (slowakische Steuernummer) der Firma |
token_invalid | 400 | Verifizierungsmerkmal (Verifikačný údaj, Signatur) stimmt nicht |
document_not_found | 404 | Beleg existiert nicht |
token_not_found | 404 | API-Token existiert nicht / gehört nicht Ihnen |
rate_limited | 429 | zu viele Requests |
Ausfall des Access Points und Wiederholung
- Antwortet die API mit
502,503oder504oder gar nicht, haben wir den Beleg nicht übernommen: wiederholen Sie den Aufruf später mit demselbenIdempotency-Key, nichts wird doppelt gesendet. - Ein von der API angenommener Beleg (
202ACCEPTED, auch mitretrying: true) geht nach der Wiederherstellung von selbst hinaus: der Access Point wiederholt die Zustellung, den Stand sehen Sie überGET /sapi/document/sentoder per Webhook; gibt er die Zustellung am Ende auf, endet der Beleg als fehlgeschlagen und derselbe Key sendet ihn erneut. - Der Empfang auf Netzebene hängt nicht vom Portal ab: eine Zustellung, die während eines Portalausfalls nicht durchkam, wiederholt der sendende Access Point nach den Peppol-Regeln, und der Beleg erscheint nach der Wiederherstellung im Portal. Meldungen an die Finanzverwaltung, die wegen des Ausfalls nicht hinausgingen, holt ein automatischer Wiederherstellungslauf nach (ein Übertragungsfehler wird wiederholt, eine inhaltliche Ablehnung nicht).
- Status und Verfügbarkeitshistorie finden Sie auf /status; in der Testumgebung simulieren Sie einen Ausfall mit dem Header
X-Sandbox-Simulate(Abschnitt Testumgebung).
SAPI-SK-Codes (Feld error.code)
| Code | Bedeutung |
|---|---|
SAPI-AUTH-001 | ungültige client_id/client_secret oder gesperrtes Konto (401) |
SAPI-AUTH-002 | fehlender oder fehlerhafter Header Authorization: Bearer (401) |
SAPI-AUTH-003 | Schlüssel nicht für den Teilnehmer berechtigt, Versand nicht freigeschaltet oder pausiert (403) |
SAPI-AUTH-004 | IP-Adresse nicht auf der Freigabeliste des Schlüssels (403) |
SAPI-VAL-001 | ungültiger Request-Body (400) |
SAPI-VAL-002 | X-Peppol-Participant-Id fehlt (400) |
SAPI-PROC-001 | vorübergehend: ein Versand mit diesem Schlüssel läuft, gleich erneut versuchen (502, retryable) |
SAPI-PROC-002 | Beleg vor dem Versand abgelehnt (422 mit Prefer: handling=strict) |
SAPI-PROC-003 | ohne Idempotency-Key: unter dieser Nummer wurde bereits ein anderer Beleg übertragen (409, details: documentId, status) |
SAPI-RES-001 | Beleg existiert nicht oder gehört einem anderen Teilnehmer (404) |
SAPI-RES-002 | Beleginhalt nicht mehr gespeichert (Aufbewahrung der Firma) oder nie archiviert (404; Code bleibt aus Kompatibilitätsgründen) |
SAPI-RES-003 / 004 | Anhang oder MLS-Empfangsbestätigung existiert noch nicht (404) |
SAPI-SYS-001 / 002 | vorübergehender Infrastruktur- oder Validatorfehler (503/502, retryable) |
SAPI-SYS-003 | Rate-Limit überschritten (429, Retry-After) |
SAPI-PROC-500 | unerwarteter Fehler, correlation_id an den Support senden (500) |
Vollständiger Fehlerkatalog der Portal-API (326)
Jeder Code, den das Backend im Feld error zurückgibt, mit dem Text, den das Portal anzeigt. Aus demselben Wörterbuch wie die Oberfläche erzeugt, kann also nicht veralten.
Vollständiger Fehlerkatalog der Portal-API
account_exists | Für diese E-Mail existiert bereits ein Konto. Melden Sie sich an und nehmen Sie die Einladung im Portal an. |
account_inactive | Ihr Konto ist nicht aktiv. Bitte kontaktieren Sie uns. |
account_under_review | Ihr Konto wird gerade geprüft. Rufen Sie uns an oder schreiben Sie an [email protected]. |
acknowledge_required | Bestätigen Sie, dass Sie die Risiken des Downloads ohne Anmeldung verstehen. |
acknowledgement_required | Bestätigen Sie, dass Sie die Folgen der Vertragskündigung verstehen. |
address_book_full | Das Adressbuch ist voll. Entfernen Sie nicht genutzte Kunden und versuchen Sie es erneut. |
admin_email_unverified | Der Zugang zur Administration erfordert eine bestätigte E-Mail-Adresse. Klicken Sie auf den Link in der Nachricht, die wir Ihnen bei der Registrierung geschickt haben. |
admin_mfa_required | Der Zugang zur Administration erfordert die Zwei-Faktor-Authentifizierung. Aktivieren Sie sie in den Einstellungen. |
ai_budget | Das Budget für KI-Entwürfe ist aufgebraucht oder das Tageslimit ist erreicht. Schreiben Sie die Antwort manuell. |
ai_failed | Der Antwortentwurf konnte nicht erstellt werden. Bitte versuchen Sie es erneut. |
ai_unavailable | KI-Antwortentwürfe sind derzeit nicht verfügbar. |
already_completed | Die Übertragung der Firma wurde bereits abgeschlossen. |
already_member | Dieser Benutzer hat bereits Zugriff (Mitglied der Firma oder Ihres Teams). |
attachment_external | Dieser Anhang liegt beim Absender als Link vor, nicht in der Rechnung selbst. |
attachment_invalid | Eine Anlage konnte nicht gesendet werden (Typ nicht erlaubt, beschädigter Inhalt oder Größe überschritten). Prüfen Sie die Anlagen und versuchen Sie es erneut. |
attachment_not_found | Der Anhang wurde nicht gefunden. |
attachment_not_readable | Der Anhang konnte nicht gelesen werden. |
billing_unconfigured | Abonnementzahlungen sind noch nicht verfügbar. |
blocked | An diese Adresse kann der Test-Webhook nicht gesendet werden (lokale oder interne Adressen sind nicht erlaubt). |
body_required | Bitte geben Sie den Text Ihrer Nachricht ein. |
body_too_long | Die Nachricht darf höchstens 4000 Zeichen lang sein. |
cannot_change_self | Die eigene Rolle können Sie nicht ändern. Bitten Sie den anderen Verwalter der Firma. |
cannot_invite_self | Sie können sich nicht selbst einladen oder Ihre eigene Einladung annehmen. |
cannot_release_to_self | Die Firma ist bereits diesem Konto zugeordnet. |
cannot_remove_owner | Der Inhaber der Firma kann nicht entfernt werden. Der Inhaber wechselt nur durch eine Übertragung der Firma. |
cannot_restrict_admin | Ein Administratorkonto des Portals kann so nicht eingeschränkt werden. |
cannot_transfer_self | Die Firma gehört bereits zu dieser E-Mail-Adresse. |
captcha_failed | Die Bot-Prüfung ist fehlgeschlagen. Bitte versuchen Sie es erneut. |
captcha_required | Die Bot-Prüfung ist fehlgeschlagen; laden Sie die Seite neu und versuchen Sie es erneut. |
channel_unknown | Ein alter Eintrag ohne bekannten Kanal kann nicht erneut abgespielt werden. Senden Sie ihn manuell an den richtigen Endpunkt. |
chat_not_found | Die Konversation wurde nicht gefunden oder ist leer. |
client_not_found | Die Firma gehört nicht zu diesem Partnerkonto. |
client_not_removable | Die Firma kann nicht entfernt werden: Sie ist von der Finanzverwaltung verifiziert, aktiv, im SMP registriert oder hat Belege. Verwenden Sie stattdessen die Freigabe (release). |
company_active | Eine aktive Firma kann nicht gelöscht werden. |
company_address_required | Ergänzen Sie vor dem Senden einer Rechnung den Firmensitz (Straße, Ort, PLZ) in den Firmendetails. |
company_already_active | Die Firma ist bereits aktiv; Aktivierungshinweise sind nicht nötig. |
company_dic_missing | Ergänzen Sie zuerst die DIČ (Steuer-ID) der Firma und versuchen Sie die Verifizierung erneut. |
company_incomplete | Ergänzen Sie vor dem Signieren die Firmendaten: Firmenname, IČO, Peppol-Identifikator und vollständiger Sitz. |
company_limit | Sie haben die maximale Anzahl von Firmen pro Konto erreicht. Kontaktieren Sie den Support, wir erhöhen das Limit. |
company_name_mismatch | Der Firmenname stimmt nicht mit dem amtlichen Register (ŽR/OR SR) für diese IČO überein. |
company_not_active | Ein Migrationscode kann nur für eine aktive, im Peppol-Netzwerk registrierte Firma ausgestellt werden. |
company_not_found | Die Firma wurde nicht gefunden. |
company_not_registered | Die Firma ist noch nicht aktiviert: Schließen Sie die Verteco-Auswahl im Portal der Finanzverwaltung ab, danach können Sie versenden. |
company_not_verified | Eine Migration ist erst nach der Auswahl von Verteco im Portal der Finanzverwaltung möglich (die Firma muss aktiv und verifiziert sein). |
company_verified_locked | Der Name einer verifizierten Firma kann nur auf den amtlichen Registereintrag geändert werden. Ergänzen Sie zuerst die IČO oder schreiben Sie uns. |
confirm_name_mismatch | Der eingegebene Name stimmt nicht mit dem Namen des eingetragenen Vermittlers überein. |
confirmation_required | Die Unterschrift erfordert die Bestätigung Ihrer Berechtigung und Ihres Einverständnisses mit dem Wortlaut. |
conflict | Dieser Datensatz existiert bereits. |
content_unavailable | Der Inhalt dieses Belegs ist nicht mehr gespeichert oder kann nicht als Rechnung gelesen werden. |
contract_pending | Das Vertragsverhältnis entsteht mit dem ersten Eintritt in das Portal (Art. 4 AGB); für diese Firma wurde noch keiner erfasst, die Vertragsausfertigung ist daher noch nicht möglich. |
country_invalid | Das Land muss ein zweibuchstabiger ISO-Code sein (SK, CZ, AT, DE…), kein Name. |
country_outside_eu | Der Online-Antrag steht Unternehmen mit Sitz in einem EU-Mitgliedstaat offen. Unternehmen außerhalb der EU schreiben an [email protected]. |
current_ip_missing | Die Liste muss auch Ihre aktuelle IP-Adresse enthalten, sonst würden Sie sich nach dem Abmelden aussperren. |
daily_limit | Sie haben das tägliche Nachrichtenlimit erreicht. Versuchen Sie es morgen erneut oder schreiben Sie an [email protected]. |
delivery_failed | Der Test-Webhook konnte nicht zugestellt werden; Ihr Endpunkt hat nicht geantwortet. |
delivery_not_found | Der Eintrag zur Webhook-Zustellung wurde nicht gefunden. |
deregister_cooldown | Pro IP-Adresse kann nur eine Firma alle 60 Sekunden entfernt werden. Versuchen Sie es gleich erneut. |
dic_immutable | Der Peppol-Identifikator kann nicht geändert werden: Er ist die Identität der Firma im Peppol-Netzwerk. |
dic_required | Geben Sie die DIČ (Steuer-ID) der Firma ein (SK + 10 Ziffern). |
dic_taken | Eine Firma mit dieser DIČ existiert bereits im Portal. |
directory_unavailable | Das zentrale SMP antwortet nicht oder hat die Änderung abgelehnt. Bitte versuchen Sie es gleich noch einmal. |
document_no_xml | Das gespeicherte Original-XML existiert nicht mehr; der Bericht kann nicht neu erstellt werden. |
document_not_found | Der Beleg wurde nicht gefunden. |
document_too_large | Das Dokument ist zu groß (Limit 3 MB). |
domestic_subject | Ein slowakisches Unternehmen stellt den Antrag nach der Anmeldung unter /sprostredkovatel/ziadost. |
duplicate_invoice_number | Ein Beleg mit dieser Nummer wurde bereits gesendet. Ein neuer Beleg braucht eine neue Nummer; derselbe Beleg wird nie zweimal gesendet. |
email_change_cooldown | Wir haben die Bestätigungs-E-Mail bereits gesendet. Eine weitere können Sie in 10 Minuten anfordern. |
email_invalid | Geben Sie eine gültige E-Mail-Adresse ein. |
email_not_verified | Bestätigen Sie zuerst Ihre E-Mail. Den Link haben wir Ihnen gesendet. |
email_send_company_not_active | Der Versand per E-Mail lässt sich nur für ein aktives Unternehmen mit Peppol-Kennung einschalten. |
email_send_unavailable | Der Versand per E-Mail ist in dieser Umgebung nicht verfügbar. |
email_taken | Diese E-Mail-Adresse wird bereits von einem anderen Konto verwendet. |
email_unchanged | Das ist Ihre aktuelle E-Mail-Adresse. |
empty_document | Fügen Sie das XML der Rechnung ein. |
empty_idea | Bitte schreiben Sie, was wir verbessern sollten. |
empty_message | Die Nachricht ist leer. |
empty_reply | Die Antwort ist leer. |
entry_not_found | Der Kunde im Adressbuch wurde nicht gefunden. |
export_format_unknown | Unbekanntes Exportformat. |
forbidden | Dafür fehlt Ihnen die Berechtigung. |
forwarder_unreachable | Der Dienst zur Belegverarbeitung antwortet nicht. Versuchen Sie es gleich erneut. |
fs_change_already_sent | Der Antrag ist bereits bei der Finanzverwaltung und kann nicht storniert werden. Stellen Sie bei Bedarf einen neuen. |
fs_change_confirm_required | Bestätigen Sie, dass Sie alle Änderungen auf einmal beantragen. |
fs_change_cooldown | Der nächste Änderungsantrag ist erst 48 Stunden nach dem letzten möglich. |
fs_change_field_readonly | Firmen-ID und Steuernummer sind nicht änderbar; eine neue Identität ist ein neuer Eintrag. |
fs_change_no_changes | Sie haben keine Änderung gegenüber den Daten bei der Finanzverwaltung eingegeben. |
fs_change_not_found | Der Änderungsantrag wurde nicht gefunden. |
fs_change_not_open | Der Antrag ist bereits abgeschlossen. |
fs_change_not_queued | Sofort senden geht nur bei einem wartenden Antrag. |
fs_change_pending | Ein Änderungsantrag wartet bereits oder liegt bei der Finanzverwaltung. Den nächsten stellen Sie nach dessen Abschluss. |
fs_secret_invalid | Der Schlüssel hat 32 Zeichen (Ziffern und die Buchstaben a bis f). Kopieren Sie den gesamten Inhalt der .txt-Datei aus dem Zip der Finanzverwaltung. |
fs_secret_mismatch | Der Schlüssel stimmt nicht mit der Signatur der Aufrufe überein, die die Finanzverwaltung bereits an Ihren Endpunkt gesendet hat. Prüfen Sie Zip und Schlüssel; verändert Ihr Proxy den Aufrufkörper, schreiben Sie uns. |
has_documents | Die Firma hat Belege im Archiv; das Löschen ist gesperrt (gesetzliche Archivierung). |
holding_unavailable | Das Freigeben des Kunden ist derzeit nicht möglich. Kontaktieren Sie den Support. |
ico_immutable | Die IČO kann nicht geändert werden. |
ico_required | Die IČO ist erforderlich (8 Ziffern). |
ico_taken | Eine Firma mit dieser IČO existiert bereits unter einem anderen Konto. Melden Sie sich damit an oder schreiben Sie uns. |
instructions_cooldown | Die Anleitung zu dieser Firma haben wir bereits gesendet. Erneut senden ist nach 24 Stunden möglich. |
integration_not_found | Unbekannte Integration. |
internal | Ein unerwarteter Fehler ist aufgetreten. Bitte versuchen Sie es erneut. |
internal_error | Ein unerwarteter Serverfehler ist aufgetreten. Bitte versuchen Sie es erneut; der Fehler wurde protokolliert. |
invalid_action | Unbekannte Aktion. |
invalid_after | Der Parameter after muss Datum und Uhrzeit im ISO-8601-Format sein (z. B. 2026-09-05T10:00:00Z). |
invalid_amount | Der Betrag muss eine Zahl sein. |
invalid_billing_model | Unbekanntes Abrechnungsmodell. Wählen Sie eines der angebotenen Modelle. |
invalid_country | Wählen Sie das Land des Firmensitzes. |
invalid_credentials | E-Mail oder Passwort ist falsch. |
invalid_current_password | Das aktuelle Passwort ist nicht korrekt. |
invalid_date | Das Datum muss im Format JJJJ-MM-TT angegeben werden. |
invalid_default_company | Die Standardfirma muss eine Ihrer Firmen sein. |
invalid_dic | Geben Sie eine gültige DIČ (10 Ziffern, optional mit Präfix SK) oder USt-IdNr. ein. |
invalid_direction | Die Belegrichtung muss gesendet oder empfangen sein. |
invalid_due_days | Das Zahlungsziel muss 0 bis 365 Tage betragen. |
invalid_email | Geben Sie eine gültige E-Mail-Adresse ein. |
invalid_feed_url | Die Feed-URL muss mit https:// beginnen. |
invalid_ico | Geben Sie eine gültige IČO (8 Ziffern) oder Handelsregisternummer ein. |
invalid_id | Geben Sie eine slowakische IČ DPH oder DIČ (z. B. SK2121358349) oder eine Peppol-ID (z. B. 0245:2121358349) ein. |
invalid_ids | Die Belegliste ist ungültig. |
invalid_invite | Die Einladung ist ungültig oder wurde bereits verwendet. |
invalid_ip_entry | Die Liste enthält einen ungültigen Eintrag. Erlaubt sind IP-Adressen (z. B. 185.76.8.211) und CIDR-Bereiche (z. B. 185.76.8.0/24). |
invalid_key | Der Vermittler-Schlüssel muss 3 bis 40 Zeichen haben: Kleinbuchstaben, Ziffern und Bindestriche. |
invalid_limit | Das Limit muss mindestens 1 sein oder leer (Standardwert). |
invalid_link | Der Anmeldelink ist ungültig oder abgelaufen. Fordern Sie einen neuen an. |
invalid_locale | Nicht unterstützte Sprache. |
invalid_month | Der Monat muss im Format JJJJ-MM angegeben werden. |
invalid_notification_email | Eine der Adressen ist keine gültige E-Mail: |
invalid_notify_event | Unbekanntes Benachrichtigungsereignis. |
invalid_notify_locale | Die E-Mail-Sprache muss Slowakisch, Englisch, Deutsch oder Ungarisch sein. |
invalid_notify_mode | Unbekannter Benachrichtigungsmodus. Wählen Sie: jedes Ereignis, tägliche Zusammenfassung, wöchentliche Zusammenfassung oder keine. |
invalid_password | Falsches Passwort. |
invalid_pattern | Das Nummernformat darf höchstens 64 Zeichen haben und muss die laufende Nummer {N}, {NNN} oder {NNNN} genau einmal enthalten. |
invalid_payload | Die Rechnung (XML) fehlt oder ist zu groß. |
invalid_persona | Unbekannte Kontorolle. |
invalid_phone | Geben Sie die Telefonnummer als +421 9xx xxx xxx ein (Ziffern, Leerzeichen, optional Bindestriche). |
invalid_prefs | Die Anzeigeeinstellungen enthalten einen ungültigen Wert und konnten nicht gespeichert werden. |
invalid_receiver | Der Empfänger muss einen Peppol-Identifikator im Format Schema:Wert haben (z. B. 0245:2121358349). |
invalid_request | Pflichtangaben fehlen (z. B. Firmenname, 10-stellige DIČ, gültige E-Mail oder Endpunkt-URL). |
invalid_role | Die Rolle muss Administrator, Mitglied oder Nur-Lesen sein. |
invalid_seq | Die nächste laufende Nummer muss mindestens 1 sein. |
invalid_session | Ungültige Konversation. Laden Sie die Seite neu und versuchen Sie es erneut. |
invalid_signature | Die Zahlungsbenachrichtigung konnte nicht verifiziert werden. |
invalid_signup | Die Registrierung ist nicht mehr gültig oder abgelaufen. Beginnen Sie die Registrierung erneut. |
invalid_sort | Unbekannte Sortierung. |
invalid_state | Unbekannter Status. |
invalid_status | Unbekannter Status. |
invalid_tag | Der Tag darf nicht leer sein. |
invalid_token | Der Link ist ungültig oder wurde bereits verwendet. |
invalid_vpds_url | Der Auswahllink muss mit https://vpds.financnasprava.sk/ beginnen. |
invalid_web | Die Website muss eine gültige Adresse sein (https://...). |
invalid_webhook_url | Die Webhook-URL muss eine gültige https://-Adresse sein (höchstens 512 Zeichen). |
invalid_window | Das Zeitfenster ist ungültig: Beginn vor Ende und höchstens 31 Tage. |
invalid_xml | Das XML des Belegs lässt sich nicht lesen (beschädigte Datei oder eine nicht erlaubte DOCTYPE-Deklaration). |
invite_email_mismatch | Diese Einladung gilt für eine andere E-Mail-Adresse. Melden Sie sich mit dem Konto an, an das sie gesendet wurde. |
invite_expired | Die Einladung ist abgelaufen. Bitten Sie um eine neue. |
ip_not_allowed | Die Anmeldung von dieser IP-Adresse ist für dieses Konto nicht erlaubt. |
lead_no_email | Der Lead hat keine E-Mail-Adresse und kann nicht kontaktiert werden. |
lead_not_contactable | Nur ein Lead im Status neu kann kontaktiert werden. |
lead_not_found | Der Lead wurde nicht gefunden. |
link_gone | Dieser Link ist nicht mehr gültig (abgelaufen, widerrufen oder der Beleginhalt ist nicht mehr gespeichert). |
lookup_unavailable | Das Register oder der Prüfdienst ist derzeit nicht erreichbar. Versuchen Sie es gleich erneut. |
malformed_request | Die Anfrage hat kein gültiges Format. Laden Sie die Seite neu und versuchen Sie es erneut. |
manager_required | Diese Änderung kann nur der Inhaber oder ein Administrator der Firma vornehmen. |
member_is_owner | Dieser Benutzer ist Inhaber der Firma. Der Inhaber wechselt nur durch eine Übertragung der Firma. |
member_not_found | Das Mitglied wurde nicht gefunden. |
members_full | Die Firma hat die maximale Anzahl von Mitgliedern erreicht. |
method_not_allowed | Dieser Vorgang wird für diese Adresse nicht unterstützt. |
mfa_already_enabled | Die Zwei-Faktor-Authentifizierung ist bereits aktiviert. |
mfa_code_invalid | Der Code stimmt nicht. Versuchen Sie den aktuellen Code aus Ihrer App oder einen Backup-Code. |
mfa_not_enabled | Backup-Codes gehören zur Zwei-Faktor-Authentifizierung. Aktivieren Sie sie zuerst. |
mfa_not_started | Starten Sie zuerst die Einrichtung der Zwei-Faktor-Authentifizierung. |
mfa_required | Geben Sie den Code aus Ihrer Authentifizierungs-App ein. |
migration_code_live | Der vorherige Migrationscode ist noch gültig. Widerrufen Sie ihn zuerst. |
migration_code_none | Es gibt keine aktive Anfrage für einen Migrationscode. |
migration_code_pending | Eine Anfrage für einen Migrationscode läuft bereits. |
migration_code_rejected | Das SMP hat den Migrationscode abgelehnt. Prüfen Sie ihn beim bisherigen Anbieter; Codes sind einmalig und zeitlich begrenzt. |
migration_code_required | Geben Sie den Migrationscode des bisherigen Anbieters ein. |
migration_rejected | Das zentrale SMP hat die Übernahmeanfrage abgelehnt. Versuchen Sie es erneut oder schreiben Sie uns. |
missing_fields | Name und E-Mail des Inhabers sind erforderlich. |
missing_parameter | In der Anfrage fehlt ein erforderlicher Parameter. |
mls_not_available | Für diesen Beleg liegt noch kein Zustellbeleg (MLS) vor. |
name_required | Geben Sie den Namen ein (Kundenname oder Firmenname). |
no_billing_account | Sie haben noch kein Abrechnungskonto. Richten Sie zuerst ein Abonnement ein. |
no_body | Der Eintrag hat keinen gespeicherten Anfragetext und kann nicht erneut abgespielt werden. |
no_content | Der Beleginhalt ist nicht mehr verfügbar; der Link kann nicht erstellt werden. |
no_dic | Die Firma hat keine DIČ (Steuer-ID). |
no_documents | Für den gewählten Zeitraum gibt es keine Belege (mit gespeichertem XML). |
no_evidence | Für diesen Beleg ist weder das Original-XML noch ein Zustellbeleg gespeichert. |
no_ids | Wählen Sie mindestens einen Beleg aus. |
no_owner | Die Firma hat keinen Inhaber. Verwenden Sie stattdessen die direkte Zuweisung. |
no_secret | Der Signaturschlüssel existiert noch nicht. Legen Sie zuerst die Benachrichtigungs-Webhook-URL fest. |
no_verification_token | Die Firma hat keinen gespeicherten Verifizierungstoken der Finanzverwaltung; die SMP-Registrierung erfordert ihn. |
not_a_reseller | Dieses Konto ist nicht Inhaber einer Vermittler-Registrierung. |
not_acceptable | Der Server antwortet nur im JSON-Format. |
not_available_for_white_label | Für Unternehmen unter einer Vermittlermarke nicht verfügbar. |
not_failed | Nur fehlgeschlagene Webhooks können wiederholt werden. |
not_found | Datensatz nicht gefunden. |
not_reseller | Dieses Konto ist nicht Inhaber einer Vermittler-Registrierung. |
not_sandbox_row | Diese Vermittler-Registrierung wird von einem Administrator verwaltet und kann nicht vom Konto aus deaktiviert werden. |
note_too_long | Die Notiz darf höchstens 200 Zeichen lang sein. |
notification_emails_too_long | Die Adressen sind zusammen zu lang (höchstens 256 Zeichen). |
owner_not_found | Für diese E-Mail existiert kein Inhaberkonto. Legen Sie es zuerst an. |
owner_of_companies | Um das Konto zu löschen, fordern Sie zuerst einen Migrationscode an oder melden Sie die Firma aus dem Peppol-Netzwerk ab. Danach können Sie das Konto endgültig löschen. |
owner_required | Diese Aktion kann nur der Inhaber des Firmenkontos ausführen. |
participant_not_registered | Die Firma hat noch keinen Eintrag im zentralen SMP unter Verteco; stellen Sie die Veröffentlichung nach der Registrierung ein. |
partner_managed | Das Vertragsverhältnis dieser Firma führt ihr Vermittler; die Vertragsbestätigung stellt er aus. |
party_missing_in_text | Der zu signierende Text enthält keine Identifikation der Firma. Laden Sie die Seite neu und versuchen Sie es erneut. |
password_already_set | Sie haben bereits ein Passwort. Verwenden Sie die Passwortänderung. |
password_not_set | Das Konto hat kein Passwort. Legen Sie eines in den Einstellungen fest und versuchen Sie es erneut. |
password_required | Legen Sie zuerst ein Passwort fest (Sicherheit); danach können Sie diese Änderung bestätigen. |
payment_mismatch | Die Zahlung konnte dem Antrag nicht zugeordnet werden. Bitte kontaktieren Sie uns. |
payment_unconfigured | Die Zahlung ist derzeit nicht verfügbar. Versuchen Sie es später oder kontaktieren Sie uns. |
pdf_unavailable | Die PDF-Erstellung ist vorübergehend nicht verfügbar. Versuchen Sie es gleich erneut oder nutzen Sie Drucken / PDF. |
profile_too_long | Eines der Profilfelder ist zu lang. Kürzen Sie den Text. |
public_link_exists | Der Beleg hat bereits einen aktiven Link. Wählen Sie Ersetzen, wenn Sie einen neuen möchten. |
public_links_disabled | Die Firma hat den Download von Rechnungen ohne Anmeldung nicht aktiviert. Der Inhaber kann ihn in den Firmendetails (Datenarchiv) einschalten. |
public_links_unavailable | Öffentliche Beleglinks sind derzeit deaktiviert. |
rate_limited | Zu viele Anfragen. Versuchen Sie es gleich noch einmal. |
read_only_member | Die Rolle Nur-Lesen kann weder Status noch Tags von Belegen ändern. |
received_only | Ein öffentlicher Link wird nur für empfangene Belege erstellt. |
receiving_toggle_cooldown | Der Empfang lässt sich höchstens dreimal pro Stunde umschalten. Die nächste Änderung ist möglich, sobald seit der ältesten der letzten drei Änderungen eine Stunde vergangen ist. |
registered_elsewhere | Der Teilnehmer ist weiterhin bei einem anderen Anbieter registriert; der Code hat die Übernahme nicht ausgelöst. |
renderer_unavailable | Die Vorschau kann gerade nicht erstellt werden (der Rendering-Dienst startet neu). Versuchen Sie es gleich noch einmal; das Senden der Rechnung ist nicht blockiert. |
reply_already_cancelled | Diese Antwort wurde inzwischen von einem Kollegen storniert. |
reply_already_sent | Diese Antwort wurde bereits gesendet; sie kann weder storniert noch erneut gesendet werden. |
reply_not_found | Die geplante Antwort wurde nicht gefunden. |
reply_to_invalid | Die Ergebnisadresse ist keine gültige E-Mail-Adresse. |
representative_incomplete | Geben Sie Name und Funktion der vertretungsberechtigten Person an oder lassen Sie beide Felder leer. |
request_rejected | Die Anfrage enthält ein unzulässiges Zeichen in einem Header oder in der URL. Falls Sie einen API-Schlüssel gesendet haben, verwenden Sie das vollständige client_secret, das beim Erstellen angezeigt wurde (die Liste zeigt nur den Anfang mit …), und gerade Anführungszeichen. |
reseller_not_found | Der Vermittler wurde nicht gefunden. |
reseller_owner | Ihr Konto besitzt einen Vermittler-Eintrag. Vereinbaren Sie dessen Übergabe mit dem Support; danach können Sie das Konto löschen. |
reseller_required | Dieser Teil ist nur für das Konto eines eingetragenen Vermittlers. |
sbd_not_available | Für diesen Beleg ist kein Transportumschlag (SBDH) gespeichert. Laden Sie stattdessen das Beleg-XML herunter. |
schedule_not_found | Dieser regelmäßige Export existiert nicht mehr. |
sender_email_invalid | Die Absenderadresse ist keine gültige E-Mail-Adresse. |
sender_email_system | Automatische Postfächer (noreply, postmaster, mailer-daemon…) können nicht hinzugefügt werden; verwenden Sie das Postfach einer Person oder des Rechnungssystems. |
sender_exists | Diese Adresse steht bereits auf der Freigabeliste. |
sender_limit | Es sind höchstens 20 freigegebene Absender möglich. |
sending_not_verified | Senden ist nicht erlaubt: Die Firma hat noch keine verifizierte Anbieterauswahl im Portal der Finanzverwaltung. |
sending_paused | Das Senden ist für diese Firma durch das verwaltende Konto pausiert. Der Rechnungsempfang läuft weiter. |
service_unavailable | Der Dienst ist vorübergehend nicht verfügbar. Bitte versuchen Sie es gleich erneut. |
session_full | Diese Konversation ist zu lang. Laden Sie die Seite neu und beginnen Sie eine neue. |
session_not_found | Das Gerät wurde nicht gefunden. |
shoptet_feed_blocked | Die Adresse zeigt auf ein privates Netz. Fügen Sie die öffentliche Adresse Ihres Shops ein. |
shoptet_feed_http | Shoptet hat die Adresse abgelehnt. Prüfen Sie den Hash in der Adresse und ob der Export nicht auf eine IP-Adresse beschränkt ist. |
shoptet_feed_invalid_xml | Die Antwort des Exports ist kein gültiges XML. Prüfen Sie die Adresse in Shoptet. |
shoptet_feed_not_configured | Die Shoptet-Verbindung ist noch nicht eingerichtet. |
shoptet_feed_not_orders_xml | Das ist kein Shoptet-Bestellexport: Die Adresse muss auf /export/orders.xml enden. |
shoptet_feed_not_system_xml | Fügen Sie die Adresse des Exports „System-Shoptet-XML“ ein (die Adresse enthält patternId=-11). Eigene Vorlagen, CSV und XLS werden nicht unterstützt. |
shoptet_feed_too_large | Die Antwort des Exports ist zu groß (über 10 MB). Wir fragen Bestellungen wochenweise ab, eine solche Antwort ist meist ein Produkt- und kein Bestellexport. Prüfen Sie den Exporttyp. |
shoptet_feed_unreachable | Der Shoptet-Export hat nicht geantwortet. Versuchen Sie es gleich noch einmal; Shoptet erlaubt nur einen Export gleichzeitig. |
sidlo_incomplete | Der Sitz muss Straße, PLZ und Ort enthalten, z. B. „Ulica 1, 010 01 Mesto“. |
smp_cancel_failed | Das Widerrufen des Codes im zentralen SMP ist fehlgeschlagen. Versuchen Sie es gleich erneut oder schreiben Sie an [email protected]. |
smp_deregister_failed | Die Abmeldung aus dem Peppol-Netzwerk ist fehlgeschlagen. Versuchen Sie es gleich erneut. |
smp_held_elsewhere | Die Registrierung dieser Firma liegt bei einem anderen Anbieter. Ein Migrationscode von uns ist nicht nötig. |
smp_not_test | Die Testumgebung ist nicht korrekt mit dem Test-SMP verbunden. Bitte schreiben Sie uns. |
smp_unavailable | Das zentrale SMP antwortet gerade nicht; versuchen Sie es gleich erneut. |
smtp_fromAddress_required | Geben Sie die Absenderadresse ein. |
smtp_fromAddress_too_long | Die Absenderadresse ist zu lang. |
smtp_from_forbidden | Die Absenderadresse darf nicht auf einer Verteco-Domain liegen. |
smtp_from_invalid | Die Absenderadresse ist keine gültige E-Mail. |
smtp_from_not_yours | Die Absenderadresse muss auf der Domain Ihrer Firma liegen (wie die E-Mail des Inhabers, eines Mitglieds oder die Benachrichtigungs-E-Mail). |
smtp_from_taken | Diese Absenderadresse wird bereits von einer anderen Firma verwendet. |
smtp_host_blocked | Der Server ist im DNS nicht zu finden oder nicht öffentlich erreichbar (interne Adressen sind nicht erlaubt). |
smtp_host_invalid | Geben Sie den Domainnamen des Servers ein (z. B. smtp.firma.de), keine IP-Adresse. |
smtp_host_required | Geben Sie die Adresse des SMTP-Servers ein. |
smtp_host_too_long | Die Adresse des SMTP-Servers ist zu lang. |
smtp_incomplete | Füllen Sie Server, Port, Benutzername, Passwort und Absenderadresse aus. |
smtp_password_invalid | Das Passwort darf keine Leerzeichen oder Zeilenumbrüche enthalten. |
smtp_password_required | Geben Sie das Passwort des SMTP-Kontos ein (bei Serverwechsel muss es erneut eingegeben werden). |
smtp_port_not_allowed | Erlaubte Ports sind 465, 587 und 2525. |
smtp_security_invalid | Die Verschlüsselung muss STARTTLS oder SSL sein. |
smtp_test_cooldown | Eine Test-E-Mail kann einmal pro Minute gesendet werden. Versuchen Sie es gleich erneut. |
smtp_test_failed | Die Test-E-Mail konnte nicht gesendet werden. Prüfen Sie die SMTP-Servereinstellungen. |
smtp_username_invalid | Der Benutzername darf keine Leerzeichen oder Zeilenumbrüche enthalten. |
smtp_username_required | Geben Sie den Benutzernamen des SMTP-Kontos ein. |
smtp_username_too_long | Der Benutzername ist zu lang. |
state_not_for_direction | Dieser Status ist für die Belegrichtung (empfangen oder gesendet) nicht möglich. |
stripe_error | Das Zahlungsportal konnte nicht geöffnet oder die Zahlung nicht überprüft werden. Bitte versuchen Sie es erneut. |
support_not_on_sandbox | Der Support läuft im Produktivportal peppol.verteco.digital, nicht in der Testumgebung. |
tag_too_long | Der Tag ist zu lang. |
target_blocked | Das Zielkonto ist gesperrt; die Übertragung ist nicht möglich. |
team_full | Sie haben die maximale Anzahl von Teammitgliedern erreicht. |
termination_confirmed | Eine bestätigte Kündigung kann nicht aus der App zurückgenommen werden. Schreiben Sie an [email protected]. |
termination_pending | Eine Kündigungsanfrage läuft bereits. Bestätigen Sie sie über den Link in der E-Mail oder brechen Sie sie ab. |
terms_not_accepted | Zum Erstellen eines Kontos müssen Sie die Geschäftsbedingungen akzeptieren. |
test_document_in_production | Testbelege (Nummer TEST-… oder VITAJTE-…) werden ab dem 1. Januar 2027 nicht mehr über das Produktivnetz gesendet. Nutzen Sie für Tests die Testumgebung test.peppol.verteco.digital. |
ticket_link_expired | Die Anfrage ist seit mehr als 90 Tagen geschlossen; der Link ist nicht mehr gültig. Schreiben Sie uns erneut an [email protected]. |
ticket_not_found | Die Anfrage wurde nicht gefunden oder der Link ist ungültig. |
token_companies_required | Wählen Sie mindestens ein Unternehmen, auf das der Schlüssel zugreifen darf. |
token_company_not_allowed | Dieser API-Schlüssel hat keinen Zugriff auf dieses Unternehmen (er gilt nur für ausgewählte Unternehmen). |
token_company_not_member | Ein Schlüssel kann nur Unternehmen umfassen, deren Mitglied Ihr Konto ist. |
token_expired | Der Link ist abgelaufen. Fordern Sie einen neuen an. |
token_invalid | Der Link oder Verifizierungstoken ist ungültig oder nicht mehr gültig. |
token_limit | Sie haben zu viele aktive API-Schlüssel (max. 50). Widerrufen Sie ungenutzte und versuchen Sie es erneut. |
token_not_allowed | Diese Einstellung kann nur nach Anmeldung im Portal geändert werden, nicht per API-Schlüssel. |
token_not_found | Der API-Schlüssel wurde nicht gefunden. |
token_not_revoked | Dieser API-Schlüssel ist aktiv, es gibt nichts wiederherzustellen. |
token_restore_expired | Der Schlüssel wurde vor mehr als 7 Tagen widerrufen und kann nicht mehr wiederhergestellt werden. Erstellen Sie einen neuen Schlüssel. |
token_scope_invalid | Der Schlüsselbereich muss „alle“ oder „ausgewählt“ sein. |
too_many_ids | Es können höchstens 500 Belege auf einmal verarbeitet werden. |
too_many_notification_emails | Geben Sie höchstens 5 E-Mail-Adressen ein. |
too_many_schedules | Eine Firma kann höchstens fünf regelmäßige Exporte haben. Löschen Sie zuerst einen, bevor Sie einen weiteren anlegen. |
too_many_tags | Der Beleg hat zu viele Tags. |
too_many_tickets | Sie haben zu viele offene Anfragen. Bitte warten Sie auf eine Antwort. |
transfer_canceled | Die Übertragung der Firma wurde abgebrochen. |
transfer_expired | Der Übertragungslink ist abgelaufen. Fordern Sie eine neue Übertragung an. |
transfer_stale | Der Inhaber der Firma hat sich inzwischen geändert; die Übertragung wurde abgebrochen. |
unauthorized | Bitte melden Sie sich erneut an. |
unknown_document | Es können nur die Dokumente DPA, SLA und NDA signiert werden. |
unsupported_document | Die Vorschau kann nur eine Rechnung oder eine Gutschrift darstellen (UBL Invoice oder CreditNote). |
unsupported_media_type | Dieser Inhaltstyp wird nicht akzeptiert. Senden Sie die Daten als JSON. |
user_not_found | Es wurde kein Konto mit dieser E-Mail gefunden. Der Benutzer muss sich zuerst registrieren. |
validation_failed | Einige Felder sind nicht korrekt ausgefüllt. |
validator_unavailable | Die Validierung ist derzeit nicht verfügbar. Versuchen Sie es gleich erneut. |
verification_code_rejected | Das SMP hat den Verifizierungstoken aus der FS-Auswahl abgelehnt; wiederholen Sie die Auswahl. |
verification_token_missing | Der Verifizierungstoken aus der FS-Auswahl fehlt; wiederholen Sie die Auswahl und versuchen Sie es erneut. |
verified_company_required | Den Antrag kann nur ein Konto mit mindestens einer verifizierten Firma stellen. |
version_stale | Der Wortlaut des Dokuments hat sich inzwischen geändert. Laden Sie die Seite neu und signieren Sie die aktuelle Fassung. |
webhook_not_configured | Legen Sie zuerst die Webhook-URL fest und speichern Sie sie. |
webhook_url_https_required | In der Produktion muss die Webhook-URL mit https:// beginnen (eine Zustellung enthält Kundenkennungen und eine Signatur). |
webhook_url_unreachable | Die Webhook-URL muss öffentlich erreichbar sein. Localhost und interne Netze sind von unseren Servern nicht erreichbar. |
white_label_owner_fixed | Eine über einen Partner geführte Firma verwaltet das Partnerkonto. Einen weiteren Eigentümer fügt der Partner durch Freigabe der Firma hinzu, oder die Auswahl von Verteco auf dem Portal der Finanzverwaltung. |
wrong_endpoint | Dies ist nicht der Token-Endpunkt. Verwenden Sie POST /sapi/auth/token mit client_id und client_secret. |
xml_not_available | Für diesen Beleg ist kein Original-XML gespeichert; der Inhalt ist nicht mehr verfügbar. |
xml_required | Das XML des Belegs fehlt, die Vorschau kann nicht erstellt werden. |
xml_too_large | Der Beleg ist für eine Vorschau zu groß (höchstens 8 MB einschließlich Anlagen). |
Rate-Limits
Die API ist durch Rate-Limiting in einem Fenster von 60 Sekunden geschützt (pro Instanz). Limit und Restkontingent liefern wir in jeder Response über Header; bei Überschreitung kommt 429 Too Many Requests mit Retry-After zurück.
- Normale Aufrufe
- dynamisches Limit mit großer Reserve, pro API-Token (oder Session, sonst IP); den aktuellen Wert liefert der Header RateLimit-Limit
- Auth (/auth/*)
- strengeres Limit pro IP (Anti-Brute-Force; außer /auth/me und /auth/logout)
RateLimit-Limit- Limit im Fenster
RateLimit-Remaining- wie viel noch übrig ist
RateLimit-Reset- Sekunden bis zum Zurücksetzen des Fensters
Retry-After- Sekunden bis zum nächsten Versuch (bei 429)
HTTP/2 429 Too Many Requests
RateLimit-Limit: <Limit im Fenster>
RateLimit-Remaining: 0
RateLimit-Reset: 37
Retry-After: 37
{ "error": "rate_limited", "message": "Too many requests. Slow down." }- Rabatte und Rundung: Die Regeln R040 (Rabattbetrag = Basis × % / 100) und R120 (Zeilenbetrag = Menge × Preis − Zeilenrabatte) tolerieren 0,02 €; exakt ist nur R046 für den Rabatt auf Preisebene (PriceAmount = BaseAmount − Amount). Einzelpreis (BT-146) sowie Bruttopreis und Preisnachlass (BT-147, BT-148) haben keine Begrenzung der Nachkommastellen, alle anderen Beträge 2. Wendet Ihr System den Rabatt auf den Einzelpreis an und rundet ihn, schreiben Sie ihn auf Preisebene: PriceAmount = gerundeter Nettopreis, BaseAmount = Listenpreis, Amount = exakte Differenz, Zeilenbetrag = round(Menge × PriceAmount, 2); ein Prozentsatz ist dort nicht möglich (er gehört in die Zeilennotiz). Zweite Möglichkeit ist ein Zeilenrabatt nur mit Betrag und Grundcode 95; Prozent und Basis im Zeilenrabatt nur, wenn Basis = round(Menge × exportierter PriceAmount, 2) und Amount = round(Basis × % / 100, 2). Eine negative Menge mit positivem Preis (Rückgabe, Abzug einer versteuerten Anzahlung) ist in Gutschrift und Rechnung erlaubt. Muster 11, 15 und 16 auf /de/vzory.
- Limits sind an das Credential gebunden, nicht an die IP: 300 Aufrufe pro Minute pro API-Token (SAPI: pro Access-Token), Auth-Endpunkte 20 pro Minute pro IP und eine Schutzobergrenze von 600 pro Minute pro IP auf /api/v1. Eine serverseitige Integration hinter einer IP ist nicht betroffen; höhere Limits setzen wir auf Anfrage, nennen Sie uns die erwartete Spitze.
- Kapazität: das Volumen ist nicht durch die Preisliste begrenzt, der Versand ist asynchron (der Aufruf übergibt den Beleg, die Zustellung läuft im Hintergrund) und ein Batch-Aufruf nimmt bis zu 100 Belege auf einmal an; für eine geplante Spitze schreiben Sie uns vorab das erwartete Volumen, und wir heben das Limit des Keys an.
- Polling ist ein vollwertiger Weg: GET /sapi/document/sent und /receive mit ?since und ?until alle 1 bis 5 Minuten; Webhooks sind eine Ergänzung, keine Voraussetzung.
- Zeitstempel (§ 76a Abs. 2 Buchst. d): sentAt = Übergabe an den Zustelldienst (damit ist die Pflicht des Ausstellers nach § 85o Abs. 11 erfüllt), deliveredAt = Bestätigung des Empfänger-Access-Points per MLS, fsReportedAt = Meldung an die Finanzverwaltung; bei empfangenen Dokumenten creationDateTime = Empfang. Alle drei stehen in jeder Zeile von /sapi/document/sent, in /sapi/document/sent/{id} und in den Webhooks (zusätzlich occurredAt).
- PDF: GET /sapi/document/receive/{id}/pdf und GET /sapi/document/sent/{id}/pdf (auch als links.pdf verlinkt) liefern das PDF des Lieferanten, wenn der Beleg eines enthält, sonst ein aus dem XML erzeugtes PDF; druckbares HTML gibt es unter …/html (Portal ?format=html).
- C#/.NET und andere Sprachen: generieren Sie den Client aus OpenAPI (NSwag, Kiota, openapi-generator); ein eigenes NuGet-Paket liefern wir nicht.
- Schlüsselbereich: beim Anlegen eines API-Schlüssels (Seite API-Schlüssel) wählen Sie, ob er alle Unternehmen des Kontos umfasst (auch später hinzugefügte) oder nur ausgewählte. Ein Aufruf mit dem Schlüssel für ein anderes Unternehmen liefert 403 token_company_not_allowed (SAPI-SK: SAPI-AUTH-003); die Rotation behält den Bereich bei. Einen Nur-Lese-Schlüssel gibt es noch nicht.
- Basispfad: jeder SAPI-SK-Aufruf, einschließlich unserer Erweiterungen (GET /sapi/document/sent, GET /sapi/document/receive/{id}/pdf, GET /sapi/discovery), läuft unter
/sapimit demselben Access-Token und dem HeaderX-Peppol-Participant-Id. Ein 401 „Authentication required“ ohne SAPI-…-Code bedeutet, dass der Pfad außerhalb von/sapiliegt (zum Beispiel /api/v1/document/sent);/api/v1ist die Portal-API und erwartet als Bearer denvpt_-Schlüssel, kein SAPI-Access-Token. - Das Ausstellungsdatum (BT-2) prüfen wir nicht gegen den Tag der Übergabe: der Beleg geht in dem Moment ins Netz, in dem wir ihn erhalten; senden Sie ihn daher am Ausstellungstag und stellen Sie ihn nicht über Mitternacht in eine Warteschlange. Einen Beleg in Fremdwährung melden wir der Finanzverwaltung mit dem Steuerbetrag in EUR aus BT-110 und BT-111 (TaxCurrencyCode EUR), wie Muster 03 zeigt.
- Lieferdatum: das XML führt es als BT-72 (
cac:Delivery/cbc:ActualDeliveryDate); ein Steuerbeleg zur erhaltenen Zahlung führt in BT-72 das Zahlungsdatum (Muster 12). Unsere eigenen Dienstleistungsrechnungen und Belege aus dem Portal geben es immer an, auch wenn es dem Ausstellungsdatum entspricht (§ 74 Abs. 1 Buchst. d des USt-Gesetzes verlangt es nur bei Abweichung). Beim Lesen nehmen Sie BT-72, sonst BT-7 (cbc:TaxPointDate), sonst das Ausstellungsdatum.
Rate-Limit-Budgets (aktuelle Werte)
Das Fenster beträgt 60 Sekunden. Jede Antwort trägt RateLimit-Limit, RateLimit-Remaining, RateLimit-Reset und RateLimit-Policy (limit;w=Fenster in Sekunden), eine 429 zusätzlich Retry-After. Werte können ohne Ankündigung erhöht werden; lesen Sie die Header, nicht diese Tabelle.
| Aufrufe | Budget-Schlüssel | Limit |
|---|---|---|
/sapi/* und /api/mcp mit Token | client_id hinter dem Token (Rotation des Access-Tokens setzt nicht zurück) | 300 / min |
/api/v1/* mit API-Schlüssel oder Session | Schlüssel (Hash) oder Session | 300 / min |
POST /sapi/auth/token, renew, revoke | IP | 60 / min |
/api/v1/auth/* (Login, Reset) | IP | 20 / min |
Öffentliche Werkzeuge (/api/v1/public/peppol-check, Validator) | IP | 15 / min |
Massenprüfung (/public/peppol-check/batch) | IP | 6 / min |
Live-Netzwerkabfragen (peppol-check, /sapi/discovery, MCP check_participant) | IP oder Schlüssel; dazu das ganze Portal | 40 / h je Aufrufer und 150 / h insgesamt; darüber antwortet die nächtliche Erhebung (source: index), die Massenprüfung ist nicht begrenzt |
Registrierung, Passwort vergessen, Kontaktformular | IP | 15 / Std |
Schutzgrenze für alles mit ungeprüftem Bearer | IP | 600 / min |
HTTP/2 200
RateLimit-Limit: 300
RateLimit-Remaining: 287
RateLimit-Reset: 41
RateLimit-Policy: 300;w=60API-Tokens
Opake Tokens vpt_… für den Server-to-Server-Zugriff. Der Klartext wird nur einmal bei der Erstellung angezeigt. Speichern Sie ihn. Wir speichern nur den SHA-256-Hash und ein 12-stelliges Präfix zur Anzeige.
/tokensSession / TokenListe Ihrer aktiven Tokens (ohne Secret), nach createdAt absteigend.
/tokensSession / TokenErstellt einen Token; gibt den Klartext zurück (ein einziges Mal).
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
name | string | ja | Name des Tokens, max. 128 |
curl -X POST https://peppol.verteco.digital/api/v1/tokens -b cookies.txt \
-H 'Content-Type: application/json' -d '{"name":"moja-appka"}'
# 201 Created
{ "id":"…","name":"moja-appka","token":"vpt_8f2a…","prefix":"vpt_8f2a3b…","createdAt":"…" }/tokens/{id}Session / TokenWiderruft den Token. Gibt 204 zurück.
Fehler: token_not_found (404)
Firmen
Firmen (Handelsregisternummer IČO / USt-IdNr. IČ DPH), die Sie verwalten. Der Zugriff ist an die Mitgliedschaft gebunden: Sie sehen nur Firmen, deren Mitglied Sie sind. Wer eine Firma anlegt, wird ihr owner.
/companiessession / tokenListe der Firmen, deren Mitglied Sie sind (mit Ihrer Rolle).
/companiessession / tokenLegt eine Firma an; Sie werden owner, status = pending_verification.
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
ico | string | ja | genau 8 Ziffern |
dic | string | ja | UID als SK + 10 Ziffern (z. B. SK2121358349); ein Nicht-Umsatzsteuerzahler sendet nur die 10-stellige DIČ, SK ergänzen wir |
legalName | string | ja | Firmenname, max. 500 |
registeredAddress | string | nein | Firmensitz, max. 1000 |
curl -X POST https://peppol.verteco.digital/api/v1/companies \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"ico":"53412834","dic":"SK2121358349","legalName":"Verteco digital services, s. r. o."}'
# 201 Created
{ "id":"08dd…","ico":"53412834","dic":"SK2121358349","legalName":"…",
"registeredAddress":null,"peppolParticipantId":null,
"status":"pending_verification","role":"owner","createdAt":"2026-06-03T09:40:27Z" }Fehler: ico_taken (409) · validation_failed (400)
/companies/{id}session / tokenFirmendetails (Sie müssen Mitglied sein).
/companies/{id}owner / adminFirma bearbeiten. Die IČO ist unveränderlich (muss der bestehenden entsprechen).
Fehler: forbidden (403) · ico_immutable (400) · company_not_found (404)
Feld status
pending_verification- nach dem Anlegen; das Senden ist noch nicht freigeschaltet
active- verifiziert, Senden freigeschaltet
Rolle des Mitglieds
owner- Ersteller der Firma (Vollzugriff)
admin- Administrator (Änderungen, Webhooks, Verifizierung)
member- Mitglied (Lesen)
viewer- nur Lesen
owner als auch admin (Firmenmanager) zur Verfügung.Verifizierung für das Senden (Verifizierungsmerkmal)
Vor dem Senden muss die Firma über das Verifizierungsmerkmal (Verifikačný údaj, VÚ) verifiziert werden, ein signiertes Token der Finanzverwaltung der Slowakischen Republik (Finančná správa, FS). Nach erfolgreicher Verifizierung wechselt der status der Firma auf active und das Senden wird freigeschaltet.
/companies/{id}/verificationowner / adminSelf-Verify des Verifizierungsmerkmals. Bei Erfolg wird der status auf active gesetzt.
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
token | string | ja | VÚ = Hex-Signatur (prod/pPFS 1024 hex, test/tPFS 768 hex) |
curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/verification \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"token":"<1024-hex VÚ>"}'
# 200 OK
{ "companyId":"08dd…","status":"active","sendingVerified":true,
"verificationMethod":"self","verifiedAt":"2026-06-15T…Z" }Fehler: company_dic_missing (400) · token_invalid (400) · forbidden (403)
Dokumente
Protokoll der Peppol-Belege (empfangene und gesendete) je Firma. Es füllt sich, während Rechnungen über den Access Point fließen. An die Mitgliedschaft in der Firma gebunden, sortiert nach createdAt absteigend.
/companies/{id}/documentssession / tokenListe der Belege der Firma. Optionaler Filter ?direction=sent|received.
curl 'https://peppol.verteco.digital/api/v1/companies/{id}/documents?direction=received' \
-H 'Authorization: Bearer vpt_8f2a…'
# 200 OK
[ { "id":"…","direction":"received","peppolMessageId":"…","docTypeId":"…",
"senderId":"0088:7300010000001","receiverId":"0245:2121358349",
"invoiceNumber":"2026001","issueDate":"2026-06-03",
"currency":"EUR","totalAmount":120.00,"status":"received","createdAt":"…" } ]/companies/{id}/documents/{docId}session / tokenDetails eines einzelnen Belegs.
Fehler: document_not_found (404)
/companies/{id}/documents/{docId}/downloadsession / tokenEigenständiges HTML der Rechnung zum Drucken. ?inline=1 → Anzeige im Browser, sonst Download.
Liefert text/html, Content-Disposition mit dem Dateinamen faktura-<číslo>.html (číslo = Rechnungsnummer).
SAPI-SK 1.0 (nationale Schnittstelle)
SAPI-SK ist die standardisierte nationale REST-Schnittstelle zwischen dem Kunden-/ERP-System und dem Access Point (sapi-sk.sk). Wir implementieren sie in vollem Umfang. Dadurch sind Sie nicht an die proprietäre Form unserer API gebunden und schreiben die Integration einmal für jeden beliebigen SAPI-SK Access Point.
- Base URL
https://peppol.verteco.digital/sapi- Authentifizierung
- OAuth2 client_credentials → kurzlebiger Access Token (JWT)
- client_id
- UUID Ihres API-Tokens (Liste im Dashboard-Bereich „API tokeny“, dt. API-Tokens)
- client_secret
- der
vpt_…-Token selbst aus dem Portal - Version
- 1.3 (10 Operationen: 4× Auth, 6× Dokumente)
vpt_-Token des Portals noch die Session). Der Widerruf des API-Tokens im Portal macht sofort sowohl /auth/token als auch /auth/renew ungültig.Sandbox (Probeumgebung)
Möchten Sie SAPI-SK ohne Registrierung und ohne Risiko ausprobieren? Verwenden Sie die öffentlichen Sandbox-Zugangsdaten. Die Sandbox validiert Requests genau wie der Produktivbetrieb, sendet aber niemals etwas in das Peppol-Netzwerk und arbeitet nicht mit realen Daten; sie liefert realistische Mock-Responses. Ideal für Entwicklung, CI und das Onboarding einer Integration.
- client_id
sandbox- client_secret
sandbox- send
- vollständige Validierung des API-Kontrakts + Mock 202 (es wird nichts zugestellt)
- receive
- 1 Beispielbeleg
sandbox-doc-0001zum Testen von Parsing und Acknowledge
# 1) Sandbox-Token (ohne Registrierung)
curl -X POST https://peppol.verteco.digital/sapi/auth/token \
-H 'Content-Type: application/json' \
-d '{ "client_id": "sandbox", "client_secret": "sandbox",
"grant_type": "client_credentials" }'
# 2) Mock-Versand: wird validiert, aber es wird NICHTS real zugestellt
curl -X POST https://peppol.verteco.digital/sapi/document/send \
-H 'Authorization: Bearer <sandbox access_token>' \
-H 'X-Peppol-Participant-Id: 0245:0000000000' \
-H 'Content-Type: application/json' \
-d '{ "metadata": { "documentId": "TEST-1",
"documentTypeId": "urn:…::Invoice##…::2.1",
"senderParticipantId": "0088:sandbox-sender",
"receiverParticipantId": "0088:sandbox-receiver" },
"payload": "<Invoice>…</Invoice>", "payloadFormat": "XML" }'
# 202 { "providerDocumentId": "sandbox-…", "status": "ACCEPTED", … }
# 3) Beispiel-Postfach + Detail des Beispielbelegs
curl https://peppol.verteco.digital/sapi/document/receive \
-H 'Authorization: Bearer <sandbox access_token>'
curl https://peppol.verteco.digital/sapi/document/receive/sandbox-doc-0001 \
-H 'Authorization: Bearer <sandbox access_token>'client_id/client_secret aus dem Portal (unten).Authentifizierung
/sapi/auth/tokenclient_credentialsTauscht client_id + client_secret gegen einen Access Token (15 Min.) und einen Refresh Token (30 Tage). Speichern Sie den Token und verwenden Sie ihn die vollen 15 Minuten: ein neuer Token bei jedem Aufruf ist unnötiger Overhead (das Request-Limit gilt auch für /auth/token).
curl -X POST https://peppol.verteco.digital/sapi/auth/token \
-H 'Content-Type: application/json' \
-d '{ "client_id": "<UUID des Tokens>", "client_secret": "vpt_8f2a…",
"grant_type": "client_credentials" }'
# 200 OK
{ "access_token": "eyJhbGciOi…", "token_type": "Bearer",
"expires_in": 900, "refresh_token": "eyJhbGciOi…" }Fehler: SAPI-AUTH-001 (401) · SAPI-AUTH-003 (401: IP außerhalb der Allowlist des Schlüssels) · SAPI-VAL-001 (400)
/sapi/auth/token/statusBearer (access)Gültigkeit und Ablauf des Access Tokens; should_refresh = true bei < 3 Min. bis zum Ablauf.
/sapi/auth/renewrefresh tokenStellt einen neuen Access + Refresh Token aus. Schlägt fehl, wenn der zugrunde liegende API-Token widerrufen wurde.
// Body
{ "refresh_token": "eyJhbGciOi…" }/sapi/auth/revoke–Gibt immer success zurück (RFC 7009). Dauerhafter Kill-Switch = Widerruf des API-Tokens im Portal.
Versand eines Dokuments
/sapi/document/sendBearer (access)Sendet ein Peppol-Geschäftsdokument (UBL / BIS 3.0) über unseren Access Point an den Empfänger. Der Versand ist fail-closed: die Firma muss ein verifiziertes Verifizierungsmerkmal (Verifikačný údaj) besitzen. Die Antwort kann ein additives Array warnings[] mit denselben unverbindlichen Hinweisen wie /document/validate tragen (TEST-Nummer, Empfänger aus demselben Konto, Rechnungsdatum ungleich Versandtag); ein Hinweis blockiert den Beleg nie.
Pflicht-Header:
| Header | Beschreibung |
|---|---|
Authorization | Bearer <access_token> |
X-Peppol-Participant-Id | Teilnehmer, in dessen Namen Sie senden (z. B. 0245:2121358349, also die Ziffern der DIČ, der slowakischen Steuernummer, ohne „SK“) |
Idempotency-Key | ein Schlüssel pro Rechnung, abgeleitet aus etwas Stabilem (z. B. Ihr System + ID oder Nummer der Rechnung); ein wiederholter Aufruf damit liefert das ursprüngliche Ergebnis und stellt nie doppelt zu, ein neuer Schlüssel für dieselbe Rechnung umgeht diesen Schutz. Der Schlüssel gilt je Firma (X-Peppol-Participant-Id). Ausnahme: ist der erste Versuch nie ins Netz gelangt (Validierungsfehler, unvollständige Anfrage, der Empfänger veröffentlicht den Dokumenttyp nicht, der Access Point hat die Wiederholungen aufgegeben, Transportfehler mit Status failed) oder endete er als undeliverable, führt derselbe Schlüssel den Versand erneut aus, „korrigieren und erneut senden“ funktioniert also unter derselben Rechnungsnummer; Vorgehen im Hinweis Korrigieren und erneut senden unten. Der Schlüssel läuft nie ab: er ist am Datensatz des Dokuments gespeichert, den wir dauerhaft aufbewahren (die Aufbewahrungsfrist löscht nur den Inhalt), eine Wiederholung mit demselben Schlüssel liefert das ursprüngliche Ergebnis also auch nach Monaten. |
curl -X POST https://peppol.verteco.digital/sapi/document/send \
-H 'Authorization: Bearer eyJ…' \
-H 'X-Peppol-Participant-Id: 0245:2121358349' \
-H 'Idempotency-Key: 7b1f0e2a-…' \
-H 'Content-Type: application/json' \
-d '{ "metadata": {
"documentId": "INV-2026-001",
"documentTypeId": "urn:…::Invoice##…::2.1",
"processId": "urn:…:bis:billing:3.0",
"senderParticipantId": "0245:2121358349",
"receiverParticipantId": "0088:7300010000001",
"creationDateTime": "2026-06-17T10:00:00Z" },
"payload": "<Invoice …>…</Invoice>",
"payloadFormat": "XML" }'
# 202 Accepted
{ "providerDocumentId": "…", "status": "ACCEPTED",
"receivedAt": "2026-06-17T10:00:01Z", "timestamp": "…" }
# bei Status "REJECTED" enthält die Response zusätzlich das Feld "detail"
# mit dem Ablehnungsgrund (Validierungsregeln, z. B. BR-CO-15)metadata dienen dem Routing und sind technisch: documentId ist Ihr interner Identifikator, nicht die Rechnungsnummer. Die Geschäftsdaten (Rechnungsnummer cbc:ID, Ausstellungsdatum, Fälligkeit, Lieferdatum, Währung, Betrag) übernehmen wir direkt aus dem UBL-Payload; nichts davon senden Sie in metadata, und UBL ist stets die Quelle der Wahrheit für die Anzeige im Portal wie auch für Webhooks. documentTypeId: der vollständige busdox-docid-qns-Identifikator; einen bloßen Namespace oder eine alleinstehende CustomizationID normalisieren wir auf den aus dem Payload abgeleiteten Typ, einen Typ, der dem Payload widerspricht, lehnen wir mit SAPI-VAL-001 ab; das Teilnehmerschema muss aus der EAS-Liste stammen.Fehler: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400) · SAPI-PROC-001 (502) · SAPI-PROC-002 (503) · SAPI-PROC-500 (500: nicht wiederholen, melden Sie die correlation_id)
202, das Verdikt steht im Body (status ACCEPTED oder REJECTED). Soll auch der HTTP-Status das Verdikt tragen, senden Sie Prefer: handling=strict (RFC 7240): eine synchrone Ablehnung kommt dann als 422 mit der SAPI-Fehlerhülle zurück (SAPI-VAL-002 bei einem Validierungsfehler, SAPI-RES-003, wenn an den Empfänger nicht zugestellt werden kann; details[] enthalten providerDocumentId und detail), und die Antwort trägt Preference-Applied: handling=strict. ACCEPTED bleibt unverändert. Vor der Übergabe an den Access Point führen wir denselben SML-Lookup aus wie er. Das Dokument wird zuerst validiert: Nur ein gültiges Dokument wird übernommen und gemeldet, ein ungültiges erhält REJECTED mit validation_failed, auch wenn der Empfänger nicht im Netz ist. Ein Empfänger, der gar nicht im Peppol-Netz ist, bedeutet ACCEPTED mit undeliverable: true: Wir haben das Dokument übernommen und melden es der Finanzverwaltung unabhängig von der Zustellung (§ 85o Abs. 11, FS FAQ 9/DPH/2025/IM, Teil II, Beispiel 9), zugestellt wird es aber niemandem; auf GET /sapi/document/sent hat es den Status undeliverable, der Webhook erhält invoice.undeliverable, eine E-Mail geht an niemanden, und derselbe Idempotency-Key sendet erneut, sobald die Empfängerkennung korrigiert ist oder der Empfänger sich registriert hat (Vorgehen im Hinweis Korrigieren und erneut senden unten). Ein Empfänger, der im Netz ist, aber den Dokumenttyp nicht veröffentlicht, erhält sofort REJECTED, ohne Zustellversuch. retrying: true bei ACCEPTED bedeutet, dass der erste Zustellversuch fehlschlug (z. B. vorübergehend nicht erreichbares SMP) und der Access Point ihn selbst wiederholt, in der Regel innerhalb von 20 Minuten; detail nennt den Grund, das endgültige Verdikt kommt über GET /sapi/document/sent oder den Webhook.handling=strict auch 422), erhält eine eigene providerDocumentId, auch ein abgelehnter.- REJECTED durch unsere Prüfung vor dem Versand (Validierungsfehler, unvollständige Anfrage, der Empfänger veröffentlicht den Dokumenttyp nicht, sein SMP-Eintrag hat für den Typ keinen Endpoint, der Access Point hat die Wiederholungen aufgegeben): Nichts ist ins Netz gelangt, nichts wurde zugestellt und nichts wird der Finanzverwaltung gemeldet. Korrigieren Sie die Daten und senden Sie das Dokument erneut mit demselben
Idempotency-Key. Der neue Versuch erhält eine neueproviderDocumentId; der erste Eintrag bleibt in der Liste der gesendeten Dokumente alsrejectedmit seinem Grund, nur als Nachweis des gescheiterten Versuchs, und lässt sich nicht löschen. Verknüpfen Sie die Rechnung in Ihrem System immer mit der letztenproviderDocumentId. Die Rechnungsnummer kann gleich bleiben, die Rechnung ist im Sinne des Gesetzes noch nicht ausgestellt. Das Ausstellungsdatum (BT-2) muss aber der Tag sein, an dem die Rechnung tatsächlich hinausgeht: Eine E-Rechnung gilt an dem Tag als ausgestellt, an dem sie dem Zustelldienst übergeben wird, und muss spätestens 15 Tage nach der Lieferung oder dem Zahlungseingang versendet werden (FS FAQ 9/DPH/2025/IM, Teil I, Beispiel 74). Geht die korrigierte Rechnung an einem späteren Tag hinaus, ändern Sie das Ausstellungsdatum auf diesen Tag. - An das Netz übergeben (ACCEPTED ohne undeliverable: submitted, delivered oder Wiederholung im Hintergrund; dazu gehört auch ein Dokument, das die MLS des Empfängers nach der Übertragung abgelehnt hat und das ein erneuter Aufruf als REJECTED mit Grund zurückgibt): Derselbe Schlüssel liefert das Ergebnis dieses Versands, nichts wird doppelt gesendet. Senden Sie eine zugestellte Rechnung nie erneut; sie wird mit einer Gutschrift (381) oder einer Belastungsanzeige (383) korrigiert.
- undeliverable (der Empfänger hat keine Adresse im Peppol-Netz): Die Rechnung wurde übergeben, sie wird der Finanzverwaltung unabhängig von der Zustellung gemeldet und die Pflicht des Ausstellers ist erfüllt (FS FAQ 9/DPH/2025/IM, Teil I, Beispiele 42 und 75). Der Schlüssel wird freigegeben. War die Empfängerkennung falsch (zum Beispiel eine IČO oder eine DIČ mit Tippfehler statt 0245:<10 Ziffern der DIČ>, oder der Empfänger ist unter einer anderen Kennung im Netz), korrigieren Sie die Kennung und senden Sie erneut mit demselben Schlüssel; lassen Sie die Rechnung unverändert (gleiche Nummer und gleiches Datum), sie wurde bereits übergeben. Eine 8-stellige Nummer ist eine IČO und wird im Netz nie gefunden. Ist die Kennung richtig und der Empfänger nur nicht registriert, senden Sie ihm dieselbe Rechnung auf anderem Weg, am besten ihr XML per E-Mail (PDF nur als Vorschau). Nach FS FAQ Teil I, Beispiel 75 ist das ein erneutes Zusenden derselben Rechnung, keine neue Rechnung, stellen Sie daher keine neue Rechnung mit anderer Nummer aus. Sobald sich der Empfänger registriert, können Sie ihm dieselbe Rechnung über Peppol erneut senden, indem Sie den Aufruf mit demselben
Idempotency-Keywiederholen. - Falsche Empfängerkennung oder leere eigene Kennung: Ein
X-Peppol-Participant-Id-Header nur mit dem Schema (zum Beispiel0245:, wenn in den Programmeinstellungen die DIČ des Unternehmens fehlt) wird beim Versand mit 403 SAPI-AUTH-003 und einer Erklärung abgewiesen, und /document/validate mit einem solchen Header ergänzt schon vor dem Versand eine Warnung inwarnings. Ein Empfänger als 0088 (GLN) oder als 0245 mit 8 Ziffern (IČO statt DIČ) wird im slowakischen Netz nicht gefunden: Das Dokument endet als undeliverable und seinstatusReason(das Detail in der Antwort auf send) nennt die Korrektur: 0245 und die 10 Ziffern der DIČ. - Fehlern vorbeugen: Rufen Sie vor dem Versand
POST /sapi/document/validate(dieselben Regeln wie beim Versand, speichert und sendet nichts) undGET /sapi/discovery?receiverId=…auf (ist der Empfänger im Netz und welche Dokumenttypen nimmt er an). Den Endstand liefernGET /sapi/document/sent?invoiceNumber=…,GET /sapi/document/sent/{id},POST /sapi/document/sent/statusoder die Webhooksinvoice.delivered,invoice.rejectedundinvoice.undeliverable.
/sapi/document/validateBearer (access)Validiert ein Dokument ohne Versand: dieselben Regeln EN 16931 + Peppol BIS 3.0, die der Access Point vor dem Versand anwendet. Nichts wird gespeichert oder versendet; funktioniert auch mit dem Sandbox-Token. Body = das JSON-Paar { payload, payloadFormat } wie bei /document/send oder direkt das XML (Content-Type: application/xml). Limit 10 MB. Die Antwort trägt zusätzlich ein Array warnings[] mit unverbindlichen Hinweisen (zum Beispiel eine TEST-Nummer, ein Empfänger, der eine andere Firma desselben Kontos ist, oder ein Rechnungsdatum BT-2, das nicht der Versandtag ist); ein Hinweis blockiert den Beleg nie.
curl -X POST https://peppol.verteco.digital/sapi/document/validate \
-H 'Authorization: Bearer eyJ…' \
-H 'Content-Type: application/xml' \
--data-binary @rechnung.xml
# 200 OK
{ "valid": false,
"errors": [ "BR-CO-15: Invoice total amount with VAT (BT-112) = … " ],
"warnings": [],
"checkedAt": "2026-09-10T12:00:00Z" }Fehler: SAPI-AUTH-002 (401) · SAPI-VAL-001 (400: leerer Body, ungültiges JSON, payloadFormat ungleich XML, > 10 MB) · SAPI-SYS-002 (502: Validator vorübergehend nicht verfügbar, erneut versuchen)
Empfang von Dokumenten
/sapi/document/receiveBearer (access)Liste der empfangenen Dokumente (älteste zuerst); die Metadaten enthalten auch invoiceNumber, sodass Sie den Beleg ohne Download des Payloads identifizieren. Query: ?pageToken, ?limit (max. 200), ?status (Filter: received = nur noch nicht bestätigte Belege, acknowledged = nur bestätigte, ohne Parameter alle empfangenen Belege; unabhängig von Groß-/Kleinschreibung, ein anderer Wert liefert den Fehler SAPI-VAL-001), ?invoiceNumber (exakte Übereinstimmung mit cbc:ID), ?since und ?until (ISO-8601-Instant; Zeitfenster nach Empfangszeitpunkt, z. B. Belege der letzten 5 Tage, Massendownload für eine externe Archivierung oder die Rekonstruktion der Buchhaltung), ?deliveryDateFrom und ?deliveryDateTo (ISO-8601-Datum; Filter nach dem Lieferdatum aus dem Beleg). Der Header X-Peppol-Participant-Id ist Pflicht.
// 200 OK
{ "documents": [ { "documentId":"…","documentTypeId":"…",
"senderParticipantId":"0088:…","receiverParticipantId":"0245:…",
"creationDateTime":"2026-06-17T…Z" } ],
"nextPageToken": "50" }/sapi/document/receive/{documentId}Bearer (access)Detail inklusive Payload (Roh-XML, so wie es über Peppol eingegangen ist).
Fehler: SAPI-RES-001 (404) · SAPI-RES-002 (404: Payload nicht archiviert)
/sapi/document/receive/{documentId}/acknowledgeBearer (access)Bestätigt die Übernahme des Dokuments durch Ihr System. Idempotent.
/sapi/document/receive/{documentId}/xmlBearer (access)Archivlink (metadata.links.xml): das Geschäftsdokument selbst als XML-Datei, gleicher Inhalt wie der Payload im Detail.
/sapi/document/receive/{documentId}/htmlBearer (access)Archivlink (metadata.links.html): generische druckbare Darstellung der Rechnung (HTML).
/sapi/document/receive/{documentId}/pdfBearer (access)Archiv-Link (metadata.links.pdf): das PDF des Belegs. Hat der Lieferant sein eigenes Rechnungs-PDF ins XML eingebettet (BT-125), erhalten Sie dieses Original; sonst ein auf Anfrage aus dem gespeicherten XML erzeugtes PDF (kein PDF wird gespeichert). Header X-Verteco-Pdf-Source: supplier | generated. 404 SAPI-RES-002 nach Löschung des Inhalts, 503 bei nicht verfügbarem Renderer (später erneut oder /html).
/sapi/document/receive/{documentId}/attachments/{index}Bearer (access)Archivlink (metadata.links.attachments[].url): die Bytes eines im Dokument eingebetteten Anhangs, z. B. das PDF-Original des Lieferanten. Erzwungener Download.
/sapi/document/receive/{documentId}/public-linkBearer (access)Link ohne Anmeldung (optional): erzeugt einen NEUEN Zufallsschlüssel für den Beleg ({"rotate":true} ersetzt den bestehenden). Liefert url (Seite), xmlUrl, htmlUrl, pdfUrl und expiresAt; der Schlüssel wird nur einmal angezeigt. Die Firma muss „Download ohne Anmeldung“ aktiviert haben (sonst 403 SAPI-AUTH-004). DELETE widerruft ihn.
Status gesendeter Dokumente
/sapi/discovery?receiverId=0245:2121358349Preflight vor dem Versand: Ist der Empfänger im Peppol-Netzwerk registriert und welche Belegtypen kann er empfangen? Derselbe SML-Lookup, den auch der Access Point durchführt; receiverId akzeptiert eine Peppol-ID, eine USt-IdNr. (IČ DPH) sowie die DIČ selbst. Response: {registered, participantId, smp, documentTypes, checkedAt}. Der Header X-Peppol-Participant-Id ist hier nicht erforderlich.
/sapi/document/sentBearer (access)Zustellstatus gesendeter Belege: pending (Übergabe an das Netzwerk) → submitted → delivered / rejected (bestätigt durch den Zustellnachweis (MLS) vom AP des Empfängers); failed = Transportfehler (ein Retry mit demselben Idempotency-Key sendet erneut). Query: ?pageToken, ?limit, ?status (pending / submitted / sent / delivered / rejected / failed; unabhängig von Groß-/Kleinschreibung, ein anderer Wert liefert den Fehler SAPI-VAL-001), ?invoiceNumber (exakte Übereinstimmung mit cbc:ID: der Status einer konkreten Rechnung mit einem einzigen Aufruf), ?since und ?until (ISO-8601-Instant; Zeitfenster), ?deliveryDateFrom und ?deliveryDateTo (ISO-8601-Datum; Filter nach Lieferdatum).
// 200 OK
{ "documents": [ {
"documentId": "…",
"receiverParticipantId": "0245:1084695645",
"peppolMessageId": "befc9112-…",
"status": "delivered",
"statusDateTime": "2026-07-09T14:52:31Z",
"creationDateTime": "2026-07-09T14:52:12Z" } ],
"nextPageToken": null }Fehler: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400: ungültiges since)
MLS-Empfangsbestätigung und Zustellnachweise
Die MLS-Empfangsbestätigung (Peppol Message Level Status) ist die Antwort des empfangenden Access Points auf unsere Übertragung: AP = angenommen und zugestellt, AB = zugestellt ohne fachliche Bestätigung, RE = abgelehnt mit Grund. Das Portal speichert sie beim gesendeten Dokument und setzt den Status entsprechend: AP und AB bedeuten beide delivered (bei AB beginnt statusDetail mit „MLS AB: “ und mls.responseCode ist AB; nach SPOG on MLS ist das eine Zustellung ohne fachliche Bestätigung, kein Vorbehalt), RE bedeutet rejected. Nach § 76a Abs. 2 Buchst. d des Gesetzes 222/2004 muss der Anbieter Datum und Uhrzeit von Versand, Zustellung und Empfang nachweisen können; jede Zeile von GET /sapi/document/sent und jeder Webhook trägt diese drei Zeiten: sentAt (Übergabe an den Zustelldienst, damit ist nach § 85o Abs. 11 die Pflicht des Ausstellers erfüllt), deliveredAt (Bestätigung des Empfänger-Access-Points per MLS) und fsReportedAt (Meldung an die Finanzverwaltung). Ein ausländischer Access Point sendet unter Umständen nie eine MLS: das Dokument bleibt dann delivered mit dem Detail as4_receipt_only und ohne Bestätigung.
/sapi/document/sent/{documentId}Bearer (access)Detail eines gesendeten Dokuments: dieselbe Zeile wie in der Liste (inkl. sentAt, deliveredAt, fsReportedAt, hasMls, links) plus mls.responseCode (AP/AB/RE), mls.receivedAt und mls.url. mls ist null, bis eine Bestätigung eintrifft.
// 200 OK
{ "document": {
"documentId": "…", "peppolMessageId": "befc9112-…", "status": "delivered",
"sentAt": "2026-09-17T08:00:12Z", "deliveredAt": "2026-09-17T08:00:31Z", "fsReportedAt": null,
"hasMls": true,
"links": { "detail": "…/sapi/document/sent/…", "mls": "…/sapi/document/sent/…/mls" } },
"mls": { "responseCode": "AP", "receivedAt": "2026-09-17T08:00:31Z", "url": "…/sapi/document/sent/…/mls" } }Fehler: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-RES-001 (404: fremdes oder empfangenes Dokument) · SAPI-RES-004 (404: noch keine Bestätigung)
/sapi/document/sent/{documentId}/mlsBearer (access)Die Bestätigung als Datei: die MLS ApplicationResponse des Empfänger-Access-Points mit Bezug auf die peppolMessageId der Übertragung. Nachweis der Zustellung oder Ablehnung; erzwungener Download. SAPI-RES-004, solange keine Bestätigung vorliegt.
/sapi/document/sent/{documentId}/xmlBearer (access)Inhalt eines gesendeten Dokuments (SAPI 1.8.15): das reine UBL-XML, das wir dem Netz übergeben haben (Transporthülle entfernt), erzwungener Download. Gegenstück der Links auf empfangene Dokumente: das Programm eines externen Buchhalters kann so auch die AUSGESTELLTEN Rechnungen des Mandanten laden. Jede Zeile trägt links.xml, links.html und links.pdf. SAPI-RES-002, sobald die Aufbewahrungsfrist der Firma den Inhalt gelöscht hat.
/sapi/document/sent/{documentId}/htmlBearer (access)Druckansicht eines gesendeten Dokuments, aus dem gespeicherten XML erzeugt (nichts wird gespeichert).
/sapi/document/sent/{documentId}/pdfBearer (access)PDF eines gesendeten Dokuments: das im XML eingebettete PDF des Ausstellers (BT-125), sonst aus dem XML gerendert; Header X-Verteco-Pdf-Source: supplier | generated. 503 SAPI-PROC-001, solange der Renderer nicht verfügbar ist (dann /html).
Nachweise der FS-Meldung, Integrität und Zeitleiste (SAPI 1.8.14)
Seit 1.8.14 tragen jede Zeile von GET /sapi/document/sent, das Detail sowie Liste und Detail der empfangenen Belege ein Objekt fsReport: state = reported (Meldung an die Sammelstelle C5 übergeben, reportedAt = fsReportedAt), pending (Meldung geschuldet, Übergabe fehlgeschlagen, wird automatisch wiederholt, reason = c5_unavailable) oder not_required (keine Meldung; reason erklärt warum: cross_border, self_send_test, issuer_without_vat_id, recipient_without_vat_id, not_billing_document, tdd_disabled, before_2026_09_01, not_recorded). Nach der Übergabe kommt tddMessageId (SBDH InstanceIdentifier der Meldung) hinzu, nach der Antwort von C5 c5ResponseCode (AP/AB/RE), c5ResponseAt, c5Detail und die Zusammenfassung outcome: accepted (AP), accepted_with_reservations (AB), rejected (RE) oder null, solange C5 nicht geantwortet hat. outcome = rejected heißt: die Meldung wurde übergeben, aber die Finanzverwaltung hat sie abgelehnt (c5Detail trägt die verletzte Regel, z. B. BR-AE-08); state bleibt reported, weil die Übergabe stattgefunden hat, und das Portal sendet die korrigierte Meldung automatisch erneut (nach der Annahme wird outcome zu accepted). Gesendete Zeilen haben zusätzlich statusReason (Maschinencode hinter statusDetail: network_retrying, network_retrying_sent, as4_receipt_only, recipient_not_registered, transport_failed, mls_rejected, validation_failed), xmlSha256 (SHA-256 des übergebenen XML, bleibt nach der Inhaltslöschung erhalten), retention und receiptRetention = permanent (die MLS-Bestätigung wird nie gelöscht). Die Bestätigung im Detail hat mls.sha256 und mls.messageId. Empfangene Belege erhielten peppolMessageId, status (received/acknowledged), receivedAt, acknowledgedAt und xmlSha256 (SHA-256 der Bytes des Geschäftsdokuments genau so, wie links.xml sie liefert, ohne SBDH-Transporthülle; beim Empfang berechnet und nach der Inhaltslöschung erhalten). Beide Listen filtern Sie mit ?fsReport=reported|pending|not_required|rejected (rejected = outcome rejected), gesendete auch mit ?status=undeliverable. Die Antwort von POST /sapi/document/send trägt peppolMessageId bereits bei der Annahme. Alles ist additiv, bestehende Felder bleiben unverändert.
/sapi/document/sent/statusBearer (access)Status von bis zu 200 gesendeten Belegen in einem Aufruf: dieselben Zeilen wie in der Liste plus mls, wenn die Bestätigung schon vorliegt. Ids, die keine gesendeten Belege dieser Firma sind, kommen in missing zurück; der Aufruf scheitert deswegen nie. Ersetzt N Aufrufe von GET /sapi/document/sent/{id} bei der ERP-Synchronisation.
// POST { "documentIds": ["7c1e…", "9af0…", "unbekannt"] } (max 200)
{ "documents": [ {
"documentId": "7c1e…", "status": "delivered", "statusReason": null, "peppolMessageId": "befc9112-…",
"sentAt": "2026-09-21T08:00:12Z", "deliveredAt": "2026-09-21T08:00:31Z", "fsReportedAt": "2026-09-21T08:05:40Z",
"fsReport": { "state": "reported", "reportedAt": "2026-09-21T08:05:40Z", "reason": null, "outcome": "accepted",
"tddMessageId": "3f2a…", "c5ResponseCode": "AP", "c5ResponseAt": "2026-09-21T08:06:02Z", "c5Detail": null },
"xmlSha256": "9b74…", "retention": { "mode": "storage", "contentAvailableUntil": null }, "receiptRetention": "permanent",
"hasMls": true, "links": { "detail": "…", "mls": "…" },
"mls": { "responseCode": "AP", "receivedAt": "2026-09-21T08:00:31Z", "url": "…", "sha256": "e1c0…", "messageId": "mls-…" } } ],
"missing": ["9af0…", "unbekannt"] }Fehler: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400: 0 / > 200 id)
/sapi/document/sent/{documentId}/eventsBearer (access)Zeitleiste des Belegs nach Zeit sortiert: submitted, network_retrying, delivered / rejected / undeliverable / failed, mls_received, fs_reported, fs_c5_verdict, content_wiped, webhook_delivered und weitere (unbekannte Typen ignorieren). Phase 1 wird aus den gespeicherten Fakten abgeleitet, kein Journal jeder Zwischenänderung.
Fehler: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-RES-001 (404: fremder oder empfangener Beleg)
/sapi/document/receive/{documentId}/eventsBearer (access)Zeitleiste eines empfangenen Belegs: received, acknowledged, fs_reported, fs_c5_verdict, content_wiped, Webhook-Zustellungen.
Massenversand
/sapi/document/batchBearer (access)Bis zu 100 Dokumente in einem Aufruf. Jedes Element durchläuft die vollständige Logik des Einzelversands (Idempotenz über itemId + idempotencyKey, Reservierung, Submit, Verdikt) und liefert ein eigenes Ergebnis; der Fehler eines Elements stoppt die übrigen nicht. Die Elemente werden sequenziell verarbeitet; failed-Elemente wiederholen Sie mit demselben idempotencyKey.
// Request
{ "documents": [ {
"itemId": "fa-2026-001",
"idempotencyKey": "fa-2026-001",
"metadata": { "documentId": "2026001", "documentTypeId": "…", "processId": "…",
"senderParticipantId": "0245:2121358349", "receiverParticipantId": "0245:1084695645" },
"payload": "<Invoice …>", "payloadFormat": "XML" } ] }
// 202 Accepted
{ "total": 2, "accepted": 1, "rejected": 1, "failed": 0,
"results": [
{ "itemId": "fa-2026-001", "ok": true, "providerDocumentId": "…", "status": "ACCEPTED" },
{ "itemId": "fa-2026-002", "ok": false, "errorCode": "SAPI-AUTH-003", "errorMessage": "…" } ] }Fehler: SAPI-AUTH-002 (401) · SAPI-AUTH-003 (403) · SAPI-VAL-001 (400: leere/zu große Liste)
Fehlermodell
Alle SAPI-Fehler haben einen einheitlichen Envelope mit Kategorie, stabilem Code, dem Flag retryable und einer correlation_id für den Support. Bei einem Anmeldefehler (SAPI-AUTH-001) enthält der Envelope zusätzlich hint (eine verständliche Erklärung, was in Client Id und Client Secret gehört) und docs (Link zur Anleitung; MK-soft-Programme direkt auf /navody/mksoft#prepojenie). Beide Felder sind optional und fehlen sonst (1.8.20).
{ "error": {
"category": "AUTH",
"code": "SAPI-AUTH-001",
"message": "Invalid client credentials.",
"retryable": false,
"correlation_id": "b4191dfc-…" } }Benachrichtigungen & Webhooks
Bei einer empfangenen Rechnung können wir die Firma per E-Mail oder per Webhook (POST an Ihre URL) benachrichtigen. Die Zustellung ist durable: Sie wird in eine Ausgangsqueue geschrieben und asynchron zugestellt (15 s Timeout); bei einem Fehlschlag wiederholen wir bis zu 12× mit exponentiellem Backoff (30 s → max. 8 h, insgesamt rund 16 Stunden), danach Dead-Letter. HTTP 401/403 bedeutet, dass Ihr Endpunkt eine Authentifizierung verlangt, die wir nicht mitsenden; prüfen Sie stattdessen die Signatur webhook-signature und antworten Sie mit 2xx. Ein Ausfall Ihres Servers verliert die Benachrichtigung also nicht, wir stellen sie beim nächsten Versuch zu. Der SSRF-Schutz blockiert Loopback-/lokale Adressen; die Webhook-URL muss öffentlich erreichbar sein.
/companies/{id}/notificationssession / tokenBenachrichtigungseinstellungen: { webhookUrl, notificationEmail, notificationEmails, hasSecret }.
/companies/{id}/notificationsowner / adminSetzt beide Kanäle (leerer String = hebt den jeweiligen Kanal auf).
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
webhookUrl | string | nein | leer oder http(s)-URL, max. 512 |
notificationEmail | string | nein | eine Adresse oder bis zu 5 durch Kommas getrennt, max. 256; jede erhält die E-Mails zu empfangenen Rechnungen (400 invalid_notification_email / too_many_notification_emails) |
/companies/{id}/webhooksession / tokenWebhook-Konfiguration: { url, hasSecret } (ohne Secret).
/companies/{id}/webhookowner / adminSetzt die Webhook-URL (generiert automatisch ein Signatur-Secret, falls noch keines existiert).
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
url | string | ja | http(s)-URL, max. 512 |
curl -X PUT https://peppol.verteco.digital/api/v1/companies/{id}/webhook \
-H 'Authorization: Bearer vpt_8f2a…' -H 'Content-Type: application/json' \
-d '{"url":"https://vas-system.sk/peppol/webhook"}'
# 200 OK { "url":"https://vas-system.sk/peppol/webhook", "hasSecret": true }/companies/{id}/webhookowner / adminEntfernt Webhook-URL und Secret. Gibt 204 zurück.
/companies/{id}/webhook/secretowner / adminGeneriert ein neues Signatur-Secret und gibt es EINMALIG zurück; speichern Sie es zur Prüfung von X-Verteco-Signature.
// 200 OK
{ "secret": "vpt_8f2a…" }/companies/{id}/webhook/testowner / adminSendet synchron eine Testbenachrichtigung (Event webhook.test, signiert, SSRF-geschützt) an die gespeicherte URL und gibt zurück, WAS gesendet wurde und WAS zurückkam. Dasselbe lösen Sie mit der Schaltfläche „Otestovať webhook“ (Webhook testen) in den Firmendetails aus.
// 200 OK
{
"sent": { "url": "https://vas-system.sk/peppol/webhook", "event": "webhook.test",
"signed": true, "payload": "{…}" },
"received": { "status": 200, "body": "OK", "durationMs": 142, "error": null }
}
// 400 webhook_not_configured, wenn keine Webhook-URL gespeichert istWebhook-Payload
Sowohl bei einer empfangenen (invoice.received) als auch bei einer gesendeten (invoice.sent) Rechnung senden wir einen POST mit diesem Body; das Feld event unterscheidet den Typ.
Zwei weitere Events melden das Urteil des Netzwerks zu einer Rechnung, die Sie gesendet haben: invoice.delivered (der Access Point des Empfängers hat die Zustellung mit einem Zustellnachweis (MLS) bestätigt) und invoice.rejected (abgelehnt, entweder durch das Netzwerk oder bereits bei der Validierung vor dem Versand); invoice.undeliverable meldet einen Empfänger ohne Eintrag im Peppol-Netz (übernommen, der FS gemeldet, nicht zugestellt). Sie tragen die Identifikation des Belegs und der Firma (documentId, invoiceNumber, receiverId, peppolMessageId, companyDic, peppolParticipantId) sowie status, statusDetail mit dem Ablehnungsgrund und statusDateTime. Ist der erste Zustellversuch fehlgeschlagen und wiederholt ihn der Access Point selbst (in der Regel innerhalb einer Stunde), bleibt das Dokument submitted und statusDetail beginnt mit network_retrying: ; eine Zustellung ergibt dann delivered, ein Aufgeben rejected mit dem Präfix network_gave_up: . Dank ihnen müssen Sie den Status gesendeter Rechnungen nicht per Polling abfragen.
Das Event company.activated kommt, wenn ein Kunde die Auswahl des Anbieters im FS-Portal (VPDS) der Finanzverwaltung der Slowakischen Republik (Finančná správa, FS) abschließt (Body: event, companyId, companyDic, peppolParticipantId, status, verifiedAt); company.deactivated dagegen bei der Abmeldung der Firma aus dem Netzwerk (gleicher Body ohne verifiedAt). company.smp_registered_elsewhere kommt, wenn eine Firma die FS-Auswahl abgeschlossen hat, ihr Eintrag im nationalen SMP aber von einem anderen Anbieter gehalten wird (Body wie company.activated plus action: "migration_code_required" und migrateUrl). Das Vorgehen für Partner steht in der Vermittler-Dokumentation. Bis der Kunde einen Migrationscode eingibt, stellt das Netzwerk an den alten Anbieter zu. Details in der Anleitung /saas:
{
"event": "invoice.received",
"eventId": "7f1c2d9e-4b1a-4e3d-9c1f-0a2b3c4d5e6f",
"occurredAt": "2026-09-03T15:04:05Z",
"companyId": "08dd…",
"documentId": "…",
"invoiceNumber": "2026001",
"senderId": "0088:7300010000001",
"supplierName": "Dodávateľ s.r.o.",
"receiverId": "0245:2121358349",
"issueDate": "2026-06-03",
"dueDate": "2026-06-17",
"deliveryDate": "2026-06-03",
"currency": "EUR",
"totalAmount": "120.00",
"peppolMessageId": "…",
"companyDic": "SK2121358349",
"peppolParticipantId": "0245:2121358349"
}Die Felder companyDic und peppolParticipantId identifizieren die Firma, auf die sich das Event bezieht (wichtig für Partner, die eine einzige Webhook-URL für alle ihre Kunden verwenden).
Urteil des Netzwerks zu einer gesendeten Rechnung:
{
"event": "invoice.delivered", // oder "invoice.rejected"
"occurredAt": "2026-09-03T15:04:05Z",
"companyId": "08dd…",
"companyDic": "SK2121358349",
"peppolParticipantId": "0245:2121358349",
"documentId": "…",
"invoiceNumber": "2026001",
"receiverId": "0245:2120049096",
"peppolMessageId": "…",
"status": "delivered", // oder "rejected"
"statusDetail": null, // bei rejected: Ablehnungsgrund
"statusDateTime": "2026-06-03T10:15:42Z"
}Aktivierung der Firma nach der Auswahl im FS-Portal (VPDS):
{
"event": "company.activated", // company.deactivated hat denselben Body ohne verifiedAt
"occurredAt": "2026-09-03T15:04:05Z",
"companyId": "08dd…",
"companyDic": "SK2121358349",
"peppolParticipantId": "0245:2121358349",
"status": "active",
"verifiedAt": "2026-06-03T10:02:11Z"
}Den Event-Namen trägt auch der Header X-Verteco-Event. Vollständige Liste der Events: invoice.received, invoice.sent, invoice.delivered, invoice.rejected, invoice.undeliverable, invoice.reported, invoice.report_pending, invoice.report_rejected, company.activated, company.deactivated, company.smp_registered_elsewhere sowie das Test-Event webhook.test. Einen unbekannten Event-Typ sollten Sie beiseitelegen und protokollieren; einen neuen Typ kündigen wir immer im Voraus an. Jedes Event trägt zusätzlich occurredAt (Ereigniszeit, ISO-8601 UTC) zum Sortieren sowie eventId (derselbe Wert wie im Header X-Verteco-Delivery-Id): eindeutig pro Event und bei jeder Wiederholung unverändert, also der richtige Schlüssel zum Deduplizieren (peppolMessageId wiederholt sich über invoice.sent, invoice.delivered und invoice.reported). invoice.*-Events tragen zusätzlich die Zeiten sentAt, deliveredAt, receivedAt und fsReportedAt (ISO-8601 UTC, null, bis das Ereignis eingetreten ist). invoice.reported kommt, wenn die Steuermeldung an die Finanzverwaltung (TDD) zum Beleg dem Zustellnetz übergeben wurde (§ 85o Abs. 11), bei einem Ausfall des C5 auch Tage später. Formale Schemata aller Events stehen im Abschnitt webhooks der OpenAPI-Spezifikation.
Signaturprüfung
Hat die Firma ein Secret, senden wir den Header X-Verteco-Signature in der Form sha256=HMAC-SHA256(secret, raw Body) (lowercase hex). Berechnen Sie den HMAC immer über die exakten Bytes des Bodys:
import crypto from 'node:crypto';
// rawBody = die exakten Bytes des Request-Bodys (kein erneut serialisiertes JSON)
function verify(rawBody, header, secret) {
const expected = 'sha256=' +
crypto.createHmac('sha256', secret).update(rawBody).digest('hex');
return crypto.timingSafeEqual(Buffer.from(header), Buffer.from(expected));
}Header jeder Zustellung: X-Verteco-Event (Event-Name), X-Verteco-Delivery-Id (= eventId im Body, bei jeder Wiederholung identisch), X-Verteco-Signature (der HMAC oben) und parallel die Standard-Webhooks-Header: webhook-id (= eventId), webhook-timestamp (Unix-Sekunden dieses Versuchs) und webhook-signature = v1,base64(HMAC-SHA256(secret, id + "." + timestamp + "." + body)). Schlüssel sind die UTF-8-Bytes Ihres Secrets; eine standardwebhooks-Bibliothek erwartet es als whsec_ + base64(secret). Empfohlene Verarbeitung: Signatur prüfen, Zustellungen mit einem webhook-timestamp älter als 5 Minuten ablehnen (Replay-Schutz), idempotent nach eventId verarbeiten, innerhalb von 15 Sekunden mit 2xx antworten und schwere Arbeit in die eigene Queue verlagern. Eine fehlgeschlagene Zustellung wiederholen wir 12-mal im Abstand von 30 s bis 8 h (insgesamt rund 16 Stunden); danach landet sie im Dead-Letter mit E-Mail-Hinweis und bleibt im Realtime-Log sichtbar. Eine produktive Webhook-URL muss https:// sein; die Testumgebung akzeptiert auch http://.
POST /companies/{id}/webhook/secret; es wird einmalig zurückgegeben (eine Rotation erzeugt ein neues). Ohne Secret senden wir den Header X-Verteco-Signature nicht.Massenkonfiguration: ein Token, mehrere Firmen
Ein einziger API-Token (an Ihr Konto/Ihre E-Mail gebunden) verwaltet alle Firmen, die dieses Konto besitzt: Wer eine Firma über POST /companies anlegt, wird deren owner und kann ihren Webhook einrichten. Der Webhook gilt pro Firma (eigene URL und eigenes Secret), sodass Sie mit demselben Token beliebig viele Firmen anbinden:
# 1) Liste Ihrer Firmen (seitenweise, siehe Firmen)
curl 'https://peppol.verteco.digital/api/v1/companies?page=0&limit=100' -H 'Authorization: Bearer vpt_8f2a…'
# 2) für JEDE Firma {id}: Webhook (und/oder E-Mail) setzen
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://vas-system.sk/peppol/webhook","notificationEmail":"faktury@firma.sk"}'
# 3) Signatur-Secret abholen (wird NUR EINMAL zurückgegeben) und für die Signaturprüfung speichern
curl -X POST https://peppol.verteco.digital/api/v1/companies/{id}/webhook/secret -H 'Authorization: Bearer vpt_8f2a…'
# → { "secret": "…" }- Der Token muss
owner/adminder jeweiligen Firma sein; bei einer Firma, in der er nur member/viewer ist, kommt403 forbiddenzurück (kein Cross-Tenant-Zugriff). - Sie können jeder Firma eine andere URL geben oder allen dieselbe; im Payload unterscheiden Sie sie anhand von
companyId(undreceiverId). - Bei Hunderten von Firmen beachten Sie das Rate-Limit pro Token (den aktuellen Wert liefert der Header
RateLimit-Limit); arbeiten Sie in Batches mit Backoff bei429(HeaderRetry-After). - Der Webhook wird erst dann tatsächlich ausgelöst, wenn die Firma in Peppol aktiv ist (nach der Auswahl von Verteco als Anbieter bei der Finanzverwaltung) und somit tatsächlich Belege empfängt.
Datenmodelle
Felder der von der API zurückgegebenen Objekte.
Company
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
id | UUID | – | Kennung der Firma |
ico | string | – | Handelsregisternummer (IČO, 8 Ziffern) |
dic | string|null | – | USt-IdNr. (IČ DPH) |
legalName | string | – | Firmenname |
registeredAddress | string|null | – | Sitz |
peppolParticipantId | string|null | – | Teilnehmer im Peppol-Netzwerk (nach der Registrierung) |
status | string | – | pending_verification | active |
role | string | – | owner | admin | member | viewer (Ihre Rolle) |
createdAt | Instant | – | Zeitpunkt der Erstellung |
Document
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
id | UUID | – | Kennung des Belegs |
direction | string | – | sent | received |
peppolMessageId | string|null | – | ID der Peppol-Nachricht |
docTypeId | string|null | – | Dokumenttyp (Peppol) |
senderId | string|null | – | Absender (scheme:id) |
receiverId | string|null | – | Empfänger (scheme:id) |
invoiceNumber | string|null | – | Rechnungsnummer |
issueDate | date|null | – | Ausstellungsdatum |
currency | string|null | – | Währung (z. B. EUR) |
totalAmount | number|null | – | Betrag |
status | string | – | Verarbeitungsstatus |
createdAt | Instant | – | Zeitpunkt der Erfassung |
User · Token · Webhook
| Feld | Typ | Pflicht | Beschreibung |
|---|---|---|---|
User | Objekt | – | { id: UUID, email: string } |
Token | Objekt | – | { id, name, prefix, lastUsedAt|null, createdAt } |
Webhook | Objekt | – | { url: string|null, hasSecret: boolean } |
Die Felder werden direkt aus der veröffentlichten openapi.json geladen, die Tabellen sind also immer identisch mit dem, was die API liefert. Beschreibungen auf Englisch.
Datenmodelle werden aus openapi.json geladen…
Glossar
- DIČ
- Slowakische Steueridentifikationsnummer (10 Ziffern). Die slowakische Peppol-ID ist 0245: + die DIČ-Ziffern, ohne SK.
- IČ DPH
- Umsatzsteuer-Identifikationsnummer (SK + DIČ). Nur Umsatzsteuerzahler haben sie; ein Nichtzahler stellt mit Steuerkategorie O aus.
- IČO
- Unternehmensregisternummer (8 Ziffern). Feld ico in der API, BT-30 in UBL.
- Verifikationstoken (VÚ)
- Signatur der Finanzverwaltung, die bei der Anbieterwahl im FS-Portal entsteht; sie schaltet den Versand für die Firma frei.
- VPDS
- Die FS-Anwendung, in der ein Steuerpflichtiger seinen Zustelldienstleister (uns) wählt.
- TDD
- Tax Data Document, die Rechnungsmeldung an die Finanzverwaltung; wir erstellen und senden sie für Sie.
- C5 / C6
- Fünfte und sechste Ecke des Peppol-Modells: der Zugangspunkt der Finanzverwaltung, der TDDs empfängt (0242:001180).
- MLS
- Message Level Status, die Empfangsbestätigung des Zugangspunkts des Empfängers (AP = angenommen, RE = abgelehnt, AB = bestätigt).
- SBDH
- Standard Business Document Header, der Umschlag, in dem ein Beleg reist; sein InstanceIdentifier ist die peppolMessageId.
- SML / SMP
- Das Netzverzeichnis: SML findet das SMP des Empfängers, das SMP nennt Zugangspunkt und akzeptierte Belegtypen.
Slowakische Konventionen aus der Praxis der Implementierer
Über Peppol BIS Billing 3.0 hinaus einigen sich die slowakischen Hersteller von ERP- und Fakturierungssystemen laufend auf eine gemeinsame Interpretation optionaler Felder (die Diskussion läuft im Slack-Kanal der Finanzverwaltung der Slowakischen Republik, Finančná správa, FS). Nachfolgend die Konventionen, die unser Portal bereits heute berücksichtigt: Alles sind gültige BIS-Konstrukte, sie passieren unsere API unverändert, und empfangene Belege zeigen sie auch in der menschenlesbaren Vorschau und im PDF an.
- Abzug einer versteuerten Anzahlung auf Positionsebene: eine negative Position mit
cac:DocumentReference, wobeicbc:IDdie Nummer des Steuerbelegs zur erhaltenen Zahlung trägt undcbc:DocumentTypeCodeden Wert130hat (BIS: invoice line object identifier, max. 1 pro Position). Eine empfangene Rechnung mit einer solchen Position wird in unserer Vorschau mit dem Hinweis „odpočet zálohy – daňový doklad č. …" (Abzug der Anzahlung, Steuerbeleg Nr. …) angezeigt. - Steuerbeleg zur erhaltenen Zahlung: gemäß den FAQ der Finanzverwaltung wird
InvoiceTypeCode 388(Tax invoice) verwendet. Er passiert sowohl unsere API als auch die Validierung; der Abzug einer nicht bezahlten (nicht versteuerten) Anzahlung wird übercbc:PrepaidAmountausgedrückt. - Stornierung einer Rechnung: Gutschrift
381(CreditNote) mitcac:BillingReferenceauf die ursprüngliche Rechnung, keine negative Rechnung 380. Achtung: Den Code 384 lehnt das Netzwerk für slowakische Parteien ab (die Regel PEPPOL-EN16931-P0112 erlaubt ihn nur zwischen deutschen Subjekten); für eine Korrektur nach oben dient die Belastungsanzeige 383. - BT-83 PaymentID: in der slowakischen Praxis setzt sich für die Zahlerreferenz das Format
/VS…/SS…/KS…durch; das variable Symbol allein ist ebenfalls üblich. Unsere Verarbeitung überträgt den Wert unverändert und zeigt ihn bei den Zahlungsangaben an. - Zusätzliche Positionsangaben (Chargen, Seriennummern, Verfallsdaten) über
cac:AdditionalItemPropertymit etablierten Bezeichnungen wieBatchNumber,SerialNumber,ExpirationDate.
Anlagen zu Belegen (BT-125)
An eine E-Rechnung können Anlagen (PDF, Bilder) als base64 im Element cac:AdditionalDocumentReference (BT-125) angehängt werden. Bei empfangenen Belegen verarbeiten wir Anlagen bis 25 MB je Anlage; beim Senden muss das gesamte XML einschließlich Base64-Anlagen unter 10 MB über SAPI-SK und unter 2 MB über den Portal-Reiter Odoslať súborom bleiben. Peppol legt kein einheitliches netzwerkweites Limit fest, die einzelnen Anbieter bestimmen es selbst (FS FAQ 9/DPH/2025/IM, Beispiel Nr. 67); prüfen Sie daher bei sehr großen Anlagen auch das Limit des Anbieters der Gegenseite.
Öffentliche Werkzeuge (Validierung, Empfängerprüfung)
Zwei Hilfs-Endpoints ohne Authentifizierung: derselbe Validierungskern und derselbe SML-Lookup, die auch unser Access Point verwendet. Sie eignen sich für CI ebenso wie für Prüfungen vor dem Versand; für sie gilt ein strengeres öffentliches Rate Limit.
/public/peppol-validateöffentlichValidierung einer E-Rechnung gegen das UBL-2.1-Schema, EN 16931 und Peppol BIS Billing 3.0, dasselbe wie der UI-Validator unter /validator. Request-Body = direkt das UBL 2.1 XML (Invoice / CreditNote, ggf. das gesamte Peppol SBD), Content-Type application/xml, Limit 3 MB.
curl -X POST https://peppol.verteco.digital/api/v1/public/peppol-validate \
-H "Content-Type: application/xml" \
--data-binary @faktura.xml// 200 OK
{
"valid": false,
"errors": [
"BR-CO-09: [BR-CO-09]-The Seller VAT identifier (BT-31) … shall have a prefix in accordance with ISO code…"
],
"warnings": []
}
// 400 = leerer Body (empty_document) oder Dokument über 3 MB (document_too_large)/public/peppol-check?id=0245:2121358349öffentlichPrüfung des Empfängers im produktiven Peppol-Netzwerk (SML-Lookup): Ist er registriert, und welche Belegtypen kann er empfangen? Der Parameter id akzeptiert eine Peppol ID (0245:…), eine USt-IdNr. (IČ DPH, SK…) sowie die reine DIČ (slowakische Steuernummer). Die Bezeichnungen in capabilities werden auf Slowakisch zurückgegeben. Authentifiziertes Gegenstück für ERP-Pipelines: GET /sapi/discovery.
// 200 OK
{
"registered": true,
"participantId": "0245:2121358349",
"smp": "sml.peppol-smp.sk",
"capabilities": ["Faktúra (BIS Billing)", "Dobropis", "Self-billing", "MLS doručenky"],
"lastCheckedAt": "2026-08-31T…Z"
}MCP-Server (KI-Assistenten)
Das Portal betreibt einen eigenen Server für das Model Context Protocol, den offenen Standard, über den KI-Assistenten (Claude Code, Claude Desktop, Cursor, VS Code Copilot und andere) externe Systeme anbinden. Der Assistent meldet sich mit einem gewöhnlichen API-Schlüssel des Kontos an und erhält sechs Werkzeuge; er sieht nie mehr als dieses Konto, und jeder Aufruf erscheint im API-Log des Schlüssels.
Adresse: https://peppol.verteco.digital/api/mcp. Transport: Streamable HTTP, JSON-RPC 2.0, zustandslos (POST /api/mcp, kein SSE-Stream, GET antwortet 405). Anmeldung mit dem Header Authorization: Bearer <API-Schlüssel>. Unterstützte Methoden: initialize, ping, tools/list, tools/call, resources/list, prompts/list.
Werkzeuge
list_companies: Firmen des Kontos mit Peppol-ID, Status und Rolle (Beginn jedes Gesprächs)list_documents: gesendete/empfangene Rechnungen einer Firma mit Zustell- und Meldestatus, seitenweiseget_document: eine Rechnung im Detail samt MLS-Quittung und Meldung, optional das UBL-XML (bis 1 MB)check_participant: Live-Prüfung des Empfängers im Peppol-Netz (SML)validate_document: UBL-Validierung gegen EN 16931 + Peppol BIS 3.0send_document: Versand einer Rechnung im Namen der Firma, erfordert confirm = true, die Versandfreigabe (Verifikačný údaj) gilt
Anbindung in Claude Code
claude mcp add --transport http verteco-peppol https://peppol.verteco.digital/api/mcp \
--header "Authorization: Bearer vpt_..."Claude Desktop (über die Brücke mcp-remote, benötigt Node.js)
{
"mcpServers": {
"verteco-peppol": {
"command": "npx",
"args": ["-y", "mcp-remote", "https://peppol.verteco.digital/api/mcp", "--header", "Authorization: Bearer vpt_..."]
}
}
}Der Versand einer Rechnung ist rechtlich bindend: Das Werkzeug lehnt einen Aufruf ohne confirm = true ab, und die Serveranweisungen verpflichten den Assistenten, die ausdrückliche Zustimmung des Nutzers zur konkreten Rechnung und zum Empfänger einzuholen. Fertige Konfigurationen für Cursor und VS Code sowie eine Schaltfläche zum Erstellen des Schlüssels finden Sie im Portal: API-Schlüssel → Reiter MCP-Server. API-Schlüssel → MCP-Server
Versand per E-Mail (Adresse des Unternehmens)
Im Portal aktiviert ein Unternehmen seine eigene Adresse <24 zufällige Zeichen>@peppol.send.verteco.app. Eine E-Mail mit UBL-XML-Anhang, die aus einem freigegebenen Postfach an diese Adresse geht, versenden wir über das Peppol-Netz genau so, als wäre die Datei auf dem Reiter Per Datei senden hochgeladen worden; der Absender erhält eine Antwort mit dem Ergebnis je Anhang, und der Beleg steht mit Zustellstatus, MLS-Empfangsbestätigung und FS-Meldung im Portal und in der API. Einrichtung: Anbindungen und Integrationen → Versand per E-Mail (Eigentümer oder Administrator des Unternehmens, angemeldet). /dashboard/integrations/email
Verarbeitungsregeln
- Angenommen wird nur Post von einer Adresse auf der Freigabeliste des Unternehmens (höchstens 20); alles andere wird ohne Antwort verworfen.
- Standardmäßig muss die Absenderdomain beim zustellenden Server SPF oder DKIM bestehen (Angleichung wie bei DMARC, relaxed). Der zustellende Server weist zusätzlich Post ab, die weder SPF noch DKIM besteht, sowie Post gegen die DMARC-Richtlinie des Absenders. Die Prüfung lässt sich in den Einstellungen abschalten; nicht empfohlen.
- Anhang: UBL 2.1 Invoice oder CreditNote (Peppol BIS Billing 3.0), Endung .xml, optional in einer SBDH-Hülle; höchstens 10 Anhänge pro Nachricht, 15 MB pro Anhang, 200 Nachrichten pro Adresse und Tag. PDF und Nachrichtentext werden nicht verarbeitet.
- IFS Finvoice 2.0: ein .xml-Anhang mit IFS-SOAP-Hülle (
IFSFinvoice) oder ein reines Finvoice wird in UBL umgewandelt und dann gleich verarbeitet. Umwandlungsregeln:INV02oder negative Summe = Gutschrift (381) mit positiven Beträgen und Verweis auf die Ursprungsrechnung (OriginalInvoiceNumber, bei IFSOrderIdentifier); Verkäufer und Käufer nach slowakischer USt-IdNr. (SellerOrganisationTaxCode,BuyerOrganisationTaxCode→0245:DIČ), ein Käufer außerhalb der Slowakei wird nicht umgewandelt; MwSt.-Aufschlüsselung ausVatSpecificationDetails, 0-%-Zeilen als Kategorie E mit Begründung ausVatFreeText, sonst „Oslobodené od DPH“; IFS-Rundungszeilen (Netto 0,00, MwSt. 0,01) entfallen, ein Einzelpreis, der nicht zur Zeilensumme passt, wird neu berechnet; Einheiten nach UN/ECE (kg → KGM, pcs → H87, h → HUR, unbekannt → C62 mit Originaltext in der Zeilennotiz); das eingebettete Rechnungsbild (InvoiceAttachments, PDF) wird bis 5 MB als Anhang mitgeführt; nur EUR. Das Ergebnis der Umwandlung steht in der Antwort und im Firmenprotokoll. - Ergebnisadresse: sendet ein Systempostfach die Rechnungen, wählen Sie in den Einstellungen eine andere Adresse für die Antwort mit dem Ergebnis (
replyToinPUT /companies/{id}/email-send, leer = dem Absender antworten). - Der Verkäufer im XML (EndpointID des Lieferanten, BT-34) muss dieses Unternehmen sein, sonst wird die Nachricht abgelehnt (eine weitergeleitete Rechnung Ihres eigenen Lieferanten wird nie als Ihre versendet). Der Käufer braucht eine EndpointID mit Schema (BT-49).
- Dieselbe Nachricht (Message-ID) wird einmal verarbeitet. Der Beleg trägt in API und Webhooks
origin = email, Akteur = Absenderadresse.
Status (ping)
Öffentlicher Health-Check-Endpoint, geeignet für das Monitoring.
/pingöffentlichStatus des Backends.
// 200 OK
{ "service": "peppol-portal-backend", "status": "ok", "timestamp": "2026-06-17T…Z" }Eine Live-Übersicht aller Komponenten finden Sie auf der Systemstatus-Seite.
Was fertig ist und was kommt
Bereits in Produktion (oft fälschlich als fehlend angenommen)
- POST /companies/{id}/documents/send ist eine stabile Portalschnittstelle; für ERP-Integrationen bleibt SAPI-SK mit Idempotency-Key die Empfehlung.
- Die SMP-Registrierung erfolgt automatisch nach der Wahl im FS-Portal; Wechsel von einem anderen Anbieter über POST /companies/{id}/smp-migrate mit Migrationscode.
- MLS-Empfangsbestätigungen, Zustellnachweise und FS-Meldungen (fsReport) in jeder Zeile von /sapi/document/sent; Webhook-Replay für ein Zeitfenster.
- Auf Firmen beschränkte Schlüssel; MCP-Server für KI-Assistenten; UBL-Muster auf /vzory; öffentlicher Validator.
In Vorbereitung (Reihenfolge nach Nachfrage der Integratoren)
- Asynchroner Batch: POST /sapi/document/batch antwortet 202 mit Job-Link und Status je Position.
- Änderungsfeed GET /sapi/document/changes?since&cursor mit Cursor statt Offset-Paging.
- Ablauf und Rotation von API-Schlüsseln im Portal, Nur-Lese-Schlüssel.
- Mehrere Webhook-Endpunkte je Firma mit Ereignisfilter.