Receiving Peppol documents in Germany for your own company

Getting started with Peppol e-invoicing for your own German company: register and verify the company, pick up incoming documents, go live. VAT numbers under scheme 9930, XRechnung in UBL and CII alongside Peppol BIS 3, and Leitweg-IDs for public authorities.

This guide walks through everything needed to exchange Peppol documents for a company registered in Germany, assuming you are setting up your own German company, and that the company only receives documents over Peppol. Change any of the three answers at the top of the page to get the guide for a different situation.

What you are setting up

You are putting one company, your own or one you represent, on the Peppol network, so it can exchange invoices electronically with its customers and suppliers.

The setup is a one-time affair: registering the company and getting it verified takes a few minutes in the Recommand dashboard, and there is nothing to gain from automating something you do once. What you do integrate is the part that repeats: sending and receiving documents. Our existing integrations can also connect Recommand to accounting or invoicing software you already use, with no code at all.

A single team can hold several companies at no extra cost, useful if you run more than one legal entity, and the document volume of all of them counts towards one plan.

Onboarding companies that are not yours?

If you are building e-invoicing or Peppol integration into a product for your own customers, and will be registering their companies rather than only your own, switch the first answer above to Many companies. The API is the same; what changes is how companies, verification and billing are organised.

Peppol in Germany

Germany has no central platform: e-invoices travel directly between the parties, over Peppol, email or EDI. What the law prescribes is the content, a structured invoice following EN 16931, not the channel.

What is specific to Germany:

  • A B2B mandate in phases. Every German business has had to be able to receive structured e-invoices since 1 January 2025. Issuing them becomes mandatory from 1 January 2027 for businesses with a prior-year turnover above EUR 800,000, and from 1 January 2028 for the rest, with statutory exemptions.
  • XRechnung alongside Peppol BIS 3. XRechnung is the German specialisation (CIUS) of EN 16931, in UBL and in CII. German companies registered through Recommand receive both Peppol BIS 3 and XRechnung, and Recommand can write and read both.
  • The VAT number is the Peppol address. German businesses are published under scheme 9930 with their VAT number (USt-IdNr.), so a German Peppol address looks like 9930:DE123456788.
  • Public authorities are addressed by their Leitweg-ID. Invoices to German public authorities go to scheme 0204, and the same Leitweg-ID has to appear in the invoice as buyer reference (BT-10).
  • German sellers have extra mandatory fields. Peppol BIS 3 and XRechnung both require a German seller to state payment instructions and a contact phone number and email address.

Create your account and API credentials

  1. Sign up at app.recommand.eu/signup.
  2. Your account starts with a team. The team holds your company, your subscription and your document history, and you can invite colleagues to it.
  3. Create an API key on the API keys page. Note the key, the secret and your team ID.
  4. Check the credentials with a request that needs no data of its own:
curl -X GET https://app.recommand.eu/api/core/auth/verify \
  -u key_xxx:secret_xxx

It answers {"success": true} when the key and secret are accepted, and 401 when they are not, so it tells you about your credentials and nothing else.

All endpoints in this guide live under https://app.recommand.eu/api/v1 and accept HTTP Basic authentication with the key as username and the secret as password. If you would rather not store a long-lived secret, JWT API keys and OAuth2 with a JWT assertion are available too, see the authentication guide.

Not planning to write any code?

Sending and receiving can also be driven entirely from the dashboard or through an integration, and each section below says how. The dashboard is available in English, Dutch, French and German; pick your language on the account page.

Try it safely first

You do not have to get anything right the first time. Everything below, adding the company, registering it, sending and receiving, can be done in a playground team first, where nothing is delivered over the real Peppol network, nothing is registered on it, and nothing is billed.

Open the team switcher at the top of the dashboard and pick Add playground. Give it a name, leave the Peppol Test Network box unticked, and you are switched into the new team straight away. There is nothing to set up beyond that.

Add a company to that team and use it as both sender and recipient to watch a document travel end to end. When the flow does what you want, repeat it once in your real team.

Two things worth knowing before you start:

  • POST /:companyId/generate takes the same body as the send endpoint minus the email delivery options, which have no meaning when nothing is delivered, and returns the exact XML that sending would produce, fully validated, without transmitting, storing or billing it. Raw XML is not accepted here: there is nothing to generate from a document you already have. It also returns the resolved documentType, doctypeId and processId.
  • Failure addresses. In a playground that is not connected to the Peppol Test Network, sending to 404:404 or 0208:1234567894 always fails, so you can exercise your error handling. Any other unregistered recipient is skipped without an error.

