Open-source code examples for working with the UN/CEFACT Cross Industry Invoice (CII), the XML syntax behind ZUGFeRD, Factur-X, and XRechnung. CII is one of the two syntaxes permitted by the European norm EN 16931 (the other is UBL 2.1), and this repository covers it as a standalone XML document, with no PDF wrapper.
Examples in C#, Java, PHP, JavaScript, Node.js, and Python covering every common CII operation: invoice creation, validation against the EN 16931 rules, parsing invoice data into JSON, and (experimental) AI-powered conversion of plain PDF invoices into compliant CII documents.
Provided and maintained by InvoiceXML, a complete e-invoice compliance toolkit for electronic invoicing standards, including CII, ZUGFeRD, Factur-X, XRechnung, UBL, and Peppol BIS Billing, available via REST-API, no-code platforms, and MCP server.
The EN 16931 specification alone runs over 400 pages, the CII D16B schema is a deep UN/CEFACT tree that no one enjoys hand-rolling, and the validation Schematron updates with every regulatory revision. A realistic in-house build is 6 to 12 weeks of engineering, plus 0.3 to 0.5 FTE permanently allocated to tracking spec changes as more and more EU countries roll out their mandates. InvoiceXML absorbs all of that behind a single REST API covering CII, ZUGFeRD, Factur-X, XRechnung, UBL, and Peppol BIS. EU-hosted, GDPR-compliant, no invoice data persisted between calls, sub-second responses, 99.95% uptime. Your integration keeps calling the same endpoints when the spec changes next quarter, you get the latest compliance out of the box, zero maintenance required.
- What is CII?
- When to use standalone CII
- Why use this repository
- Operations covered
- Quick start by language
- Parse CII data as JSON
- Render CII as a readable PDF
- AI-powered PDF to CII conversion (Experimental)
- Profiles and validation
- Related e-invoicing standards
- Frequently asked questions
- Resources and references
- Contributing
- License
CII (Cross Industry Invoice) is an XML schema maintained by UN/CEFACT, the United Nations Centre for Trade Facilitation and Electronic Business. The version referenced by EN 16931 is D16B, whose root element is CrossIndustryInvoice.
CII is a syntax, not a document format in its own right. That distinction explains most of the confusion around it:
- ZUGFeRD and Factur-X are CII XML embedded inside a PDF/A-3 container.
- XRechnung can be CII (or UBL), with extra German rules layered on top.
- Standalone CII is the same XML on its own, with no PDF and no national CIUS.
This repository covers that last case. The examples produce plain EN 16931 CII, declaring urn:cen.eu:en16931:2017 as the guideline identifier in BT-24.
Reach for standalone CII when you want the structured data without a PDF wrapper:
- ERP and EDI pipelines that ingest or emit CII directly, with no interest in a visual document.
- Embedding into your own PDF/A-3 container, when you already have a designed invoice PDF and only need the XML payload to attach.
- Archival of the machine-readable data separately from the human-readable rendering.
- Interoperating with CII-based partners who exchange raw XML over their own channels.
If you want a human-readable PDF with the data embedded, you want the hybrid formats instead: see the ZUGFeRD examples (Germany) or the Factur-X examples (France). If you are invoicing a German public authority, you want XRechnung. If your recipient is on the Peppol network, they will most likely expect UBL.
The CII D16B schema is large, deeply nested, and documented mainly as UN/CEFACT reference material rather than as anything a developer can copy and run. This repository provides side-by-side, copy-pasteable code examples for the languages most commonly used in invoicing, ERP, and accounting systems, so developers can:
- Pick the language already used in their stack
- Skip hand-building a
CrossIndustryInvoicetree from the raw schema - Run the same operations (create, validate, parse to JSON, AI-convert) in any of the supported languages
- Compare behavior and output across implementations
- Use the produced invoices as test fixtures for their own systems
Every example in this repository produces or consumes invoices validated against the CII D16B XSD and the EN 16931 Schematron before delivery.
| Operation | Description |
|---|---|
| Create CII | Build an EN 16931 compliant CII D16B XML invoice from a structured JSON request |
| Validate CII | Verify a CII file against the D16B XSD and the business rules for the profile it declares |
| Extract JSON | Parse a CII XML file into structured invoice data as JSON for downstream systems |
| Render to PDF | Render a CII XML file into a human-readable PDF preview |
| AI Convert (experimental) | Convert a plain, unstructured PDF invoice into a compliant CII document using a large language model |
Each language has its own folder containing all four operations as standalone, runnable files. Open the folder for your language to see installation steps, dependencies, and usage.
/csharp
Create.cs # Build a CII D16B XML invoice
Validate.cs # Validate against the D16B XSD and EN 16931 rules
ExtractJson.cs # Parse a CII XML into JSON
AiConvert.cs # (Experimental) Convert plain PDF to CII using AI
/java
Create.java
Validate.java
ExtractJson.java
AiConvert.java
Render.java
/php
create.php
validate.php
extract-json.php
ai-convert.php
render.php
Browser-side examples for generating and inspecting CII invoices client-side, useful for web-based invoicing apps that want to avoid round-trips to a server.
/javascript
create.html
validate.html
extract-json.html
ai-convert.html
render.html
Open the JavaScript examples →
/nodejs
create.js
validate.js
extract-json.js
ai-convert.js
render.js
/python
create.py
validate.py
extract_json.py
ai_convert.py
render.py
Many downstream systems (ERPs, accounting software, expense management tools) work natively with JSON rather than XML, and the CII tree is unpleasant to walk by hand: business terms live several namespaces deep under names like ram:SpecifiedLineTradeAgreement. The ExtractJson examples in every language upload a CII XML file and receive the EN 16931 model back as clean JSON: seller, buyer, line items, tax breakdown, totals, and payment details.
The invoice fields sit at the root of the response, so you read seller.name or totals.grandTotalAmount (BT-112) directly, with no wrapper object to unpack.
This is the fastest way to get invoice data out of a CII file and into a modern data pipeline.
Standalone CII is a machine format with no visual layer, so nobody can read it without tooling, and eyeballing a raw CrossIndustryInvoice tree is not a reasonable way to check an invoice.
The Render examples upload a CII XML file and receive a formatted PDF preview, with every EN 16931 business term mapped to a readable layout. All CII profiles from MINIMUM through EXTENDED are supported, the profile being auto-detected from BT-24, and the labels can be localized with the language field (en, de, fr).
Two things worth knowing:
- The PDF has no legal standing. It is a visual representation for humans; the XML file remains the authoritative invoice for compliance and tax purposes. If you need a legally exchangeable hybrid PDF, you want ZUGFeRD or Factur-X instead.
- It is generated fresh from the structured data, not extracted from any existing PDF layer. That is what makes it useful for verifying what your XML actually says, including for CII you extracted out of a ZUGFeRD or Factur-X file.
Experimental feature. Human verification required before any production use.
Real-world PDF invoices are often messy: scanned at low quality, irregularly formatted, multi-page, multilingual, or missing fields that EN 16931 requires. Producing a fully compliant CII document from such an input is non-trivial, and AI extraction can make subtle mistakes that automated validators may not catch: wrong tax category codes, transposed amounts, missing seller VAT identifiers, incorrect currency formatting.
Output from the
AiConvertexamples must always be reviewed by a human before the invoice is sent to a customer or submitted to a tax authority. This is a developer convenience for bootstrapping test data and prototyping, not an unattended production pipeline.
The AiConvert examples in each language demonstrate the same pattern:
- Read a plain (non-CII) PDF invoice
- A large language model reads the document and infers the invoice fields (seller, buyer, line items, tax breakdown, totals, payment terms)
- The API maps those fields to the EN 16931 semantic model and generates CII D16B XML
Useful for bootstrapping test fixtures from invoices you already have, rather than hand-writing CII trees.
Validation runs in two layers, and what the second layer checks depends on what your document declares in BT-24 (GuidelineSpecifiedDocumentContextParameter):
| Declared profile | Rules applied |
|---|---|
urn:cen.eu:en16931:2017 (what these examples produce) |
CII D16B XSD, then the full EN 16931 Schematron |
| A Factur-X / ZUGFeRD profile (MINIMUM, BASIC WL, BASIC, EXTENDED) | The XSD, then that profile's own official rules, so an EXTENDED invoice is not wrongly failed for using extended fields |
| An XRechnung identifier | The XSD, then the KoSIT BR-DE rules |
| Anything unrecognized | The XSD and the EN 16931 base rules, plus a PROFILE-DETECTION warning explaining the fallback. An exotic identifier is never auto-failed |
The response reports data.customizationId (what the document declared) and data.profile (the rule set that was actually applied), and every finding carries a layer field telling you whether it came from the schema (xsd), the core rules (en16931), or a profile overlay (cius).
CII is one syntax among several in the European e-invoicing landscape:
- UBL 2.1: the other EN 16931 syntax, from OASIS. Pure XML like standalone CII, and the native format of the Peppol network.
- ZUGFeRD 2.x: German hybrid format, CII XML embedded in a PDF/A-3. See the ZUGFeRD examples.
- Factur-X: French equivalent of ZUGFeRD 2.x. Technically identical specification, different branding. See the Factur-X examples.
- XRechnung: the German CIUS of EN 16931, expressible in CII or UBL, mandatory for German B2G. See the XRechnung examples.
- Peppol BIS Billing 3.0: UBL-based subset exchanged over the Peppol network.
- EN 16931: the European norm that underlies all of the above.
For a side-by-side comparison of when to use which format, see the e-invoicing standards comparison on invoicexml.com.
What is the difference between CII and ZUGFeRD or Factur-X? ZUGFeRD and Factur-X are CII, wrapped in a PDF/A-3 so a human can read the invoice too. The XML inside them is structurally the same as what this repository produces. Use standalone CII when you do not need the PDF layer.
How does CII differ from UBL? Both are valid EN 16931 syntaxes expressing the same semantic model, but they are entirely different XML: CII comes from UN/CEFACT, UBL from OASIS. CII dominates in Germany and France (via ZUGFeRD and Factur-X); UBL dominates on the Peppol network and in the Nordics, the Netherlands, and Belgium.
Which CII version is used?
D16B, the version referenced by EN 16931. The retired CrossIndustryDocument root used by ZUGFeRD 1.0 is not interchangeable and is reported as schema-invalid.
Can I embed the output in a ZUGFeRD or Factur-X PDF?
Yes. The generated CII XML is structurally identical to the XML those formats embed, so you can attach it to a PDF/A-3 in your own pipeline. If you would rather receive the complete hybrid PDF in one call, use /v1/create/zugferd or /v1/create/facturx instead.
Do I need to calculate totals myself?
No. The invoice.totals object and the invoice.vatBreakdowns array are calculated from your line items when omitted. Provide them explicitly only if you need to override the computed result.
Is the output validated automatically?
Yes. Every generated CII document is validated against the D16B XSD and the EN 16931 Schematron before delivery. If validation fails (for example mismatched totals), the API returns a 400 with errorCode 4001 and the violated rules as findings, each carrying the rule id, layer, and the JSON field paths to correct.
- UN/CEFACT Cross Industry Invoice (CII) specification
- EN 16931 (European Committee for Standardization)
- Factur-X specification (FNFE-MPE), which profiles CII
- ZUGFeRD specification (FeRD), which profiles CII
- invoicexml.com: guides, tutorials, validators, and standard comparisons for CII, ZUGFeRD, Factur-X, XRechnung, UBL, and Peppol
Pull requests are welcome. Useful contributions include:
- Additional languages (Go, Rust, Ruby, Kotlin, Swift)
- Alternative library implementations in existing languages
- Sample invoice fixtures covering edge cases (multi-currency, intra-EU reverse charge, zero-rated supplies, credit notes)
- Translations of the README and inline comments
- Bug fixes and validation rule clarifications
Please include a working example, pinned dependency versions, and a short note in the relevant language folder's README.