DEEN
Reverse charge

Reverse charge on German e-invoices: VAT category AE, § 13b UStG and EU customers (ZUGFeRD/XRechnung)

Short answer: With reverse charge the customer owes the VAT, not the supplier. The invoice shows no VAT, carries the note "Steuerschuldnerschaft des Leistungsempfängers" (German for "reverse charge") and, for customers in other EU countries, both VAT IDs. In an EN 16931 e-invoice that means VAT category AE, rate 0, VAT amount 0, exemption reason VATEX-EU-AE and the buyer's VAT ID in the XML. The German e-invoice mandate only applies when both sides are established in Germany, for example construction services under § 13b UStG. Under German law, cross-border B2B invoices can be e-invoices, but they don't have to be. Below: the rules, the XML fields, typical validation errors and a curl and TypeScript example we ran against the production API.

This guide is for teams outside Germany that sell to or buy from German businesses, and for international companies with a German entity that bills customers across the EU. German statutes are cited by their German names: UStG is the German VAT Act, BMF the Federal Ministry of Finance.

When reverse charge applies

Reverse charge shifts the VAT liability from the supplier to the customer. Seen from Germany, there are two typical groups.

1. B2B services between businesses in different EU countries

The EU VAT Directive sets the place of supply for services to a business at the place where the customer has established its business (Art. 44), and makes the customer liable for the VAT when the supplier is not established in that country (Art. 196). Germany implements this in § 3a(2) UStG. If a German company sells a SaaS subscription to an SAS in Paris, the place of supply is France. No German VAT is due; the customer accounts for it in France.

For the German seller's invoice, § 14a(1) UStG applies: it must carry the note "Steuerschuldnerschaft des Leistungsempfängers", show the seller's and the customer's VAT IDs, and be issued by the 15th day of the month after the month of supply. The Directive asks for the same content in English terms: the customer's VAT ID and the mention "Reverse charge" (Art. 226 points 4 and 11a).

§ 3a(2) UStG applies subject to its paragraphs 3 to 8 and §§ 3b and 3e. A service connected with land, for example, is supplied where the land is. Check special cases with your tax advisor.

The other direction is § 13b(1) UStG: if a business from another EU country supplies such a service to a company in Germany, the German customer owes the VAT in Germany (§ 13b(5)). The invoice then comes from the foreign supplier. Under Art. 219a(2)(a)(i) of the Directive, a supplier that is not established in the country of supply invoices under the rules of its own country when the customer owes the VAT, unless the customer issues the invoice itself (self-billing). A French supplier billing a German customer under reverse charge therefore follows French invoicing rules, not German ones.

2. Domestic cases inside Germany under § 13b(2) UStG

VAT liability can also shift between two German businesses. § 13b(2) UStG lists, among others:

For construction and building cleaning, the customer only owes the VAT if it provides such services itself on a sustained basis. That is assumed when the tax office has confirmed it with a certificate valid for at most three years (§ 13b(5) UStG). Under § 14a(5) UStG the invoice must carry the note "Steuerschuldnerschaft des Leistungsempfängers" and must not state VAT separately. All other mandatory invoice details still apply, see German e-invoice mandatory fields.

EC Sales List

A German business that supplies § 3a(2) services in another EU country, where the customer owes the VAT, also reports them in the EC Sales List (Zusammenfassende Meldung) to the Federal Central Tax Office, by the 25th day after the end of the calendar quarter (§ 18a(2) UStG). Intra-Community supplies of goods are in principle reported monthly (§ 18a(1) UStG). The report runs alongside the invoice; fakturai does not create it.

Does the German e-invoice mandate apply to reverse charge?

Under § 14(2) sentence 2 no. 1 UStG, an invoice to another business for its business purposes must be an e-invoice if both the supplier and the customer are established in Germany. Established means registered office, place of management, a fixed establishment involved in the supply or, failing those, residence or habitual abode in Germany. Reverse charge on its own does not exempt an invoice from the e-invoice rules; what counts is where both sides are established.

CaseExtra invoice detailsGerman e-invoice mandate?
A German business sells SaaS, consulting or development to a business in France, Austria, the Netherlands and so on (§ 3a(2) UStG)§ 14a(1) UStG: "Steuerschuldnerschaft des Leistungsempfängers", both VAT IDs, invoice by the 15th of the following monthNo, the customer is not established in Germany. An e-invoice is allowed if the customer agrees.
A business in another EU country sells such a service to a business in Germany (§ 13b(1) UStG)The foreign supplier issues the invoice; the German customer owes the VATNo, as long as the supplier has no German fixed establishment involved in the supply.
Construction services to a German construction company (§ 13b(2) no. 4 UStG)§ 14a(5) UStG: "Steuerschuldnerschaft des Leistungsempfängers", no separately stated VATYes, both are established in Germany. Transition rules under § 27(38) UStG.
Building cleaning for a German cleaning company (§ 13b(2) no. 8 UStG)§ 14a(5) UStG, same as constructionYes, both are established in Germany.