A playground stays useful after you are live, too: it is the safest place to try a new invoice layout or a new integration. See how can I test without sending real invoices.

Playgrounds are separate

Playground companies are not registered on the Peppol network and playground documents never leave it, so nothing you do there affects your real company.

Register the company

You are registering one company, once, so the dashboard is the shortest path.

  1. Open Companies and start the company wizard.
  2. Fill in the legal name, address and country, plus the identifiers described in the next section.
  3. Choose whether the company should also receive documents over Peppol, or only send them.
  4. Save. The company is registered on the Peppol network as part of this step: its identifiers and the document types for its country are set up for you.

Right after saving, the dashboard offers the verification step, which the section below covers. Note the company's ID from its detail page. Every API call for sending and receiving takes it in the path.

Rather create it from code?

The create company endpoint does exactly the same thing, and returns the company id and a verificationUrl in one response. It is worth using when company creation is part of a flow you are automating, which is likely the case if you are registering many companies. Switch the first answer above to Many companies for that version.

More than one entity?

Add each legal entity as its own company: run the wizard again. There is no per-company fee, and all of them share your document volume.

Three identifiers that are easy to mix up

A German invoice involves three different identifiers. Only the first one is a Peppol address:

IdentifierWhat it is forWhere it goes
Participant identifierThe company's address on the Peppol networkA company identifier, e.g. 9930:DE123456788
Legal registration identifierThe register entry, e.g. HRB 12345 B, shown on the invoice (BT-30)enterpriseNumber, with an optional enterpriseNumberScheme
Buyer reference (BT-10)The buyer's routing reference; for an authority, its Leitweg-IDbuyerReference on the document

German identifiers and Peppol address

FieldGerman value
country"DE"
vatNumberDE + 9 digits, e.g. DE123456788
enterpriseNumberOptional: the commercial register number
enterpriseNumberSchemeOptional: leave it out unless the buyer expects one
company.json
{
  "name": "Beispiel GmbH",
  "address": "Musterstraße 1",
  "postalCode": "10115",
  "city": "Berlin",
  "country": "DE",
  "enterpriseNumber": "HRB 12345 B",
  "vatNumber": "DE123456788"
}

The VAT number is checked against the German format and its check digit, and registered as the company's Peppol identifier: 9930: followed by the VAT number. The register number is never registered as a Peppol identifier.

Without a VAT number

A company without a VAT number gets no identifier by default. Following the German identifier guideline, add one of these yourself with the create identifier endpoint or in the dashboard:

  • 0088: the company's GS1 Global Location Number (GLN), 13 digits
  • 9918: the company's IBAN

Both are checked for their check digits.

Public authorities: the Leitweg-ID

A German public authority receives invoices under scheme 0204 with its Leitweg-ID, for example 0204:991-33333TEST-33. Only add a 0204 identifier for a public authority that receives through Recommand, using the exact Leitweg-ID it was assigned; its check digits are verified. The older Leitweg-ID scheme 9958 is deprecated on Peppol and is refused.

Which identifier you send from

A company sends from the identifier with the lowest scheme, but never from a Leitweg-ID: that one only names an authority's invoice reception. An invoice to a Leitweg-ID always goes out under the company's VAT number (9930) or, without one, its GLN (0088), the sender identifiers the federal invoice portals list.

Registering as a recipient

To receive documents, the company must be published as a recipient on an SMP (Service Metadata Publisher). That is what isSmpRecipient does, and it is the default:

{
  "isSmpRecipient": true
}

What that means:

  • The company becomes findable on the Peppol network: any sender can look it up and deliver to it via the Peppol network.
  • Recipient registration is exclusive. If the company is already registered for receiving through another Peppol provider, registration fails until it is deregistered there, or until you hand us a migration key from that provider (see below).
  • The document types the company accepts are registered along with it, based on its country. Which ones those are is covered further down.
  • The company is only published once it is verified.

Moving from another provider with a migration key

If the company already receives through another Peppol provider, ask that provider for a migration key for each identifier you want to move. Submit the key when adding the identifier, or use the migration endpoint for an existing identifier. See Moving from another provider with a migration key for the requests, verification requirements and possible outcomes.

Moving an existing German registration

Recipient registration is exclusive: a German company that already receives through another Peppol provider has to be deregistered there before it can be registered with Recommand, unless that provider issues a migration key, which moves the registration over without a gap.

If you do not know who the current provider is, look the VAT number up as a recipient (9930:DE123456788): the verify endpoint returns the SMP it is published on, which names the provider to ask.

Verify the company

A company cannot exchange documents on Peppol until an authorised representative has confirmed their identity. The company object exposes this as isVerified, and it stays false until the check is done.

