Peppol Validator API & Agent Skill
Validate Peppol UBL and CII / Factur-X XML invoices programmatically. No signup, no API key. Just send XML and get results.
API endpoint
Send a UBL or CII XML invoice and receive validation results as JSON. The format is detected automatically. UBL invoices are validated against CEN EN16931 and Peppol BIS Billing 3.0 rules. CII / Factur-X invoices are validated against CEN EN16931 (CII binding) rules.
POST https://peppolvalidator.com/api/v1/validateOption 1: Raw XML body
Send the XML directly as the request body with a Content-Type: application/xml header.
curl -X POST https://peppolvalidator.com/api/v1/validate \
-H "Content-Type: application/xml" \
-d @invoice.xmlOption 2: Multipart form data
Upload the file as a file field in a multipart request.
curl -X POST https://peppolvalidator.com/api/v1/validate \
-F "file=@invoice.xml"JavaScript / Node.js
const xml = fs.readFileSync("invoice.xml", "utf-8");
const res = await fetch("https://peppolvalidator.com/api/v1/validate", {
method: "POST",
headers: { "Content-Type": "application/xml" },
body: xml,
});
const result = await res.json();
console.log(result.status); // "valid" | "invalid" | "error"Python
import requests
with open("invoice.xml") as f:
xml = f.read()
res = requests.post(
"https://peppolvalidator.com/api/v1/validate",
headers={"Content-Type": "application/xml"},
data=xml,
)
result = res.json()
print(result["status"]) # "valid" | "invalid" | "error"Response format
The API returns a JSON object with the validation result. The status field is either "valid", "invalid", or "error".
| Field | Type | Description |
|---|---|---|
status | string | "valid", "invalid", or "error" |
format | string? | "ubl" or "cii" (detected automatically) |
specification | string? | e.g. "Peppol BIS Billing 3.0" or "EN16931 (CII / Factur-X)" |
errors | array | Validation errors (rule, message, XPath location) |
warnings | array | Validation warnings |
infos | array | Informational messages |
invoiceNumber | string? | Extracted invoice number |
sellerCountry | string? | Seller country code (ISO 3166-1 alpha-2) |
validatedAt | string | ISO 8601 timestamp |
errorMessage | string? | Present when status is "error" |
resultsUrl | string | Link to shareable results page |
Example response
{
"fileId": "a1b2c3d4-...",
"filename": "invoice.xml",
"status": "invalid",
"format": "ubl",
"specification": "Peppol BIS Billing 3.0",
"sellerCountry": "BE",
"invoiceNumber": "INV-2026-001",
"errors": [
{
"id": "1",
"severity": "error",
"rule": "BR-16",
"location": "/Invoice",
"message": "An Invoice shall have at least one Invoice line (BG-25)."
}
],
"warnings": [
{
"id": "2",
"severity": "warning",
"rule": "PEPPOL-EN16931-R080",
"location": "/Invoice/cac:TaxTotal",
"message": "Tax category tax amount must equal..."
}
],
"infos": [],
"validatedAt": "2026-02-17T12:00:00.000Z",
"resultsUrl": "https://peppolvalidator.com/r/a1b2c3d4-..."
}Quickstart
- No signup or API keys needed. Start calling the API immediately.
- Send a UBL or CII XML invoice to
POST /api/v1/validatewith the XML as the request body. - Check the
statusfield in the JSON response:"valid","invalid", or"error". - If
"invalid", iterate over theerrorsarray for rule IDs, XPath locations, and fix guidance. - Share the
resultsUrlwith your team to view results in the browser.
HTTP status codes
| Code | Meaning |
|---|---|
200 | Validation completed (check status field for result) |
400 | Bad request (empty body, missing file field, exceeds 5MB) |
500 | Server error during validation |
503 | Validation rules temporarily unavailable |
Error codes
All error responses include a machine-readable code field alongside the human-readable error message.
| Code | HTTP | Description |
|---|---|---|
EMPTY_BODY | 400 | No XML content in the request body |
MISSING_FILE | 400 | No "file" field in multipart form data |
FILE_TOO_LARGE | 400 | Uploaded file exceeds the 5MB limit |
BODY_TOO_LARGE | 400 | Raw request body exceeds the 5MB limit |
RULES_UNAVAILABLE | 503 | Schematron rules are loading; retry after 5-10 seconds |
VALIDATION_FAILED | 500 | Internal error during validation; retry with exponential backoff |
PDF_GENERATION_FAILED | 400 | XML could not be parsed or converted to PDF |
Retry guidance
- •400 errors: Do not retry. Fix the request based on the error code.
- •500 errors: Retry with exponential backoff (1s, 2s, 4s). Maximum 3 retries.
- •503 errors: Schematron rules are loading into memory. Retry after 5-10 seconds.
Monitor service health at /status or via the GET /api/v1/health endpoint.
Authentication
No authentication required. All API endpoints are publicly accessible without API keys, tokens, or signup. Send requests directly with no authorization headers.
Rate limiting may be introduced in the future. For high-volume usage (thousands of invoices per hour), reach out at hello@peppolvalidator.com.
CORS
The API sets Access-Control-Allow-Origin: * so you can call it from any domain, including browser-based applications.
XML to PDF conversion
Convert a UBL XML invoice or credit note to a professional PDF document. Send the XML and receive a PDF file in return.
POST https://peppolvalidator.com/api/v1/xml-to-pdfcURL example
curl -X POST https://peppolvalidator.com/api/v1/xml-to-pdf \
-H "Content-Type: application/xml" \
-d @invoice.xml \
-o invoice.pdfResponse
Returns application/pdf with a Content-Disposition: attachment header. On error, returns JSON with an error field and a 400 status code. Supports both raw XML body and multipart form upload (same as the validation endpoint).
MCP Server
Peppol Validator exposes a Model Context Protocol (MCP) server so AI agents like Claude, ChatGPT, and others can call validation tools natively. The server uses Streamable HTTP transport.
https://peppolvalidator.com/mcpAvailable tools
| Tool | Description |
|---|---|
validate_invoice | Validate a Peppol UBL or CII XML invoice against EN16931 and BIS Billing 3.0 schematron rules |
xml_to_pdf | Convert a UBL or CII XML invoice to a human-readable PDF |
get_verification_challenge | Get a HATCHA challenge to prove the caller is an AI agent (required before submitting feedback) |
submit_feedback | Report validation accuracy issues, API problems, or general feedback (requires HATCHA verification) |
Configuration
Add this to your MCP client configuration (e.g. claude_desktop_config.json or .cursor/mcp.json):
{
"mcpServers": {
"peppol-validator": {
"url": "https://peppolvalidator.com/mcp"
}
}
}Discovery
MCP-compatible agents can discover the server automatically via:
- •
/.well-known/mcp: server URL and metadata - •
/.well-known/mcp/server-card.json: full server card with tool schemas
Test it
curl -X POST https://peppolvalidator.com/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Agent Skill
An Agent Skill is a structured instruction file that teaches AI coding agents how to use a tool. Add the Peppol Validator skill to your project and your agent can validate invoices automatically.
Install
Download SKILL.mdDownload and place in your project. For Claude Code, use .claude/skills/. For other agents, use .agents/skills/.
.claude/skills/validating-peppol-invoices/SKILL.mdOr create the file manually with these contents:
---
name: validating-peppol-invoices
description: Validates Peppol UBL XML invoices and credit notes
against EN16931 (CEN) and Peppol BIS Billing 3.0 schematron
rules via the Peppol Validator API. Use when validating
e-invoices, checking Peppol compliance, debugging UBL XML
validation errors, or verifying invoices before sending via
the Peppol network.
---
# Validating Peppol Invoices
POST XML to the Peppol Validator API and parse the JSON result.
## Endpoint
\`POST https://peppolvalidator.com/api/v1/validate\`
Send raw XML with \`Content-Type: application/xml\`:
```bash
curl -X POST https://peppolvalidator.com/api/v1/validate \
-H "Content-Type: application/xml" \
-d @invoice.xml
```
Returns JSON with status ("valid" / "invalid" / "error"),
errors, warnings, and invoice metadata.What your agent can do with it
- •Validate XML invoices during development and flag issues inline
- •Run validation as part of CI/CD before deploying invoice generation code
- •Debug Peppol validation errors by examining rule IDs and locations
- •Verify fixes by re-validating after changes
Try it now
Validate an invoice via the web UI or send one to the API. No signup needed.
Common questions
Is the API free?
Yes. The API is free with no signup or API key required. We may introduce rate limits in the future if needed, but casual and CI/CD usage is welcome.
What validation rules are applied?
For UBL invoices: CEN EN16931 business rules (BR-*) and Peppol BIS Billing 3.0 rules (PEPPOL-EN16931-*). For CII / Factur-X invoices: CEN EN16931 business rules, syntax rules (CII-SR-*), and code list validation. The format is detected automatically.
What file formats are supported?
UBL 2.1 XML invoices and credit notes (Peppol BIS Billing 3.0) and CII XML invoices (EN16931 / Factur-X / ZUGFeRD). The format is detected automatically from the XML namespace.
Is there a rate limit?
There is no hard rate limit today. Please be reasonable. If you need to validate thousands of invoices per hour, reach out first.
What is an Agent Skill?
An Agent Skill is a structured instruction file that tells AI coding agents (like Claude Code, Cursor, Windsurf, etc.) how to use a tool. By adding the Peppol Validator skill to your project, your AI agent can validate invoices during development without manual steps.