XRechnung API — Generate & Validate German E-Invoices

Add XRechnung 3.0.2 to your software without implementing UBL/CII serialization, KoSIT validation, and ongoing specification updates yourself. Generate and validate through one API built around EN 16931 — for developers integrating German e-invoicing.

  • Generate & validate
  • UBL 2.1 + CII D16B
  • KoSIT-validated

No credit card required · 500 free trial invoices, 30-day expiry.

Get an API key instantly and generate your first XRechnung invoice in under a minute.

XRechnung version
3.0.2
XML syntaxes
2
Semantic model
EN 16931
Data retention
0

JSON Input

Canonical invoice data

InvoiceSpec Engine

Maps to EN 16931 & validates

Compliant Output

XML

Generate XRechnung

Send a canonical JSON invoice; receive a KoSIT-validated XRechnung 3.0.2 XML document. The example below uses a real minimal invoice body — swap in your API key and it runs.

POST/v1/invoice/xrechnungReal output
Request — application/json
{
"invoice": {
"invoiceNumber": "INV-DEMO-001",
"issueDate": "2025-07-01",
"invoiceTypeCode": "380",
"currencyCode": "EUR",
"buyerReference": "991-12345-67",
"seller": {
"name": "Acme GmbH",
"legalRegistrationIdentifier": "HRB98765",
"vatIdentifier": "DE123456789",
"electronicAddress": "DE123456789",
"electronicAddressSchemeId": "9930",
"postalAddress": {
"addressLine1": "Musterstr. 1",
"city": "Berlin",
"postcode": "10115",
"countryCode": "DE"
},
"contact": {
"contactPoint": "Max Mustermann",
"telephone": "+49 30 12345678",
"email": "billing@acme.de"
}
},
"buyer": {
"name": "Example Corp",
"electronicAddress": "FR12345678901",
"electronicAddressSchemeId": "9930",
"postalAddress": {
"addressLine1": "12 Rue de Rivoli",
"city": "Paris",
"postcode": "75001",
"countryCode": "FR"
}
},
"deliveryInformation": {
"actualDeliveryDate": "2025-07-01"
},
"paymentInstructions": {
"meansCode": "30",
"creditTransfer": {
"accountIdentifier": "DE89370400440532013000"
}
},
"documentTotals": {},
"vatBreakdowns": [
{
"vatCategoryCode": "S",
"vatCategoryRate": 19
}
],
"invoiceLines": [
{
"lineIdentifier": "1",
"quantity": 10,
"unitCode": "C62",
"priceDetails": {
"netPrice": 150
},
"lineVatInformation": {
"vatCategoryCode": "S",
"vatRate": 19
},
"itemInformation": {
"name": "Consulting Services"
}
}
]
},
"config": {
"spec": "xrechnung",
"syntax": "cii"
}
}
Response — application/xml
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<rsm:CrossIndustryInvoice xmlns:udt="urn:un:unece:uncefact:data:standard:UnqualifiedDataType:100" xmlns:ram="urn:un:unece:uncefact:data:standard:ReusableAggregateBusinessInformationEntity:100" xmlns:qdt="urn:un:unece:uncefact:data:standard:QualifiedDataType:100" xmlns:rsm="urn:un:unece:uncefact:data:standard:CrossIndustryInvoice:100">
<rsm:ExchangedDocumentContext>
<ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:ID>urn:fdc:peppol.eu:2017:poacc:billing:01:1.0</ram:ID>
</ram:BusinessProcessSpecifiedDocumentContextParameter>
<ram:GuidelineSpecifiedDocumentContextParameter>
<ram:ID>urn:cen.eu:en16931:2017#compliant#urn:xeinkauf.de:kosit:xrechnung_3.0</ram:ID>
</ram:GuidelineSpecifiedDocumentContextParameter>
</rsm:ExchangedDocumentContext>
<rsm:ExchangedDocument>
<ram:ID>INV-DEMO-001</ram:ID>
<ram:TypeCode>380</ram:TypeCode>
<ram:IssueDateTime>
<udt:DateTimeString format="102">20250701</udt:DateTimeString>
</ram:IssueDateTime>
</rsm:ExchangedDocument>
<rsm:SupplyChainTradeTransaction>
<ram:IncludedSupplyChainTradeLineItem>
<ram:AssociatedDocumentLineDocument>
<ram:LineID>1</ram:LineID>
</ram:AssociatedDocumentLineDocument>
<ram:SpecifiedTradeProduct>
<ram:Name>Consulting Services</ram:Name>
</ram:SpecifiedTradeProduct>
<ram:SpecifiedLineTradeAgreement>
<ram:NetPriceProductTradePrice>
<ram:ChargeAmount>150.0</ram:ChargeAmount>
<ram:BasisQuantity>1</ram:BasisQuantity>
</ram:NetPriceProductTradePrice>
</ram:SpecifiedLineTradeAgreement>
<ram:SpecifiedLineTradeDelivery>
<ram:BilledQuantity unitCode="C62">10</ram:BilledQuantity>
</ram:SpecifiedLineTradeDelivery>
<ram:SpecifiedLineTradeSettlement>
<ram:ApplicableTradeTax>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradeSettlementLineMonetarySummation>
<ram:LineTotalAmount>1500.00</ram:LineTotalAmount>
</ram:SpecifiedTradeSettlementLineMonetarySummation>
</ram:SpecifiedLineTradeSettlement>
</ram:IncludedSupplyChainTradeLineItem>
<ram:ApplicableHeaderTradeAgreement>
<ram:BuyerReference>991-12345-67</ram:BuyerReference>
<ram:SellerTradeParty>
<ram:Name>Acme GmbH</ram:Name>
<ram:SpecifiedLegalOrganization>
<ram:ID>HRB98765</ram:ID>
</ram:SpecifiedLegalOrganization>
<ram:DefinedTradeContact>
<ram:PersonName>Max Mustermann</ram:PersonName>
<ram:TelephoneUniversalCommunication>
<ram:CompleteNumber>+49 30 12345678</ram:CompleteNumber>
</ram:TelephoneUniversalCommunication>
<ram:EmailURIUniversalCommunication>
<ram:URIID>billing@acme.de</ram:URIID>
</ram:EmailURIUniversalCommunication>
</ram:DefinedTradeContact>
<ram:PostalTradeAddress>
<ram:PostcodeCode>10115</ram:PostcodeCode>
<ram:LineOne>Musterstr. 1</ram:LineOne>
<ram:CityName>Berlin</ram:CityName>
<ram:CountryID>DE</ram:CountryID>
</ram:PostalTradeAddress>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="9930">DE123456789</ram:URIID>
</ram:URIUniversalCommunication>
<ram:SpecifiedTaxRegistration>
<ram:ID schemeID="VA">DE123456789</ram:ID>
</ram:SpecifiedTaxRegistration>
</ram:SellerTradeParty>
<ram:BuyerTradeParty>
<ram:Name>Example Corp</ram:Name>
<ram:PostalTradeAddress>
<ram:PostcodeCode>75001</ram:PostcodeCode>
<ram:LineOne>12 Rue de Rivoli</ram:LineOne>
<ram:CityName>Paris</ram:CityName>
<ram:CountryID>FR</ram:CountryID>
</ram:PostalTradeAddress>
<ram:URIUniversalCommunication>
<ram:URIID schemeID="9930">FR12345678901</ram:URIID>
</ram:URIUniversalCommunication>
</ram:BuyerTradeParty>
</ram:ApplicableHeaderTradeAgreement>
<ram:ApplicableHeaderTradeDelivery>
<ram:ActualDeliverySupplyChainEvent>
<ram:OccurrenceDateTime>
<udt:DateTimeString format="102">20250701</udt:DateTimeString>
</ram:OccurrenceDateTime>
</ram:ActualDeliverySupplyChainEvent>
</ram:ApplicableHeaderTradeDelivery>
<ram:ApplicableHeaderTradeSettlement>
<ram:InvoiceCurrencyCode>EUR</ram:InvoiceCurrencyCode>
<ram:SpecifiedTradeSettlementPaymentMeans>
<ram:TypeCode>30</ram:TypeCode>
<ram:PayeePartyCreditorFinancialAccount>
<ram:IBANID>DE89370400440532013000</ram:IBANID>
</ram:PayeePartyCreditorFinancialAccount>
</ram:SpecifiedTradeSettlementPaymentMeans>
<ram:ApplicableTradeTax>
<ram:CalculatedAmount>285.00</ram:CalculatedAmount>
<ram:TypeCode>VAT</ram:TypeCode>
<ram:BasisAmount>1500.00</ram:BasisAmount>
<ram:CategoryCode>S</ram:CategoryCode>
<ram:RateApplicablePercent>19</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>
<ram:SpecifiedTradePaymentTerms>
<ram:Description>Payment due</ram:Description>
</ram:SpecifiedTradePaymentTerms>
<ram:SpecifiedTradeSettlementHeaderMonetarySummation>
<ram:LineTotalAmount>1500.00</ram:LineTotalAmount>
<ram:TaxBasisTotalAmount>1500.00</ram:TaxBasisTotalAmount>
<ram:TaxTotalAmount currencyID="EUR">285.00</ram:TaxTotalAmount>
<ram:GrandTotalAmount>1785.00</ram:GrandTotalAmount>
<ram:DuePayableAmount>1785.00</ram:DuePayableAmount>
</ram:SpecifiedTradeSettlementHeaderMonetarySummation>
</ram:ApplicableHeaderTradeSettlement>
</rsm:SupplyChainTradeTransaction>
</rsm:CrossIndustryInvoice>