For German companies the flow is short:

  1. Open the verification URL (from the create-company response, the dashboard, or a fresh one from the verify company endpoint).
  2. The representative fills in their name and completes the identity check.
  3. isVerified flips to true and the company is published on the Peppol network.

In some cases manual verification by our team will be required. If that's the case, isVerified will remain false until this manual verification is completed. The user is informed of this in the verification process.

Verifying once, in the dashboard

You have one company, and it is verified once. There is nothing here worth automating: open Companies in the dashboard, pick the company and start verification. If you are authorised to act for the company, complete the check yourself; otherwise use the button to forward the link to whoever is.

The page is self-contained and works in any browser. The person completing it does not need a Recommand account.

That is the whole step. From here on the API takes over: sending and receiving documents is what you actually integrate.

Changing identifiers resets verification

Updating the company's vatNumber or enterpriseNumber sets isVerified back to false, and the company has to be verified again before it can exchange documents.

Document types registered for you

When you register a German company as a recipient, it is published for Peppol BIS 3 and for XRechnung 3.0 in both syntaxes, so senders can reach it with the European or the German flavour of EN 16931:

Document typeProcess
Invoice (Peppol BIS 3 UBL)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
Credit note (Peppol BIS 3 UBL)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
Invoice (XRechnung 3.0 UBL)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
Credit note (XRechnung 3.0 UBL)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0
Invoice and credit note (XRechnung 3.0 CII)urn:fdc:peppol.eu:2017:poacc:billing:01:1.0

Whichever of these a sender picks, you get the same parsed invoice or credit note out of the API, with the original XML stored next to it.

Need more document types, such as self-billing, message level responses, invoice responses? Register the combinations you want with the create company document type endpoint.

Pick up incoming documents

Once the company is published as a recipient, everything sent to it arrives in Recommand automatically. There are two ways to get the documents into your own systems.

Register an endpoint once with the create webhook endpoint and events are pushed to you as they happen, document.received among them:

curl -X POST https://app.recommand.eu/api/v1/webhooks \
  -u key_xxx:secret_xxx \
  -H "Content-Type: application/json" \
  -d @create-webhook.json
create-webhook.json
{
  "url": "https://your-app.example/webhooks/recommand",
  "companyId": null,
  "secret": "your_webhook_signing_secret"
}

Pass a secret and verify the HMAC SHA-256 signature on every delivery before you trust the payload, then acknowledge with a 200 before doing the heavy processing. Both are covered in working with webhooks.

Polling the inbox

If you would rather pull, the inbox endpoint lists unread documents, and mark as read drops one off the list once your system has it. Fetch details, the original XML or a rendered PDF from the documents endpoints.

Receiving without writing code

  • In the dashboard. Incoming invoices appear under Sent and received, with the original XML, a readable rendering, attachments and the delivery history.
  • By email. Add notification email addresses per company so incoming documents land in the mailbox your bookkeeping already watches, attachments included. See email delivery and notifications.
  • In your accounting software. Forward incoming documents straight to Exact Online, Yuki, ClearFacts or another supported tool, see integrations.

Two things worth setting up early, whichever route you take:

  • Labels and suppliers to keep documents organised as volume grows, see suppliers and labels.
  • Rules to act on incoming documents automatically: forwarding, labelling, notifying, see rules.

The full picture, including retries and idempotency, is in receiving documents.

Going live

A short list before you start sending or receiving real invoices:

  • A valid subscription, so sending is not blocked. Playgrounds skip that check; production does not.
  • The company verified, with isVerified true. Until then it cannot exchange documents.
  • Errors surfaced, not swallowed. Validation errors name the field that is wrong; put that in front of whoever can fix it rather than logging it.
  • Webhook endpoint hardened, if you took that route: signature verification, a fast 200, retries and idempotency on your side.
  • One real document sent and received, ideally between two companies you control, so you have seen both ends.
  • Notification addresses set, so incoming documents also reach a mailbox somebody reads.

Tell your customers and suppliers

Once you are live, your Peppol address is public on the network: suppliers can find and reach you without any action from you. Ask customers who still email PDFs to switch, and let your accountant know where the documents now land.

Where to get help

  • Troubleshooting. Common rejections, delivery failures and validation errors are collected in the troubleshooting guide.
  • Questions. The FAQ covers Peppol, addressing, VAT and billing.
  • Email. support@recommand.eu:include the company ID and, for a delivery problem, the document ID.
  • Discord. Join the server for release announcements and quick questions.
  • Keep track of changes. New endpoints and behaviour are recorded in the changelog.