What is a Leitweg-ID, and how to put it on a Stripe invoice
By evoicely · Last checked 19 October 2026
A Leitweg-ID is the routing ID a German public authority gives you so your e-invoice reaches the right office.
It goes into the buyer reference of the invoice (business term BT-10). You get it from the buyer, usually with the order; you can't look it up or work it out yourself.
Stripe has no field for it, so store it on each invoice as metadata, for example under the key leitweg_id.
What it is
The federal government and the states agreed on one format for addressing e-invoices to public bodies, the Leitweg-ID. Its format specification is maintained by KoSIT as part of the XRechnung standard. Federal and state governments assign the actual IDs themselves (Leitweg-ID format specification 2.0.2, KoSIT).
In an XRechnung the Leitweg-ID goes into BT-10 Buyer reference. XRechnung makes BT-10 mandatory for every invoice (rule BR-DE-15). Business customers have no Leitweg-ID; with them, any reference you agree on goes in BT-10, such as a PO or customer number (XRechnung 3.0.2 specification).
When you need one
- Invoices to federal authorities. The federal e-invoicing ordinance requires every e-invoice to contain at least a Leitweg-ID, bank details, payment terms and the seller's email address (§ 5 ERechV).
- Invoices to states and municipalities. Several states also require it. Some states and municipalities use their own reference instead, which then goes in the same field (XRechnung specification).
- Peppol. When you send Peppol BIS Billing 3.0 to a German public body, BT-10 must contain the Leitweg-ID (KoSIT guideline on Peppol identifiers in Germany).
These public procurement rules apply alongside the VAT rules on B2B e-invoicing, not instead of them. Where they differ, you have to meet the stricter one (BMF letter of 15 October 2026, nos. 24–25).
Format
A Leitweg-ID has three parts separated by hyphens, and is 5 to 46 characters long:
| Part | Required | Format |
|---|---|---|
| Coarse address (Grobadressierung) | Yes | 2 to 12 digits, built from the official regional key: state or federal government (2 digits, 99 for the federal government), then optionally administrative district, county and municipality. |
| Fine address (Feinadressierung) | No | Up to 30 letters A–Z and digits, not case-sensitive. Each state or the federal government decides how it's used. |
| Check digits | Yes | 2 digits, ISO/IEC 7064 MOD 97-10, the same method as an IBAN. |
The format specification's own example is 04011000-1234512345-06. We use it on this page; it is an illustration, not an ID to invoice against.
Checking the digits catches typos before an invoice bounces. Remove the hyphens, replace letters with numbers (A = 10 … Z = 35), and the result modulo 97 must be 1:
def leitweg_id_checks_out(lid: str) -> bool:
digits = "".join(str(int(c, 36)) for c in lid.replace("-", "").upper())
return int(digits) % 97 == 1
leitweg_id_checks_out("04011000-1234512345-06") # True
leitweg_id_checks_out("04011000-1234512345-07") # FalseA valid check digit only means the ID is well-formed, not that it exists or belongs to your buyer.
Where to get it
From the buyer. The format specification says the buyer usually passes it on with the specific order. If you don't have it, ask the office that placed the order. Don't build one from the format rules; the fine address is assigned on the public-sector side and can't be derived.
Don't mix it up with a Peppol ID. Public bodies on Peppol use the Leitweg-ID scheme (code 0204) for their Peppol participant ID as well, but the Peppol ID that receives the message and the Leitweg-ID in BT-10 can differ.
KoSIT's example: Peppol ID 0204:04000000-FHBXLAND-82, Leitweg-ID 04000000-900X44X06-60 (KoSIT guideline on Peppol identifiers, linked above).
Putting it on a Stripe invoice
Stripe's Invoice object has no buyer reference field. There are two places for it:
metadata: key-value pairs for your own systems, not shown to the customer (up to 50 keys, values up to 500 characters). This is where a converter can read it.custom_fields: up to 4 name/value pairs printed on Stripe's invoice PDF. In the Dashboard you add them under Advanced options in the invoice editor. Use this if the Leitweg-ID should also be visible on the PDF.
(Stripe metadata, Update an invoice, Invoicing in the Dashboard)
With the API
Set it when you create the invoice, along with a custom field for the PDF:
curl https://api.stripe.com/v1/invoices \
-u "$STRIPE_SECRET_KEY:" \
-d customer=cus_123 \
-d "metadata[leitweg_id]=04011000-1234512345-06" \
-d "custom_fields[0][name]=Leitweg-ID" \
-d "custom_fields[0][value]=04011000-1234512345-06"Or add it to an existing invoice:
curl https://api.stripe.com/v1/invoices/in_123 \
-u "$STRIPE_SECRET_KEY:" \
-d "metadata[leitweg_id]=04011000-1234512345-06"Most fields are locked once an invoice is finalized, but metadata can still be updated on an open invoice (How invoicing works). Set custom fields while the invoice is still a draft, so they appear on the PDF.
Subscriptions and customer-level IDs
Stripe doesn't copy metadata from one object to another. A leitweg_id on the Customer does not end up on its invoices.
Subscription metadata is copied, but into parent.subscription_details.metadata, not into the invoice's own metadata.
A tool that only reads the invoice's own metadata won't see either. If yours does, copy the Leitweg-ID to each invoice:
Stripe keeps a renewal invoice as a draft for about an hour after the invoice.created event, which is enough time to set it from a webhook
(Stripe metadata, Subscription invoices).
The fine address can route to a specific unit inside an authority, so take the ID from each order rather than assuming one per customer.
What ends up in the XML
This is what the buyer reference looks like in an XRechnung (UBL syntax) and in a ZUGFeRD file (CII syntax), generated from fictional data by the same code evoicely uses. Both complete files pass validation in our test suite: the XRechnung with the official KoSIT validator, the ZUGFeRD XML with Mustang.
<!-- XRechnung, UBL -->
<cbc:BuyerReference>04011000-1234512345-06</cbc:BuyerReference>
<!-- ZUGFeRD / CII, inside rsm:SupplyChainTradeTransaction -->
<ram:ApplicableHeaderTradeAgreement>
<ram:BuyerReference>04011000-1234512345-06</ram:BuyerReference>
...
</ram:ApplicableHeaderTradeAgreement>evoicely's converter reads leitweg_id, falling back to buyer_reference for business customers who gave you another reference.
It looks in the invoice's own metadata first, then the subscription's (parent.subscription_details.metadata), then the Customer's, so a Leitweg-ID stored once on the Customer is enough.
If none is set, it uses your Stripe invoice number, which satisfies BR-DE-15 but won't route an invoice inside a public authority. For public-sector buyers, always set leitweg_id.
For credit notes, it uses the metadata of the invoice being credited.
Related guides
- Mapping a Stripe invoice to EN 16931: every other field, and what Stripe doesn't store.
- XRechnung vs ZUGFeRD: which format a public-sector or business customer needs.
- Germany's e-invoicing mandate for Stripe users: who has to send e-invoices, and from when.
Where evoicely fits
evoicely is being built to turn your Stripe invoices into XRechnung and ZUGFeRD files with the Leitweg-ID in place, read from the metadata described above, and to check each file with the official validators. It's planned, not available yet. Join the waitlist.
This is general information, not legal or tax advice. Check what applies to your business with your tax advisor.