The BMF letter of 15 October 2025, which amends the letter of 15 October 2024, says in para. 17 that the e-invoice rules also apply to invoices for supplies where the customer owes the VAT under § 13b UStG, if both supplier and customer are established in Germany. In the same letter the BMF adds to the VAT application decree (UStAE section 14.1(6)): if at least one of the businesses involved is not established in Germany, there is no obligation to issue an e-invoice. The invoice can then be issued on paper or, with the recipient's consent, as an e-invoice or in another electronic format.

For customers in other EU countries this means: a ZUGFeRD invoice under EN 16931 is a full invoice as long as the customer has agreed to receive invoices electronically (§ 14(1) sentence 5 UStG). Many teams with their own billing therefore use one format for all business customers. For domestic § 13b cases, the transition rules in § 27(38) UStG apply: for supplies up to the end of 2026, paper or, with consent, PDF is allowed if the invoice is sent by 31 December 2026; for supplies in 2027 only for businesses with at most 800,000 euros turnover in the previous year. Details: German e-invoice transition periods.

How EN 16931 encodes reverse charge

ZUGFeRD/Factur-X and XRechnung both implement EN 16931, so the VAT category rules are the same in both formats. Reverse charge uses code AE from the UNTDID 5305 code list, and the exemption reason uses VATEX-EU-AE from the VATEX list.

FieldMeaningValue for reverse charge
BT-151VAT category of the invoice lineAE
BT-152VAT rate of the invoice line0
BT-118VAT category in the VAT breakdown (BG-23)AE
BT-119VAT rate in the VAT breakdown0
BT-116Taxable amountSum of the AE line net amounts
BT-117VAT amount0.00
BT-120Exemption reason as texte.g. "Steuerschuldnerschaft des Leistungsempfängers" or "Reverse charge"
BT-121Exemption reason as codeVATEX-EU-AE
BT-31Seller VAT IDYour VAT ID
BT-48Buyer VAT IDYour customer's VAT ID

The BR-AE rules

This is what it looks like in the XML. The excerpt comes from the invoice we generated through the production API for this guide (example below):

<!-- Line 1 (line 2 is encoded the same way) -->
<ram:ApplicableTradeTax>
  <ram:TypeCode>VAT</ram:TypeCode>
  <ram:CategoryCode>AE</ram:CategoryCode>
  <ram:RateApplicablePercent>0</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>

<!-- Buyer VAT ID (BT-48) -->
<ram:SpecifiedTaxRegistration>
  <ram:ID schemeID="VA">FR99999999999</ram:ID>
</ram:SpecifiedTaxRegistration>

<!-- VAT breakdown (BG-23) -->
<ram:ApplicableTradeTax>
  <ram:CalculatedAmount>0.00</ram:CalculatedAmount>
  <ram:TypeCode>VAT</ram:TypeCode>
  <ram:ExemptionReason>Steuerschuldnerschaft des Leistungsempfängers</ram:ExemptionReason>
  <ram:BasisAmount>166.90</ram:BasisAmount>
  <ram:CategoryCode>AE</ram:CategoryCode>
  <ram:ExemptionReasonCode>VATEX-EU-AE</ram:ExemptionReasonCode>
  <ram:RateApplicablePercent>0</ram:RateApplicablePercent>
</ram:ApplicableTradeTax>

Common validation errors

ErrorRuleTypical cause
Lines at 0 % but category SBR-S-05The billing system sets the rate to 0 but leaves the category on standard.
AE without a buyer VAT IDBR-AE-02The VAT ID is missing in the customer record or is not passed on.
AE with 19 %BR-AE-05The category was switched, the rate was not.
VAT amount in the AE breakdown is not 0BR-AE-09VAT was still calculated, or rounding produced a cent.
No exemption reasonBR-AE-10The note only appears in free text or on the PDF, not in BT-120 or BT-121.
Category O together with VAT IDsBR-O-02"Not subject to VAT" was chosen, but seller or buyer VAT IDs were sent.

fakturai catches most of these before it builds a file and answers with HTTP 422 instead. The production messages, verbatim:

