Validator API
Validiere E-Rechnungen gegen offizielle KoSIT-Schemas und Schematron-Regeln. Erhalte detaillierte Fehlermeldungen mit Korrekturvorschlägen.
/api/v1/invoice/{countryCode}/validateValidierung läuft nur mit gültigem Bearer-Key. Ohne Key antwortet der Endpoint mit 401.
Vor dem Versand prüfen
Finde Formatfehler, bevor die Rechnung beim Empfänger liegt — mit Fehlermeldung und Korrekturhinweis.
KoSIT-konform
Offizielle Schematron-Regeln der KoSIT (Koordinierungsstelle für IT-Standards)
37 Länder
Unterstützung für AE, AT, AU, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GR, HR, HU, IE, IS, IT, JP, LI, LT, LU, LV, MT, NL, NO, NZ, OM, PL, PT, RO, SE, SI, SK
Alle Formate
XRechnung, ZUGFeRD, Factur-X, Peppol UBL sowie nationale Formate (FatturaPA, ebInterface, Facturae, ISDOC, NAV, myDATA, KSeF FA(3), eFactura/CIUS-RO, CIUS-PT, QR-Bill) werden unterstützt — die vollständige Tabelle steht weiter unten.
Beispiel
1curl -X POST 'https://service.invoice-api.xhub.io/api/v1/invoice/de/validate' \2 -H 'Authorization: Bearer sk_test_xxx' \3 -H 'Content-Type: application/json' \4 -d '{5 "invoice": {6 "invoiceNumber": "RE-2026-001",7 "type": "invoice",8 "issueDate": "2026-01-15",9 "dueDate": "2026-02-15",10 "currency": "EUR",11 "seller": {12 "name": "Meine Firma GmbH",13 "street": "Musterstraße 1",14 "city": "Berlin",15 "postalCode": "10115",16 "countryCode": "DE",17 "vatId": "DE123456789"18 },19 "buyer": {20 "name": "Kunde AG",21 "street": "Kundenweg 42",22 "city": "München",23 "postalCode": "80331",24 "countryCode": "DE",25 "vatId": "DE987654321"26 },27 "items": [{28 "position": 1,29 "description": "Beratung",30 "quantity": 10,31 "unit": "HUR",32 "unitPrice": 150.00,33 "taxRate": 19,34 "netAmount": 1500.00,35 "taxAmount": 285.00,36 "grossAmount": 1785.0037 }],38 "subtotal": 1500.00,39 "total": 1785.00,40 "taxSummary": [{ "taxRate": 19, "netAmount": 1500.00, "taxAmount": 285.00 }],41 "paymentTerms": { "dueDays": 30 }42 }43 }'Ein Format gezielt prüfen
/api/v1/invoice/{countryCode}/{format}/validateNeben der Länder-Route gibt es eine Route je Format. Sie erzeugt die Rechnung genau in diesem Format und schickt das Ergebnis durch dessen XSD und Schematron — statt durch die aller Formate des Landes.
Länder-Route
/api/v1/invoice/{countryCode}/validatePrüft alle Formate des Landes und zusätzlich die fachlichen Landesregeln. Für DE ergibt die Rechnung oben elf Einträge in results[] — XRechnung und zehn ZUGFeRD-Profile — und in errors[] die Codes DE_REF_002 und DE_SELLER_CONTACT_001 (gemessen am 2026-09-15).
Format-Route
/api/v1/invoice/{countryCode}/{format}/validatePrüft genau ein Format. Bei ZUGFeRD und Factur-X wird jedes Profil erzeugt und geprüft, deshalb stehen dort mehrere Einträge in results[]. Die fachlichen Landesregeln laufen hier nicht mit: valid bezieht sich allein auf das erzeugte XML.
Pfadparameter format
Die Spec kennt diese Werte, immer klein geschrieben:
ebinterfaceebInterfacefacturaeFacturaefacturxFactur-XfatturapaFatturaPAhr-fiskHR-FISKisdocISDOCksefKSeFmydatamyDATAnavNAVpdfPDFpeppol-ublPeppol UBLqr-billQR-BillublUBLxrechnungXRechnungzugferdZUGFeRDWelche davon ein Land wirklich als prüfbares XML-Format führt, hängt vom Land ab — die Liste je Land liefert der formats-Endpoint. Ein Wert, den das Land nicht führt, wird mit 400 abgewiesen: /de/pdf/validate antwortet mit „Format 'pdf' is not a validatable XML format for country DE“ (gemessen am 2026-09-15).
Request
1curl -X POST 'https://service.invoice-api.xhub.io/api/v1/invoice/de/zugferd/validate' \2 -H 'Authorization: Bearer sk_test_xxx' \3 -H 'Content-Type: application/json' \4 -d '{5 "invoice": {6 "invoiceNumber": "RE-2026-001",7 "type": "invoice",8 "issueDate": "2026-01-15",9 "dueDate": "2026-02-15",10 "currency": "EUR",11 "seller": {12 "name": "Meine Firma GmbH",13 "street": "Musterstraße 1",14 "city": "Berlin",15 "postalCode": "10115",16 "countryCode": "DE",17 "vatId": "DE123456789"18 },19 "buyer": {20 "name": "Kunde AG",21 "street": "Kundenweg 42",22 "city": "München",23 "postalCode": "80331",24 "countryCode": "DE",25 "vatId": "DE987654321"26 },27 "items": [{28 "position": 1,29 "description": "Beratung",30 "quantity": 10,31 "unit": "HUR",32 "unitPrice": 150.00,33 "taxRate": 19,34 "netAmount": 1500.00,35 "taxAmount": 285.00,36 "grossAmount": 1785.0037 }],38 "subtotal": 1500.00,39 "total": 1785.00,40 "taxSummary": [{ "taxRate": 19, "netAmount": 1500.00, "taxAmount": 285.00 }],41 "paymentTerms": { "dueDays": 30 }42 }43 }'Antwort
Dieselbe Rechnung wie oben, an /de/zugferd/validate geschickt — die Antwort des Dienstes vom 2026-09-15, unverändert:
1{2 "valid": true,3 "results": [4 { "format": "zugferd-2.4-minimum", "valid": true, "errors": [] },5 { "format": "zugferd-2.4-en16931", "valid": true, "errors": [] },6 { "format": "zugferd-2.4-basic", "valid": true, "errors": [] },7 { "format": "zugferd-2.4-basic-wl", "valid": true, "errors": [] },8 { "format": "zugferd-2.4-extended", "valid": true, "errors": [] },9 { "format": "zugferd-2.5-minimum", "valid": true, "errors": [] },10 { "format": "zugferd-2.5-en16931", "valid": true, "errors": [] },11 { "format": "zugferd-2.5-basic", "valid": true, "errors": [] },12 { "format": "zugferd-2.5-basic-wl", "valid": true, "errors": [] },13 { "format": "zugferd-2.5-extended", "valid": true, "errors": [] }14 ]15}An /de/xrechnung/validate ergibt dieselbe Rechnung valid: false, einen Eintrag in results[] (xrechnung-3.0.2-ubl) und die Regelcodes PEPPOL-EN16931-R020, BR-DE-1, BR-DE-6, BR-DE-7 und BR-DE-15. Jeder Eintrag trägt dort location (XPath) und severity; dieselben Funde stehen zusätzlich flach in errors[].
Auth und Kontingent wie bei der Länder-Route: ein Bearer-Key ist Pflicht (ohne ihn 401), und der Aufruf ist an das Monatskontingent des Schlüssels gebunden — ist es erschöpft, antwortet auch diese Route mit 429. Plane sie wie einen Erzeugungsaufruf ein: die Prüfung erzeugt den Beleg intern.
Unterstützte Länder
Der Ländercode wird als Teil der URL angegeben: /api/v1/invoice/{countryCode}/validate
DEDeutschland
ATÖsterreich
CHSchweiz
FRFrankreich
ITItalien
ESSpanien
NLNiederlande
BEBelgien
PLPolen
PTPortugal
AEVereinigte Arabische Emirate
AUAustralien
BGBulgarien
CYZypern
CZTschechien
DKDänemark
EEEstland
FIFinnland
GBGroßbritannien
GRGriechenland
HRKroatien
HUUngarn
IEIrland
ISIsland
JPJapan
LILiechtenstein
LTLitauen
LULuxemburg
LVLettland
MTMalta
NONorwegen
NZNeuseeland
OMOman
RORumänien
SESchweden
SISlowenien
SKSlowakei
= Verfügbar
Deutschland
/api/v1/invoice/de/validateÖsterreich
/api/v1/invoice/at/validateFrankreich
/api/v1/invoice/fr/validateItalien
/api/v1/invoice/it/validateSchweiz
/api/v1/invoice/ch/validateSpanien
/api/v1/invoice/es/validateRequest Parameter
Path Parameter
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
countryCode | string | ISO 3166-1 alpha-2 Ländercode. Verfügbar (37): AE, AT, AU, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GR, HR, HU, IE, IS, IT, JP, LI, LT, LU, LV, MT, NL, NO, NZ, OM, PL, PT, RO, SE, SI, SK. |
Headers & Body
| Parameter | Typ | Pflicht | Beschreibung |
|---|---|---|---|
Authorization | header | Bearer Token mit sk_test_* oder sk_live_* API Key | |
Content-Type | header | application/json | |
invoice | object (body) | Das zu validierende invoice-Objekt (JSON). Der Endpoint nimmt ausschließlich einen JSON-Body mit dem Feld invoice entgegen — kein Roh-XML, kein Datei-Upload. |
Authentifizierung
Verwende deinen API Key im Authorization-Header: für Testumgebung oder für Produktion.Bearer sk_test_... / Bearer sk_live_...
Response
Gültige Rechnung
200 OK1{2 "valid": true,3 "errors": [],4 "warnings": []5}Ungültige Rechnung
200 OK1{2 "valid": false,3 "errors": [4 {5 "code": "BR-DE-1",6 "message": "Eine Rechnung (INVOICE) muss Angaben zu "PAYMENT INSTRUCTIONS" (BG-16) enthalten.",7 "field": "/Invoice/cac:PaymentMeans"8 },9 {10 "code": "BR-DE-15",11 "message": "Das Element "Buyer reference" (BT-10) muss übermittelt werden.",12 "field": "/Invoice/cbc:BuyerReference"13 }14 ],15 "warnings": [16 {17 "code": "MISSING_OPTIONAL",18 "message": "Delivery date is recommended",19 "field": "deliveryDate"20 }21 ]22}Error Responses
1{2 "error": "Bad Request",3 "message": "Invoice data is required"4}1{2 "error": "UNAUTHORIZED",3 "message": "Invalid or missing API key"4}1{2 "error": "INTERNAL_ERROR",3 "message": "An unexpected error occurred"4}Response-Felder
valid
true / false
errors
Array von Fehlern. Jeder Fehler enthält code, message und optional field.
warnings
Array von Warnungen. Gleiches Schema wie Fehler, aber keine kritischen Probleme.
Schema für Errors/Warnings
| Feld | Typ | Beschreibung |
|---|---|---|
code | string | Fehlercode (z.B. BR-DE-01, BR-16) |
message | string | Lesbare Fehlerbeschreibung |
field | string (optional) | XPath oder Feldname, wo der Fehler aufgetreten ist |
Unterstützte Formate
| Format | Schema | Validierung |
|---|---|---|
| XRechnung 3.0.2 | EN16931 CII/UBL | KoSIT 3.0.2 Schematron |
| XRechnung 3.0 | EN16931 CII/UBL | KoSIT 3.0 Schematron |
| ZUGFeRD 2.5 | EN16931 CII | EN16931 Schematron |
| ZUGFeRD 2.4 | EN16931 CII | EN16931 Schematron |
| ZUGFeRD 2.3 | EN16931 CII | EN16931 Schematron |
| Factur-X 1.09 | EN16931 CII | EN16931 Schematron |
| Factur-X 1.08 | EN16931 CII | EN16931 Schematron |
| Factur-X 1.0 | EN16931 CII | EN16931 Schematron |
| UBL (Peppol BIS 3.0) | EN16931 UBL | Peppol BIS 3.0 / EN16931 |
| ebInterface | ebInterface XSD (AT) | ebInterface |
| FatturaPA 1.2.3 | FatturaPA XSD (IT) | SDI-Schema |
| Facturae | Facturae XSD (ES) | Facturae XSD |
| ISDOC | ISDOC XSD (CZ) | ISDOC XSD |
| NAV | NAV XSD (HU) | NAV-Online XSD |
| myDATA | myDATA XSD (GR) | myDATA XSD |
| KSeF FA(3) | KSeF UBL-Slot (PL) | KSeF FA(3) XSD |
| eFactura (CIUS-RO) | EN16931 UBL | CIUS-RO |
| CIUS-PT | EN16931 UBL | CIUS-PT |
| QR-Bill | Swiss QR-Bill (CH/LI) | QR-Bill Spezifikation |
Häufige Validierungsfehler
BR-DE-1Zahlungsangaben fehlen: Eine Rechnung muss Angaben zur Zahlung (BG-16) enthalten
Lösung: Setze paymentMethods (z. B. bank_transfer) und dazu seller.bankAccount mit IBAN
BR-DE-15Käuferreferenz fehlt: Das Element Buyer reference (BT-10) muss übermittelt werden
Lösung: Setze countrySpecific.buyerReference — bei öffentlichen Auftraggebern die Leitweg-ID in countrySpecific.leitwegId
BR-DE-17Unzulässiger Rechnungstyp: Der Rechnungstyp-Code (BT-3) muss 326, 380, 384, 389, 381, 875, 876 oder 877 sein
Lösung: Setze invoice.type auf einen zulässigen Wert (invoice = 380); proforma ist in XRechnung nicht erlaubt
BR-16Keine Rechnungsposition: Eine Rechnung muss mindestens eine Position (BG-25) enthalten
Lösung: Füge mindestens einen Eintrag in items hinzu
BR-CO-10Summe der Positionsnettobeträge ungleich Rechnungsnetto
Lösung: Prüfe die Summe aller items[].quantity * items[].unitPrice
Vollständige Fehlerliste: Error Handling Dokumentation
Für die Zahl der Rechnungspositionen gilt auf beiden Prüf-Routen dieselbe tarifabhängige Grenze wie beim Erzeugen — darüber antwortet die API mit HTTP 400 und TOO_MANY_LINE_ITEMS: Grenzen in der Creator-API
Validierung und dein Kontingent
Der Validierungsaufruf wird deinem monatlichen Kontingent nicht angerechnet — er ist aber daran gebunden: Ist das Kontingent aufgebraucht, antwortet auch die Validierung mit 429. Plane das ein, wenn du in CI/CD-Pipelines oder automatischen Tests validierst.
Validierung im Playground
Im Playground kannst du die Validierung ohne eigenen API-Key ausprobieren — die Anfrage läuft dort über unseren Schlüssel und ist pro IP begrenzt. Der Endpoint selbst verlangt immer einen Bearer-Key.
Zum Playground →