Real engine output — a complete, KoSIT-validated XRechnung 3.0.2 CII document with seller/buyer parties, line items, VAT breakdown, and totals.

Try it with curl
curl
curl -X POST https://api.invoicespec.com/v1/invoice/xrechnung \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-H "Accept: application/xml" \
-d '{"invoice":{"invoiceNumber":"INV-DEMO-001","issueDate":"2025-07-01","invoiceTypeCode":"380","currencyCode":"EUR","buyerReference":"991-12345-67","seller":{"name":"Acme GmbH","legalRegistrationIdentifier":"HRB98765","vatIdentifier":"DE123456789","electronicAddress":"DE123456789","electronicAddressSchemeId":"9930","postalAddress":{"addressLine1":"Musterstr. 1","city":"Berlin","postcode":"10115","countryCode":"DE"},"contact":{"contactPoint":"Max Mustermann","telephone":"+49 30 12345678","email":"billing@acme.de"}},"buyer":{"name":"Example Corp","electronicAddress":"FR12345678901","electronicAddressSchemeId":"9930","postalAddress":{"addressLine1":"12 Rue de Rivoli","city":"Paris","postcode":"75001","countryCode":"FR"}},"deliveryInformation":{"actualDeliveryDate":"2025-07-01"},"paymentInstructions":{"meansCode":"30","creditTransfer":{"accountIdentifier":"DE89370400440532013000"}},"documentTotals":{},"vatBreakdowns":[{"vatCategoryCode":"S","vatCategoryRate":19}],"invoiceLines":[{"lineIdentifier":"1","quantity":10,"unitCode":"C62","priceDetails":{"netPrice":150},"lineVatInformation":{"vatCategoryCode":"S","vatRate":19},"itemInformation":{"name":"Consulting Services"}}]},"config":{"spec":"xrechnung","syntax":"cii"}}'

