Learn how to integrate InvoiceHub validation into your application.
All API requests require an API key. Include it in the Authorization header:
Authorization: Bearer ih_live_xxxxxxxxxxxxxxxxxxxxxxGet your API key from the dashboard.
Validate a UBL 2.1 invoice against the official CEN EN 16931 Schematron (v1.3.16). Returns structured errors and warnings mapped to the official BR-* rule identifiers.
No API key yet? Try POST /api/v1/playground (unauthenticated, rate-limited) or the live playground on the home page.
Content-Type: application/xmlAuthorization: Bearer <api_key>Raw XML invoice document
<?xml version="1.0" encoding="UTF-8"?>
<Invoice xmlns="urn:oasis:names:specification:ubl:schema:xsd:Invoice-2">
<cbc:CustomizationID>urn:cen.eu:en16931:2017</cbc:CustomizationID>
<cbc:ID>INV-001</cbc:ID>
<cbc:DocumentCurrencyCode>EUR</cbc:DocumentCurrencyCode>
<!-- ... -->
</Invoice>{
"timestamp": "2026-06-17T10:30:00Z",
"requestId": "0f3c…",
"performance": { "duration_ms": 5 },
"report": {
"valid": true,
"format": "UBL_2.1",
"profile": "Peppol BIS Billing 3.0",
"rulesEvaluated": 13,
"errors": [],
"warnings": [],
"metadata": {
"invoiceNumber": "INV-2026-001",
"currency": "EUR",
"payableAmount": 180.6
}
}
}{
"timestamp": "2026-06-17T10:30:00Z",
"requestId": "0f3c…",
"performance": { "duration_ms": 4 },
"report": {
"valid": false,
"format": "UBL_2.1",
"rulesEvaluated": 13,
"errors": [
{
"ruleId": "BR-CO-15",
"severity": "CRITICAL",
"message": "Invoice total amount with VAT must equal total without VAT + total VAT.",
"path": "Invoice.cac:LegalMonetaryTotal.cbc:TaxInclusiveAmount"
}
],
"warnings": []
}
}Build an EN 16931-conformant UBL 2.1 invoice from structured JSON. Every monetary total is computed for you, and the generated document is validated against the official Schematron before it is returned — if it would not pass, you get the validation report (HTTP 422) instead of an invalid document. We never hand back XML we have not checked.
{
"invoiceNumber": "INV-2026-001",
"issueDate": "2026-06-19",
"dueDate": "2026-07-19",
"currency": "EUR",
"seller": {
"name": "Acme Trading GmbH",
"vatId": "DE123456789",
"address": { "street": "Hauptstraße 1", "city": "Berlin", "postalZone": "10115", "country": "DE" }
},
"buyer": {
"name": "Buyer Industries SARL",
"address": { "city": "Paris", "postalZone": "75001", "country": "FR" }
},
"lines": [
{ "description": "Consulting services", "quantity": 10, "unitPrice": 100, "vatRate": 19, "unitCode": "HUR" }
],
"payment": { "iban": "DE89370400440532013000" }
}{
"requestId": "0f3c…",
"performance": { "duration_ms": 6 },
"xml": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Invoice …>…</Invoice>",
"report": { "valid": true, "format": "UBL_2.1", "rulesEvaluated": 54, "errors": [], "warnings": [] }
}Standard-rated lines (VAT category S) require avatRate and the seller vatId (BR-S-2). Exempt and reverse-charge categories require an exemptionReason.
Query GET /api/v1/formats for the live list. Current status:
| Format | Status |
|---|---|
| UBL 2.1 (Invoice & CreditNote) | Generally available |
| Official CEN EN 16931 Schematron (v1.3.16) | Generally available |
| UN/CEFACT CII | Planned |
| XRechnung (DE) | Planned |
| Factur-X / ZUGFeRD (hybrid PDF) | Planned |
| Peppol BIS Billing 3.0 | Planned |
UBL 2.1 is validated with the official CEN EN 16931 Schematron artifacts (v1.3.16). XSD schema validation and additional syntaxes are in progress.
InvoiceHub ships a Model Context Protocol endpoint so AI agents can validate and generate EU e-invoices directly. It speaks JSON-RPC 2.0 over Streamable HTTP at POST https://api.invoicehub.dev/mcp and exposes three tools:validate_invoice,generate_invoice andlist_supported_formats.
curl -X POST https://api.invoicehub.dev/mcp \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/call",
"params":{"name":"validate_invoice","arguments":{"xml":"<Invoice …>…</Invoice>"}}}'The full API is described by an OpenAPI 3.1 document. Import it into Postman or Insomnia, or generate a typed client in your language with tools likeopenapi-generator,Speakeasy orFern.
npx @openapitools/openapi-generator-cli generate \
-i https://api.invoicehub.dev/api/v1/openapi.json \
-g typescript-fetch -o ./invoicehub-clientcurl -X POST https://api.invoicehub.dev/api/v1/validate \
-H "Authorization: Bearer ih_live_xxx" \
-H "Content-Type: application/xml" \
-d @invoice.xmlconst response = await fetch('https://api.invoicehub.dev/api/v1/validate', {
method: 'POST',
headers: {
'Authorization': 'Bearer ih_live_xxx',
'Content-Type': 'application/xml'
},
body: xmlContent
});
const result = await response.json();
console.log(result.report);import requests
response = requests.post(
'https://api.invoicehub.dev/api/v1/validate',
headers={
'Authorization': 'Bearer ih_live_xxx',
'Content-Type': 'application/xml'
},
data=xml_content
)
result = response.json()
print(result['report'])| Plan | Hourly Limit | Daily Limit |
|---|---|---|
| Free | 60 | 600 |
| Pro | 10,000 | 100,000 |
| Enterprise | Unlimited | Unlimited |
Rate limit headers are included in every response:
X-RateLimit-Limit: 60X-RateLimit-Remaining: 42X-RateLimit-Reset: 2026-06-17T11:00:00ZInvalid or missing API key. Check your authentication header.
Invoice validation failed. Check the errors array in the response.
Rate limit exceeded. Check the Retry-After header for when to retry.
Unexpected error. Contact support if this persists.
Check our pricing page for support options.
Contact us and we'll get back to you.