E-invoice Validator (XRechnung, Peppol BIS 3, EN 16931)

Validate XRechnung, Peppol BIS 3 and EN 16931 e-invoices (UBL/CII, ZUGFeRD/Factur-X XML) with the official KoSIT validator, explain every business rule and preview the automatic repair. Remote, free, no key, nothing stored.

เซิร์ฟเวอร์ MCP แบบโฮสต์

npx add-mcp 'https://einvoice-validator-k2qw.onrender.com/mcp'

ติดตั้งลง Claude Code, Codex, Cursor และอื่นๆ

เอกสาร

JSON API

POST https://einvoice-validator-k2qw.onrender.com/api/validate with the invoice XML as the request body (Content-Type: application/xml), max 5 MB. No authentication, no storage.

curl -sS --data-binary @invoice.xml -H "Content-Type: application/xml" https://einvoice-validator-k2qw.onrender.com/api/validate

Response:

{
  "accepted": false,
  "scenario": "EN16931 XRechnung (UBL Invoice)",
  "engine": "KoSIT Validator 1.6.3",
  "messages": [
    {"code": "BR-CO-10", "level": "error", "text": "[BR-CO-10]-Sum of Invoice line net amount (BT-106) = Σ Invoice line net amount (BT-131).",
     "location": "/ubl:Invoice/cac:LegalMonetaryTotal", "auto_fix": true, "rule_url": "https://einvoice-validator-k2qw.onrender.com/rules/BR-CO-10.html"}
  ],
  "counts": {"error": 1, "warning": 0, "information": 0},
  "duration_ms": 1830
}

accepted follows the validator's assessment (warnings alone do not reject). scenario is one of EN16931 XRechnung (UBL Invoice), EN16931 XRechnung (UBL CreditNote), EN16931 XRechnung (CII), their Extension/CVD variants, Peppol BIS Billing 3.0 (UBL Invoice) or Peppol BIS Billing 3.0 (UBL CreditNote); it is null and no_scenario is true when the CustomizationID does not match any known profile — then no rule can be checked.

Rate limit: fair use. The service runs on a free tier and may take up to a minute to wake up after idle periods; GET /health returns 200 when ready.

Use it from your AI agent (MCP)

The validator is also a remote Model Context Protocol server (Streamable HTTP, no key, nothing stored), listed in the official MCP Registry as io.github.nyo-agentti/einvoice-validator. Endpoint: https://einvoice-validator-k2qw.onrender.com/mcp

  • validate_einvoice — argument xml (the complete invoice XML as text). Runs the same KoSIT validation as this page and returns accepted / rejected, the scenario and every rule message with location and a link to the rule page. For a rejected file it also reports what our repair engine would change, measured on that file; the corrected file itself is 9 € per file on the website.
  • explain_rule — argument rule (e.g. BR-CO-10, BR-DE-15, PEPPOL-EN16931-R001): what the rule means and how to fix it.

Claude Code:

claude mcp add --transport http einvoice-validator https://einvoice-validator-k2qw.onrender.com/mcp

Cursor (~/.cursor/mcp.json) and other clients that take a server URL:

{"mcpServers": {"einvoice-validator": {"url": "https://einvoice-validator-k2qw.onrender.com/mcp"}}}

VS Code (.vscode/mcp.json):

{"servers": {"einvoice-validator": {"type": "http", "url": "https://einvoice-validator-k2qw.onrender.com/mcp"}}}

Claude desktop and claude.ai: Settings → Connectors → Add custom connector → paste the endpoint URL. Then ask, for example: "Validate invoice.xml as XRechnung and explain each error."

Repair API (Repair API plan)

POST https://einvoice-validator-k2qw.onrender.com/api/repair with the UBL 2.1 invoice or credit note XML, or the UN/CEFACT CII invoice XML (Factur-X / ZUGFeRD EN 16931, XRechnung CII; the response field syntax is ubl or cii and the repaired file keeps its syntax), as the request body and your API key in Authorization: Bearer <key> (or X-API-Key). The invoice is validated, repaired deterministically, validated again, and returned. Nothing is stored. See Pricing for the plans; keys are issued per subscription period.

curl -sS --data-binary @invoice.xml -H "Content-Type: application/xml" -H "Authorization: Bearer $API_KEY" \
     "https://einvoice-validator-k2qw.onrender.com/api/repair?profile=peppol"

Query parameters (all optional): profile=auto|peppol|xrechnung (target profile; auto keeps the invoice's own), process=01|02 (Peppol process), and the confirmation-type repairs that are on by default and can be switched off with =0: merge_notes (PEPPOL-EN16931-R002), flip_bt111_sign (R055), eas_heuristic (CL008/R010/R020 electronic address), map_type_code (P0100/P0101/P0112 invoice type code). format=xml returns only the repaired XML with the headers X-Repair-Changes, X-Accepted-Before, X-Accepted-After.

Response (JSON):

{
  "syntax": "ubl",
  "settings": {"profiili": "peppol", "prosessi": "01", ...},
  "changes": [
    {"rule": "BR-CO-10", "path": "/Invoice/cac:LegalMonetaryTotal/cbc:LineExtensionAmount", "before": "1.000", "after": "314.86",
     "explanation": "..."}
  ],
  "diff": "--- ennen.xml
+++ jalkeen.xml
@@ ...",
  "repaired_xml": "<?xml version="1.0" ...",
  "validation_before": {"accepted": false, "scenario": "EN16931 XRechnung (UBL Invoice)", "counts": {"error": 3, "warning": 0, "information": 0}, "errors": ["BR-CO-10", "BR-CO-13", "BR-CO-15"]},
  "validation_after":  {"accepted": true,  "scenario": "EN16931 XRechnung (UBL Invoice)", "counts": {"error": 0, "warning": 0, "information": 0}, "errors": []},
  "remaining_messages": [],
  "quota": {"used": 12, "limit": 5000},
  "duration_ms": 640
}

Status codes: 200 repaired (also when nothing needed repair: changes is empty and the file is returned unchanged), 400 bad input or unknown parameter, 401 missing or invalid key, 403 expired key, 422 neither a UBL 2.1 Invoice/CreditNote nor a UN/CEFACT CII CrossIndustryInvoice, 429 monthly quota used (X-Quota-Limit, X-Quota-Used on every response), 503 validator starting or paid plans not open.

What is repaired, and what only gets an explanation, is listed per rule in the rule reference (auto-fix). The repaired file is a proposal: the business content is yours to verify.