More rules and their causes: XRechnung validation errors. You can check an existing file, including one from another tool, without an account in the validator.

Other VAT categories at 0 %

Besides AE, EN 16931 has other categories with a 0 rate. Each follows its own rules:

CodeMeaningRequired in the XMLfakturai
ZZero rate, e.g. supplies of solar panels under § 12(3) UStGNo exemption reason allowed (BR-Z-10)vat_category "Z", vat_rate "0"
EExempt supplyExemption reason as text or code is required (BR-E-10)vat_category "E" plus vat_exemption_reasons.E with text and/or code
KIntra-Community supply of goods; invoice under § 14a(3) UStG with both VAT IDs by the 15th of the following monthBuyer VAT ID (BR-IC-02), delivery date (BR-IC-11), delivery country (BR-IC-12), exemption reason (BR-IC-10)vat_category "K"; delivery country from the buyer address, standard text and VATEX-EU-IC
GExport to a country outside the EUExemption reason (BR-G-10), seller VAT ID (BR-G-02)vat_category "G"; standard text and VATEX-EU-G
ONot subject to VATNo seller or buyer VAT ID (BR-O-02)not supported

For exempt supplies, § 14(4) sentence 1 no. 8 UStG also requires a note that an exemption applies. Which category and exemption reason fit your supply is a tax question, not a technical one.

Example: SaaS subscription for a customer in France

Say you run a SaaS product from a German company and bill November 2026 to a customer in Paris with a French VAT ID: three users on the Pro plan at 49 euros and an API add-on at 19.90 euros, net. Seller details (name, address, your VAT ID, bank account) come from your fakturai profile, and fakturai assigns the sequential invoice number. In the body you set vat_category to "AE" and vat_rate to "0" on each line. The line names are German because this is the exact body we sent:

{
  "invoice_date": "2026-11-01",
  "due_date": "2026-11-15",
  "service_period": {
    "start": "2026-11-01",
    "end": "2026-11-30"
  },
  "currency": "EUR",
  "buyer": {
    "name": "Exemple Logiciel SAS",
    "address": {
      "line_one": "12 Rue Exemple",
      "postcode": "75002",
      "city": "Paris",
      "country": "FR"
    },
    "vat_id": "FR99999999999",
    "contact_email": "factures@example.com"
  },
  "lines": [
    {
      "name": "Pro-Plan, 3 Nutzer (November 2026)",
      "quantity": "3",
      "unit": "C62",
      "unit_price": "49.00",
      "vat_rate": "0",
      "vat_category": "AE"
    },
    {
      "name": "API-Zusatzpaket 10.000 Aufrufe (November 2026)",
      "quantity": "1",
      "unit": "C62",
      "unit_price": "19.90",
      "vat_rate": "0",
      "vat_category": "AE"
    }
  ]
}

Saved as invoice.json, you send it to the API like this:

curl -X POST https://fakturai.de/api/v1/invoices \
  -H "Authorization: Bearer $FAKTURAI_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Accept: application/pdf" \
  -H "Idempotency-Key: kunde-fr-2026-11" \
  --data @invoice.json \
  --dump-header headers.txt \
  --output invoice.pdf

Without vat_exemption_reasons, fakturai writes the text "Steuerschuldnerschaft des Leistungsempfängers" (BT-120) and the code VATEX-EU-AE (BT-121) for AE. To use your own text, for example the English "Reverse charge" next to the German wording, send vat_exemption_reasons.AE.text. If you only send a text, fakturai writes no code; if you want both, also send code. All fields are in the API documentation and the JSON schema.

The same in TypeScript

If your backend builds the invoice itself, a small function is enough. It deliberately knows only two cases: a customer in Germany (19 %) or a business in another EU country with a VAT ID (AE). Anything else throws an error instead of silently setting the wrong category.

// reverse-charge.mts: Node.js with built-in fetch, no extra packages
const OTHER_EU = new Set([
  "AT", "BE", "BG", "CY", "CZ", "DK", "EE", "ES", "FI", "FR", "GR", "HR", "HU", "IE",
  "IT", "LT", "LU", "LV", "MT", "NL", "PL", "PT", "RO", "SE", "SI", "SK",
]);

type Customer = {
  name: string;
  street: string;
  postcode: string;
  city: string;
  country: string; // ISO 3166-1 alpha-2
  vatId?: string; // customer's VAT ID, checked for validity beforehand
  email?: string;
};
type Item = { name: string; quantity: string; unitPrice: string };

