Guides
Generating XRechnung invoices with the InvoiceSpec API
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 onhttp://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.
{"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:
buyerReferenceis required for XRechnung. TheBR-DE-15Schematron rule rejects invoices without it. For public-sector invoices this is the Leitweg-ID.- The seller
contactgroup is required under XRechnung rulesBR-DE-5,BR-DE-6, andBR-DE-7. You need a contact point, telephone, and email. documentTotalsis empty. In AUTO mode the engine calculates line net amounts, VAT, and the payable total from the line data you provide.config.versionis 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.
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.
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 exampleBR-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.
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