Guides

Generating XRechnung invoices with the InvoiceSpec API

By Mohamed Waleed

Generating XRechnung invoices with the InvoiceSpec API

This walkthrough shows you how to generate a compliant XRechnung XML file with a single API call. You will send one JSON payload, get back validated CII XML, and learn how the engine handles the EN 16931 rules and the German-specific CIUS additions so you do not have to maintain that logic yourself.

What you need before you start

  • An InvoiceSpec API key. You can get one from the dashboard in seconds.
  • The API base URL. For production, use https://api.invoicespec.com. For local development, the engine runs on http://localhost:8080.
  • A basic understanding of the invoice JSON schema. You do not need to know the XRechnung XML structure. The engine maps the JSON to CII XML for you.

The request structure

Every InvoiceSpec request has two top-level objects: invoice and config. The invoice object carries the business data: invoice number, parties, line items, taxes, and totals. The config object selects the output format, syntax, version, and calculation mode.

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.0 },
"lineVatInformation": { "vatCategoryCode": "S", "vatRate": 19 },
"itemInformation": { "name": "Consulting Services" }
}
]
},
"config": { "spec": "xrechnung", "syntax": "cii" }
}

A few things to notice in this payload:

  • buyerReference is required for XRechnung. The BR-DE-15 Schematron rule rejects invoices without it. For public-sector invoices this is the Leitweg-ID.
  • The seller contact group is required under XRechnung rules BR-DE-5, BR-DE-6, and BR-DE-7. You need a contact point, telephone, and email.
  • documentTotals is empty. In AUTO mode the engine calculates line net amounts, VAT, and the payable total from the line data you provide.
  • config.version is omitted, so the engine targets the latest active XRechnung release (currently 3.0.2). Pin an explicit version only when you need to lock the output to a specific release.

Send the request

The XRechnung generation endpoint is POST /v1/invoice/xrechnung. Pass your API key in the Authorization header as a bearer token.

bash
curl -X POST https://api.invoicespec.com/v1/invoice/xrechnung \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d @invoice.json

The response is a validated XRechnung CII XML document. The engine runs the KoSIT XSD schema and Schematron validation before returning it, so the XML you get back passes the same validation the recipient's system will run.

AUTO mode: let the engine calculate totals

The default calculationMode is AUTO. In this mode you provide the line quantities, unit prices, and VAT rates, and the engine computes the rest: line net amounts, the document-level totals, and the VAT breakdown amounts. This is the simplest way to generate an invoice and the right starting point for most use cases.

If you need full control, set calculationMode to MANUAL and provide every calculated field yourself. The engine validates that your totals are internally consistent and rejects the request if they are not. A third mode, PARTIAL, lets you provide some calculated fields and let the engine fill in the rest.

Choosing the XML syntax

XRechnung supports two XML syntaxes: CII and UBL. Set the config.syntax field to choose:

  • "cii" produces a Cross-Industry Invoice document. This is the default and the most widely supported syntax for XRechnung.
  • "ubl" produces a UBL 2.1 document. Some recipient systems prefer UBL, particularly in cross-border or Peppol contexts.

Both syntaxes carry the same EN 16931 data model and the same XRechnung business rules. The choice depends on what your recipient's system expects.

Validating an existing XRechnung file

If you already have a XRechnung XML file and want to check whether it passes validation, use the validate endpoint: POST /v1/invoice/xrechnung/validate. Send the raw XML in the request body and the engine runs the same KoSIT XSD and Schematron checks.

bash
curl -X POST https://api.invoicespec.com/v1/invoice/xrechnung/validate \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/xml" \
-d @xrechnung.xml

The response tells you whether the document is valid and, if it is not, lists every rule violation with the offending XPath and the rule identifier so you can fix the source data.

Error handling

When the engine rejects a request, it returns a structured error with a machine-readable code and a human-readable message. The most common errors when generating XRechnung are:

  • INVALID_INPUT: a required field is missing or a value violates the JSON schema. The error response names the field and the constraint.
  • VALIDATION_FAILED: the generated XML fails a KoSIT Schematron rule. The response includes the rule identifier (for example BR-DE-15), the XPath of the offending element, and a description so you can trace the failure back to the source field in your JSON.

Read the errors reference for the full list of error codes and recovery guidance.

Next steps

  • Read the full API reference for the XRechnung generate and validate endpoints, including every request field and response shape.
  • Browse the invoice JSON schema explorer to see every field, its type, and its EN 16931 business term mapping.
  • Try the free XRechnung Generator to generate a real invoice from a form without writing code.
XRechnungAPICIIdeveloperstutorial

Mohamed Waleed

Founder, InvoiceSpec

Mohamed is the founder of InvoiceSpec, where he builds the e-invoicing infrastructure software companies use to ship compliant XRechnung, ZUGFeRD, and EN 16931 documents without maintaining the logic in-house. He writes about German e-invoicing compliance in plain terms for the finance and ops teams who have to meet it.

Related posts

Guides

Generate and validate XRechnung, EN 16931, and ZUGFeRD with one API — endpoint-specific schemas, examples, and recovery guidance.

Read the API reference