// Simplified rule for B2B services under § 3a(2) UStG. Exceptions (e.g. services
// connected with land) and supplies of goods: check with your tax advisor.
function vatFor(customer: Customer) {
  if (customer.country === "DE") return { vat_rate: "19.00" };
  if (OTHER_EU.has(customer.country) && customer.vatId) {
    return { vat_rate: "0", vat_category: "AE" };
  }
  throw new Error(`${customer.name}: non-EU customer or EU customer without VAT ID is not covered`);
}

export function buildInvoice(
  customer: Customer,
  items: Item[],
  period: { start: string; end: string },
  dueDate: string,
) {
  const vat = vatFor(customer);
  return {
    invoice_date: period.start, // subscription billed in advance
    due_date: dueDate,
    service_period: period,
    currency: "EUR",
    buyer: {
      name: customer.name,
      address: {
        line_one: customer.street,
        postcode: customer.postcode,
        city: customer.city,
        country: customer.country,
      },
      vat_id: customer.vatId,
      contact_email: customer.email,
    },
    lines: items.map((item) => ({
      name: item.name,
      quantity: item.quantity,
      unit: "C62",
      unit_price: item.unitPrice,
      ...vat,
    })),
  };
}

const body = buildInvoice(
  {
    name: "Exemple Logiciel SAS",
    street: "12 Rue Exemple",
    postcode: "75002",
    city: "Paris",
    country: "FR",
    vatId: "FR99999999999",
    email: "factures@example.com",
  },
  [
    { name: "Pro-Plan, 3 Nutzer (November 2026)", quantity: "3", unitPrice: "49.00" },
    { name: "API-Zusatzpaket 10.000 Aufrufe (November 2026)", quantity: "1", unitPrice: "19.90" },
  ],
  { start: "2026-11-01", end: "2026-11-30" },
  "2026-11-15",
);

const resp = await fetch("https://fakturai.de/api/v1/invoices", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.FAKTURAI_API_KEY}`,
    "Content-Type": "application/json",
    Accept: "application/pdf",
    "Idempotency-Key": "kunde-fr-2026-11",
  },
  body: JSON.stringify(body),
});
if (resp.status !== 201) throw new Error(`${resp.status}: ${await resp.text()}`); // 422 = check the data
const pdf = Buffer.from(await resp.arrayBuffer()); // ZUGFeRD/Factur-X PDF with embedded CII XML
console.log(resp.headers.get("x-facturai-invoice-number"), pdf.length, "bytes");

We type-checked the code with TypeScript 5.9 in strict mode and ran it on Node.js 26. It produces exactly the JSON body above and needs no extra packages; set FAKTURAI_API_KEY in the environment.

Tested against the production API

Tested on 5 November 2026: we sent exactly this body to https://fakturai.de/api/v1/invoices from a fresh test account with synthetic seller data. Response: HTTP 201, application/pdf, a PDF with an embedded factur-x.xml (EN 16931 profile). In the XML, both lines and the VAT breakdown carry category AE at rate 0, taxable amount 166.90 euros, VAT 0.00 euros, total 166.90 euros, the exemption reason "Steuerschuldnerschaft des Leistungsempfängers" with VATEX-EU-AE, and the customer's VAT ID. The PDF shows "0 % (AE)" in the VAT column, "MwSt. 0 % (AE) auf 166,90 €" in the totals and below it the note "(AE) Steuerschuldnerschaft des Leistungsempfängers. USt-IdNr. des Leistungsempfängers: FR99999999999", plus the country in the buyer address.

We then checked the file in the free validator: KoSIT result "accept", PDF/A compliant, 0 hard errors and 4 advisories. The fakturai engine check also reported Mustang "valid". The advisories come from Peppol and XRechnung rules (such as BR-DE-15 on the buyer reference, which is required for invoices to German public authorities) and were not counted as errors. A second request with the same Idempotency-Key returned HTTP 409 and no second invoice.

What fakturai does not do

Get started

Check an existing invoice for free, without an account, in the validator. To generate invoices, create a free account at /en/signup, add your seller profile with VAT ID and create an API key. The free plan includes 50 generated invoices per month; paid plans can't be booked yet. The REST endpoints and the MCP server are described in the API documentation.

Start free

Not tax advice

This page is a technical guide with an overview of the legal rules, not legal or tax advice. Whether and how reverse charge applies to your supplies is something to clarify with your tax advisor. fakturai is not bookkeeping software. It generates and checks the technical structure under EN 16931; content, tax treatment, delivery and archiving of your invoices stay your responsibility. There is no legal, tax or delivery guarantee.

Sources

All sources accessed on 6 November 2026. German statutes and BMF documents are only available in German.

Further reading