CII is the UN/CEFACT Cross Industry Invoice: one of the two XML syntaxes EN 16931 permits, and the one underneath Factur-X, ZUGFeRD and the CII binding of XRechnung. These files are that XML on its own, with no PDF wrapper and no national rule set on top, which makes them the cleanest thing to develop a CII parser against.
Because plain CII adds nothing to the European core, there is no ladder of profiles here and no syntax choice. What actually differs between real CII documents is the document type and the VAT treatment, so that is what the set varies.
The set
All three carry the same three-line services invoice from a German seller to a French buyer, so you can diff them against each other and see only the difference that matters.
A credit note is not a different message
In CII a credit note is the same rsm:CrossIndustryInvoice root you already parse, with one field changed:
<ram:TypeCode>381</ram:TypeCode>
Worth stating plainly because UBL does the exact opposite: there a credit note is a separate CreditNote document with its own root element and namespace. Code ported between the two syntaxes gets this wrong in both directions, either looking for a root element that never changes or switching on a type code that never moves. The UBL sample set has the other half of the comparison.
Zero VAT needs a reason, and only sometimes a manual one
The reverse-charge file is the common cross-border case: two VAT-registered businesses in different member states, the supplier charges nothing and the buyer accounts for the tax. The VAT breakdown carries category AE at a zero rate, plus the justification the rules demand in BT-120 and BT-121.
Which the API filled in by itself. Categories AE, K, G and O each map to exactly one canonical VATEX reason, so there is nothing to guess and nothing for you to supply. Category E, plain exemption, is the exception: it stands in for dozens of different national provisions, so guessing a reason is wrong more often than right and the field is left to you. That asymmetry is the whole subject of the first invalid fixture below.
Files that are wrong on purpose
The first is a clean single-rule failure: category E, arithmetic all consistent, no BT-120 or BT-121. Only BR-E-10 fires. If your validator passes it, it is not running the VAT category rules.
The second is deliberately not single-rule, and that is what makes it useful. EN 16931's totals are anchored on line evidence, so deleting the lines does not fail one rule, it fails three: BR-16 for the missing lines, then BR-CO-10 and BR-S-08 because the sum of line net amounts and the VAT breakdown now claim figures nothing supports. One edit, three findings. If you are building error reporting, a cascade like this is a better test of your grouping and de-duplication than any single-rule file.
How these files were generated
One call, no options at all, since plain CII has nothing to configure:
curl -X POST https://api.invoicexml.com/v1/create/cii \
-H "Authorization: Bearer $INVOICEXML_API_KEY" \
-H "Content-Type: application/json" \
-d @invoice.json \
--output cii-en16931.xml
The credit note is the same call with the type code set to 381 in the invoice body, and the reverse-charge file is the same call with the VAT category set to AE on the lines. Every file is validated against the D16B schema and the EN 16931 CII rules before publishing, which is how we know the valid ones hold up and each broken one breaks exactly where this page says.
The invalid fixtures had to be produced by bypassing our own pipeline, because refusing to emit them is precisely its job. To check a file of your own, the CII validator takes an upload directly. If you need this XML inside a readable PDF instead, that is Factur-X.
Why sample files go stale
These were generated on 6 August 2026, against the EN 16931 CII rules 1.3.16 and the UN/CEFACT D16B schema.
Plain CII is the most stable target in this family: the CEN rule set updates roughly twice a year and the underlying UN/CEFACT schema moves slowly. That is genuinely less maintenance than the national profiles carry. What it does not mean is no maintenance, because the moment your invoices go to an actual country you inherit that country's rule set and its release calendar on top of this one, and most integrations that start on plain CII end up there.
On the InvoiceXML API the current artefacts are what runs, for the core and for every profile above it, with no SDK to upgrade and no redeploy when a rule set moves. Start with the free trial, or read how the CII API fits the rest of the family.