Validate XRechnung

Check an existing XRechnung XML against the 3.0.2 syntax and business rules before you send it. Upload the file and an optional version; the engine returns a structured validation report.

Request — curl
curl -X POST https://api.invoicespec.com/v1/invoice/xrechnung/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "file=@invoice-xrechnung.xml" \
-F 'request={"version":"3.0.2"}'
Response — application/json
{
"valid": false,
"version": "3.0.2",
"syntax": "CII",
"summary": { "errors": 1, "warnings": 0, "information": 0 },
"issues": [
{
"severity": "ERROR",
"code": "BR-DE-15",
"message": "An electronic address (BT-34) of the Seller is required."
}
],
"requestId": "req_01HXYZ..."
}

A failed validation is not an HTTP error — the endpoint returns 200 OK with valid: false and a structured issue list.

Try the free XRechnung validator →

No signup required — validate a file or paste XML directly in the browser.

What triggers this error

The seller block above is missing the electronicAddress field (BT-34). The engine catches this and returns the exact rule code so you can fix it programmatically.

Cause — missing BT-34
// Seller block missing the electronicAddress (BT-34)
"seller": {
"name": "Acme GmbH",
"vatIdentifier": "DE123456789",
"postalAddress": {
"addressLine1": "Musterstr. 1",
"city": "Berlin",
"postcode": "10115",
"countryCode": "DE"
}
// ← electronicAddress and electronicAddressSchemeId omitted
}

