eliDocs
API Reference

POST /v1/validate

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:

  1. XML structure (XSD)
  2. EN 16931 business rules (Schematron)
  3. 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:

validate-xml.sh
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.xml

Validate PDF:

validate-pdf.sh
curl -X POST https://api.beliq.eu/v1/validate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary @invoice.pdf

Request

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.

validate.sh
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.xml

Response

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: false is not an API error. It means validation ran successfully and found rule violations.
  • format tells you which syntax family was detected (cii, ubl, fatturapa, facturae, eslog, or sdi_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 use ruleId: "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.