POST /v1/validate
Validate an e-invoice document — EN 16931 / CIUS Schematron for UBL and CII, Italy FatturaPA XSD-only for invoice XML, or Italy SDI file messaggio XSD-only when applicable.
Upload an invoice file (XML or PDF) and receive a validation result.
For UBL and CII documents in the EN 16931 family, checks include:
- XML structure (XSD)
- EN 16931 business rules (Schematron)
- Country- or network-specific rules when applicable — XRechnung for Germany, Peppol BIS Billing 3.0 for cross-border / Peppol Network invoices
For Italy FatturaPA XML (Agenzia namespaces: FatturaElettronica / FatturaElettronicaSemplificata), Beliq validates against the published W3C XML Schema graph bundled in the engine. That path is XSD only (no EN 16931 Schematron; no BR-* rule IDs). Additional normative constraints from the Italian technical specification (tables / regole) are not implemented as code in this release.
For Italy SDI file messaggio XML (namespace http://www.fatturapa.gov.it/sdi/messaggi/v1.0, roots such as NotificaScarto, RicevutaConsegna, … per MessaggiTypes_v1.1), Beliq validates against the authority Messaggi XSD vendored in the engine. Use format=sdi_messaggio or rely on auto-detect when the root element matches. This is interchange notification / receipt structural validation only — not FatturaPA invoice-body validation and not a substitute for SDI transport (which remains outside Beliq; SDI submission is not implemented).
For Spain Facturae XML (MINECO namespace http://www.facturae.gob.es/formato/Versiones/Facturaev3_2_2.xml, root Facturae), Beliq validates against the published Facturae 3.2.2 XSD bundled in the engine. Use format=facturae or rely on auto-detect. That path is XSD only (no EN 16931 Schematron; no BR-* rule IDs). VeriFactu / FACe submission and XAdES signing remain outside Beliq (BYOC).
For Slovenia e-SLOG 2.0 XML (namespace urn:eslog:2.00, root Invoice wrapping M_INVOIC), Beliq validates against the GZS/ePOS e-SLOG 2.0 XSD bundled in the engine. Use format=eslog or rely on auto-detect. That path is XSD only (no EN 16931 Schematron; no BR-* rule IDs). UJP submission, e-route provider services, and XML-DSig signing remain outside Beliq (BYOC).
Quick copy examples
Validate XML:
curl -X POST "https://api.beliq.eu/v1/validate?format=auto" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/xml" \
--data-binary @invoice.xmlValidate PDF:
curl -X POST https://api.beliq.eu/v1/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/octet-stream" \
--data-binary @invoice.pdfRequest
POST /v1/validate
Content-Type: application/xml | application/octet-stream
Authorization: Bearer <api-key>Headers
| Header | Required | Description |
|---|---|---|
Authorization |
required | Bearer <api-key> or use X-API-Key header |
Content-Type |
required | application/xml for XML input, application/octet-stream for PDF or binary input |
Beliq-Ruleset |
optional | Pin the validation ruleset for this request to a channel (latest or previous), overriding your org’s default channel. The applied ruleset is echoed in the Beliq-Ruleset-Resolved response header. See Ruleset versioning. |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
format |
string | optional | Format hint: auto, cii, ubl, fatturapa, facturae (Spain Facturae 3.2.2 XML — XSD only), eslog (Slovenia e-SLOG 2.0 XML, XSD only), or sdi_messaggio (Italy SDI file messaggio XML — XSD only, not a FatturaPA invoice). When set to auto (default), the engine detects the format automatically (including FatturaPA, Facturae, e-SLOG, and SDI messaggi when the root element matches). |
Request body
The raw XML or PDF file content as the request body. Do not JSON-encode it.
curl -X POST "https://api.beliq.eu/v1/validate?format=auto" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/xml" \
--data-binary @invoice.xmlResponse
Success (200)
{
"success": true,
"data": {
"valid": true,
"format": "cii",
"profileDetected": "XRechnung",
"schematronVersion": "1.3.16",
"ciusVersion": "XRechnung-2.5.0",
"errors": [],
"warnings": []
}
}Validation result object
| Field | Type | Description |
|---|---|---|
valid |
boolean | true if the invoice passes all validation stages with no fatal/error-level violations |
format |
string | Detected format: cii, ubl, fatturapa, facturae, eslog, sdi_messaggio, or unknown |
profileDetected |
string? | Detected profile label when applicable (e.g. xrechnung, peppol, romania-ro-cius, netherlands-nlcius, en16931, Italy FatturaPA labels such as italy-fatturapa-ordinaria-fpr12, Spain Facturae label spain-facturae-v3-2-2, Slovenia e-SLOG label slovenia-eslog-v2-0, or messaggio labels such as italy-sdi-notifica-scarto) |
sha256 |
string | Lowercase-hex SHA-256 of the exact request body validated. Reproduce with sha256sum on your file. Always present. |
rulesetSha256 |
string? | Single fingerprint of the rule artifacts that judged the document. Present whenever a ruleset ran; reconstructable from rulesetArtifacts. |
rulesetArtifacts |
object[]? | The component rows behind rulesetSha256, { key, version, fileSha256 } each. See Verify a hash for the reconstruction and catalog cross-check. |
driftCheckedAt |
string? | ISO 8601 UTC instant reporting when the pinned artifacts that judged the document were last confirmed to still match their upstream authority sources (the nightly drift check). A conservative lower bound: “verified at least as recently as this instant.” Present alongside rulesetSha256 only when every pinned artifact cleared a clean, matching check; omitted otherwise. See When the ruleset was last drift-checked. |
rulesetChannel |
string? | The ruleset channel applied to this request (latest or previous), when a non-default channel was selected via the Beliq-Ruleset header or your org default. See Ruleset versioning. |
rulesetFellBack |
boolean? | true when previous was requested but the format retains no prior ruleset, so the request fell back to latest. Present only alongside rulesetChannel. |
schematronVersion |
string? | EN 16931 Schematron version used (e.g. "1.3.16"). Omitted for FatturaPA, Facturae, e-SLOG, and SDI file messaggio (XSD-only validation). |
ciusVersion |
string? | CIUS Schematron version used (e.g. "XRechnung-2.5.0" or "PeppolBIS-Billing-3.0.20") |
peppolVersion |
string? | Peppol BIS Billing 3.0 CIUS version used. Only present when profileDetected === "peppol"; mirrors ciusVersion for Peppol-specific consumers |
romaniaRoCiusVersion |
string? | Romania CIUS-RO Schematron version used. Only present when profileDetected === "romania-ro-cius"; mirrors ciusVersion for Romania-specific consumers. See Romania format reference. |
netherlandsNlciusVersion |
string? | Netherlands NLCIUS (SI-UBL 2.0) Schematron version used. Only present when profileDetected === "netherlands-nlcius"; mirrors ciusVersion for NL-specific consumers. See Netherlands NLCIUS format reference. |
italyFatturapaXsdBundle |
string? | Present for FatturaPA invoice XML: human-readable label of the authority XSD bundle used (no Schematron). |
italyFatturapaRuntimeVersion |
string? | Present for FatturaPA invoice XML: the pinned bundle version. |
italySdiMessaggiXsdBundle |
string? | Present for SDI file messaggio XML: human-readable label of the MessaggiTypes XSD bundle (not FatturaPA invoices). |
italySdiMessaggiXsdVersion |
string? | Present for SDI file messaggio XML: the pinned bundle version. |
spainFacturaeXsdBundle |
string? | Present for Facturae invoice XML: human-readable label of the authority XSD bundle used (no Schematron). |
spainFacturaeRuntimeVersion |
string? | Present for Facturae invoice XML: the pinned bundle version. |
sloveniaEslogXsdBundle |
string? | Present for e-SLOG XML: human-readable label of the authority XSD bundle used (no Schematron). |
sloveniaEslogRuntimeVersion |
string? | Present for e-SLOG XML: the pinned bundle version. |
errors |
ValidationError[] | Violations at fatal or error severity |
warnings |
ValidationError[] | Violations at warning or info severity |
Validation error object
| Field | Type | Description |
|---|---|---|
ruleId |
string | Official business rule ID (e.g. BR-01, BR-DE-1, PEPPOL-EN16931-R001) |
severity |
string | fatal, error, warning, or info |
location |
string? | XPath location of the violation in the source XML |
message |
string | Human-readable description of the violation |
Peppol BIS Billing 3.0 example
When the input declares the Peppol BIS Billing 3.0 customization, Beliq runs the OpenPeppol Schematron in addition to EN 16931 and reports the Peppol version explicitly:
{
"success": true,
"data": {
"valid": true,
"format": "ubl",
"profileDetected": "peppol",
"schematronVersion": "1.3.16",
"ciusVersion": "PeppolBIS-Billing-3.0.20",
"peppolVersion": "PeppolBIS-Billing-3.0.20",
"errors": [],
"warnings": []
}
}Example with validation errors
{
"success": true,
"data": {
"valid": false,
"format": "cii",
"profileDetected": "XRechnung",
"schematronVersion": "1.3.16",
"ciusVersion": "XRechnung-2.5.0",
"errors": [
{
"ruleId": "BR-01",
"severity": "error",
"location": "/rsm:CrossIndustryInvoice/rsm:ExchangedDocumentContext",
"message": "An Invoice shall have a Specification identifier (BT-24)."
},
{
"ruleId": "BR-DE-1",
"severity": "error",
"location": "/rsm:CrossIndustryInvoice",
"message": "An XRechnung invoice must contain a buyer reference (BT-10)."
}
],
"warnings": [
{
"ruleId": "BR-CL-01",
"severity": "warning",
"location": "/rsm:CrossIndustryInvoice/...",
"message": "The currency code should be a valid ISO 4217 code."
}
]
}
}Response verifiability
Every response carries two hashes so you can confirm the result yourself: sha256 (the exact bytes you sent) and rulesetSha256 (the rule artifacts that judged them), plus the rulesetArtifacts rows the ruleset hash is built from. Responses may also carry driftCheckedAt, a UTC timestamp reporting when those artifacts were last confirmed against their upstream authority sources.
{
"success": true,
"data": {
"valid": false,
"format": "ubl",
"profileDetected": "netherlands-nlcius",
"sha256": "8b508d3648dbee66ca6798e6bc812842204974328fd626e3d9cdf60c98782cd1",
"rulesetSha256": "7a590a263701e50305677ec253c61d83a13336c0e8b10b01674573347a52de00",
"rulesetArtifacts": [
{ "key": "en16931_ubl_schematron", "version": "1.3.16", "fileSha256": "39f9d282867f1a49e7708d9e29a53da89643e1ee56f10cec1ebcf1277595fcbd" },
{ "key": "netherlands_nlcius_schematron", "version": "2.0.3.13", "fileSha256": "73da3db0b8cf6a37a8ad17051ac1603a83a695e2fa066820803aa1283a06e140" }
],
"driftCheckedAt": "2026-07-03T04:12:07Z"
}
}sha256sum your file to match sha256; sort the rulesetArtifacts "<key>@<version>=<fileSha256>" lines, join with newlines, and SHA-256 to reproduce rulesetSha256; then cross-check each component against GET /v1/rulesets. driftCheckedAt, when present, reports how recently that ruleset was drift-checked against its authority sources. Full walkthrough: Verify a hash.
Error responses
| HTTP Status | Error Code | When |
|---|---|---|
| 400 | VALIDATION_ERROR |
Request body is empty or not a valid file |
| 422 | INVALID_XML |
Input XML is malformed and cannot be parsed |
| 503 | ENGINE_UNAVAILABLE |
The validation engine is temporarily unavailable |
400 example
{
"success": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Request body must contain an XML or PDF file"
}
}Notes
valid: falseis not an API error. It means validation ran successfully and found rule violations.formattells you which syntax family was detected (cii,ubl,fatturapa,facturae,eslog, orsdi_messaggio).- Rule IDs follow the official naming conventions where Schematron is used:
BR-*for EN 16931 core rules,BR-DE-*for XRechnung rules,PEPPOL-*for Peppol-specific rules. FatturaPA, Facturae, e-SLOG, and SDI file messaggio XSD violations useruleId: "XSD"(structural). Messaggio validation does not imply FatturaPA invoice conformance or SDI operational interchange. - See the validation artifacts page for details on which Schematron versions are currently in use.