Validation-error handling

Validation errors are returned as data, not as HTTP failures, so you can handle them programmatically. Each issue carries a normalized severity (ERROR, WARNING, INFORMATION), the official rule code (e.g. BR-DE-15), and a human-readable message. Inspect the issues array, map each finding back to the offending invoice field, and re-run generation or validation once corrected.

Your integration stays stable while XRechnung evolves

XRechnung, EN 16931 rules, and validator configurations evolve over time. InvoiceSpec tracks supported releases underneath the API so your team doesn't have to maintain the standards implementation itself.

The exact version used for every call is returned in the response, and the validation endpoint accepts an optional version field so you can pin a spec version until you are ready to migrate to a new one.

Supported syntaxes & version

XRechnung version 3.0.2, serialized in either of the two EN 16931-compliant XML syntaxes.

CII D16B

Cross Industry Invoice, UN/CEFACT CII D16B syntax — the default XRechnung output format and the most widely deployed.

UBL 2.1

Universal Business Language 2.1 — OASIS UBL syntax, selectable via the request config for systems that consume UBL.

Typical integration workflow

From structured invoice data to an XRechnung document ready for your existing delivery workflow — the engine handles the format mapping and rule checking.

  1. 1

    Send structured invoice data

    POST a canonical JSON invoice to /v1/invoice/xrechnung. No XML hand-authoring — the engine maps your data to the XRechnung model.

  2. 2

    Engine generates and validates

    InvoiceSpec maps your data to EN 16931, serializes it as CII or UBL, and runs the official KoSIT validator before returning the document.

  3. 3

    Validate before you send

    POST an existing XRechnung XML to /v1/invoice/xrechnung/validate to check it against the 3.0.2 syntax and business rules before delivery.

  4. 4

    Handle the result

    A valid document comes back as XML; a failed validation returns 200 OK with a structured issue list you can act on programmatically.

Frequently asked questions

Which XRechnung version does the API support?

XRechnung version 3.0.2, the current release. The validation endpoint accepts an optional version field so you can pin the validation package explicitly.

Which XML syntaxes can I generate?

CII D16B (the default) and UBL 2.1. Select the syntax via the request config; both are valid XRechnung 3.0.2 serializations built on EN 16931.

How are validation errors returned?

Validation failures are not HTTP errors. The endpoint returns 200 OK with valid: false and a structured issues array (severity, code, message), so you can surface and fix each finding programmatically.

What happens when a new XRechnung version or spec update ships?

InvoiceSpec tracks XRechnung and EN 16931 releases and rolls the supported version forward. The version used for each call is returned in the response, and you can pin a version on validation until you are ready to migrate.

Is this only for German invoices?

InvoiceSpec currently focuses on German e-invoicing. XRechnung is Germany's EN 16931 implementation for structured electronic invoices, which is also available as a first-class capability with its own endpoints. Additional countries and delivery networks would only be listed here once they are actually supported.

Start with 500 free trial invoices

Generate and validate XRechnung invoices against the real API — no credit card required to get started.

  • Generate & validate
  • UBL 2.1 + CII D16B
  • KoSIT-validated

API key in seconds — first XRechnung invoice in under a minute.