Skip to content
Siddhartha Bhatia

How Peppol G3 certificates work — from the first lookup to the final receipt

18 min read

peppolpkias4security

What actually happens when you send a Peppol invoice?

Imagine you want to send a sensitive letter to someone you have never met.

You do not have their address. You do not know if they are who they say they are. And once the letter leaves your hands, you need proof that they actually received it — not just that it was delivered to their building.

Now add one more problem: the letter contains financial information, so it must be sealed in a way that only the intended recipient can open. Not the post office. Not anyone who intercepts it in transit. Only them.

That is, in plain terms, what every Peppol document exchange must solve. And G3 certificates are the mechanism that solves it — end to end, at every single step of the journey.

This post walks through the complete flow — six distinct moments where certificates do real work. If you have built an Access Point, you have seen the errors when any of these steps goes wrong; here is what is actually happening under the hood, and why it was designed this way.

A quick map before we begin

The Peppol network uses a four-corner model. Think of it as a relay race, not a direct throw.

CornerWho they arePlain English
C1 — SenderThe business sending the documentThe company raising the invoice
C2 — Sender APTheir Access PointTheir post office
C3 — Receiver APThe recipient's Access PointThe recipient's post office
C4 — ReceiverThe business receiving the documentThe company receiving the invoice

C1 and C4 are the actual businesses. They never talk directly to each other on the Peppol network. Their Access Points (C2 and C3) do all the technical heavy lifting.

The only hop where Peppol traffic actually flows is C2 to C3. That is where certificates earn their keep.

C1supplierC4buyerSML / SMPsigned metadata1C2 · Sender APsends + signsC3 · Receiver APverifies + receipts2TLS channel34AS4 message — signed, then encrypted5verify first6signed Receipt1SMP discovery — verify the SMP signature2TLS 1.2+ — server-auth only, no mTLS3encrypt — AES-128-GCM + RSA-OAEP for C34sign — XML-DSIG with C2’s private key5verify + decrypt — chain, CRL/OCSP, digests6signed Receipt — non-repudiation evidence
The whole journey at a glance. C1 and C4 never touch the Peppol network — every certificate operation happens on the C2 ↔ C3 hop (and its discovery lookup). Each numbered touchpoint gets its own figure below.

The certificate family: who holds what

Before walking through the flow, meet the players.

OpenPeppol — the organisation that runs the Peppol network — operates its own Certificate Authority (CA), hosted on DigiCert's platform (that detail matters later). Think of a CA as the passport office for the network. Every legitimate Access Point must get its identity documents from this office. No exceptions. Certificates from anyone else are not accepted.

The G3 PKI (Public Key Infrastructure) has three levels, like a family tree:

  • The Root CA sits at the top. It is kept offline, as root CAs are — sign the intermediates, then stay disconnected — and exists only to vouch for the level below it. You will never see this certificate appear in any actual transaction; its only job is to be the ultimate "I vouch for this" authority, and every trust decision on the network ultimately resolves to it. If it were ever compromised, every certificate on the network would need reissuing — which is exactly why it stays physically disconnected. The root certificate itself is valid January 2025 → January 2035, and since no chain can outlive its anchor, that is the expiry horizon for the entire G3 generation.
  • Two Intermediate CAs sit in the middle — one for Access Points (the AP CA), one for SMP operators (the SMP CA). These are the actual certificate factories. When you apply for your Peppol certificate as an AP operator, you deal with the AP Intermediate CA.
  • Leaf certificates are what your software uses day to day. AP operators hold an AP leaf cert. SMP operators hold an SMP leaf cert. These expire every two years and must be renewed.
MUST BE IN EVERY TRUST STOREPeppol Root CA G3self-signed · offlinevalid 2025–2035signssignsAP Intermediate CAissues AP leaf certsSMP Intermediate CAissues SMP leaf certsC2 AP leafsigns messagesproves identityC3 AP leafdecrypts payloadssigns receiptsSMP leafsigns the metadatamTLS to the SMLleaf keys: RSA 2048 · signatures: SHA-256 · leaf validity: 2 years · same crypto as G2SMP HTTPS/TLS certificate — issued by a public CA (e.g. Let’s Encrypt)NOT Peppol PKI — never use the SMP G3 cert for TLS, or a public cert to sign metadata
Every trust decision on the network resolves to the offline Root CA G3 (valid 2025–2035). Leaf keys are RSA 2048, everything is signed with SHA-256 — the same profile as G2 — and leaves expire every two years. The one certificate that is not Peppol PKI: the SMP’s ordinary HTTPS certificate.

Note the red row in the figure: the SMP's web server also needs a standard HTTPS certificate, like any website — and that one comes from a normal public CA, not from OpenPeppol. This distinction trips people up constantly, so keep it in mind.

One more important note. In G3, leaf keys are RSA 2048-bit and every certificate in the chain is signed with SHA-256 — the same cryptographic profile G2 already used. G3 was not a crypto upgrade; it was a rebuild of the trust chain on a new CA platform, with fresh roots valid to 2035. We will come back to exactly why G2 had to go, at the end.

Touchpoint 1 — "Where do I send this?" — the SMP discovery

Before C2 can send anything, it needs to answer a basic question: where is C3, and what is their address?

In the physical world, you would look someone up in a directory. Peppol has one too. It is called the SMP — Service Metadata Publisher. Think of it as the Yellow Pages for Peppol Access Points. Every registered receiver has an entry. That entry contains their AS4 endpoint URL and the public half of their certificate.

But there is a step before the directory. How does C2 find which SMP directory holds C3's entry? That is the job of the SML — Service Metadata Locator. Think of the SML as the "find the right phone book" service.

How the lookup actually works

C2 starts with the receiver's Participant Identifier — something like iso6523-actorid-upis::0088:5798000000001 (scheme 0088 is a GS1 GLN; only the ICD codes on the Peppol participant-scheme code list are allowed). This is the receiver's unique identity on the Peppol network.

C2 cannot just search a database directly. Instead, it does something clever with DNS: it lowercases the identifier value (0088:5798000000001 — the scheme prefix is not part of the hash input), hashes it with SHA-256, Base32-encodes the digest into a DNS name under the SML zone, and asks for a NAPTR record — a DNS record type that can carry a full URL. Since OpenPeppol's 2026 SML insourcing, that zone is participant.sml.prod.tech.peppol.org — the EC-operated edelivery.tech.ec.europa.eu zone it replaces retires on August 31, 2026. The answer points at the one SMP that holds C3's entry, which C2 then queries over HTTPS for a document called SignedServiceMetadata: C3's AS4 endpoint URL, C3's transport certificate (the public key C2 will encrypt to later), and the transport profile (peppol-transport-as4-v2_0).

Here is where the first G3 certificate does its job. The SMP signs that entire response with its SMP G3 leaf certificate, and C2 must verify the signature before trusting a single byte of it: SMP leaf → SMP Intermediate CA → Root CA G3, anchored in C2's own trust store. The whole derivation, end to end, with real values:

IDiso6523-actorid-upis::0088:5798000000001the receiver’s participant identifier (0088 = GS1 GLN)SHA-256sha256(lowercase(“0088:5798000000001”))= 8900d078 12cf8ff1 ad458db8 50a4d427 … 4c1214ddBASE32REANA6ASZ6H7DLKFRW4FBJGUE7Z74GX3UTA2OIK2P6TAWTASCTOQRFC 4648, trailing ‘=’ padding strippedDNSreana6asz6h7dlkfrw4fbjgue7z74gx3uta2oik2p6tawtasctoq.iso6523-actorid-upis.participant.sml.prod.tech.peppol.orgNAPTR query against OpenPeppol’s SML zone (since the 2026 SML insourcing)NAPTR100 10 “U” “Meta:SMP” “!.*!https://smp.nemhandel.dk!”flag U = terminal URL · this GLN really resolves to NemHandel’s SMPSMPSignedServiceMetadataC3’s AS4 endpoint URL · C3’s transport cert (AP G3 leaf) · peppol-transport-as4-v2_0verify before trusting: SMP leaf → SMP Intermediate CA → Root CA G3 ✓
Real values, not placeholders — the actual derivation for 0088:5798000000001 (scheme 0088 = GS1 GLN), reproducible with dig against the live network: it resolves to NemHandel’s SMP. The answer is only trustworthy because of the last step: the SMP leaf signature over the metadata, chain-validated to the Root CA G3 in C2’s trust store.

If C2 skips this check, an attacker who can tamper with the response swaps in their own endpoint URL and their own public key as the "transport certificate" — and C2 happily encrypts the invoice to the attacker's key. This is why SMP signature validation is non-negotiable.

Touchpoint 2 — Opening the connection — TLS

C2 now has C3's endpoint URL. It opens an HTTPS connection.

This is standard TLS — the same technology securing every bank website. TLS 1.2 is the minimum, over port 443; newer versions can be used when both sides support them. The server (C3's endpoint) presents a TLS certificate. C2 validates it using normal trust store rules.

The clarification that confuses many developers: the Peppol AS4 profile does not require mutual TLS. The TLS layer is one-directional — C3 proves it is a legitimate HTTPS server, and that is all.

C2's identity — proving who the sender actually is — is not handled by TLS at all. It is handled at the application layer, inside the SOAP message itself, in the WS-Security header. We will get to that in Touchpoint 4.

Think of the TLS layer as the locked van that carries your letter. It keeps outsiders from reading the parcel in transit. But it does not prove who packed the parcel. That proof is sealed inside the parcel itself.

C2 · Sender APC3 · Receiver APHTTPS · port 443 · TLS 1.2 minimumserver cert presented ✓no client certificate — no mTLSTLS = privacy of the channel · sender identity travels in the WS-Security header
The transport layer is one-directional: C3 proves it is a legitimate HTTPS server, full stop. Peppol AS4 does not use mutual TLS — the sender’s identity is proven inside the message (FIG 6), not during the handshake.

Touchpoint 3 — Sealing the envelope — payload encryption

Now C2 needs to prepare the actual document for transmission. This is where the document is locked in a way that only C3 can open.

The order of operations is mandatory and cannot be swapped around: wrap, compress, sign, then encrypt. Compression must come before encryption (random-looking ciphertext does not compress), and — this surprises many people — the signature is computed before the payload is encrypted, per the eDelivery AS4 security policy Peppol builds on. This section covers the sealing machinery; the signature is the next touchpoint.

Step 1 — Wrap the document in SBDH

First, the UBL invoice (or whatever document is being sent) is wrapped in an SBDH — Standard Business Document Header. Think of the SBDH as the envelope label. It carries routing metadata: who is sending, who is receiving, what type of document it is, which process it belongs to. Without the SBDH, C3 does not know where to deliver the contents once decrypted.

The SBDH plus the document together form a Standard Business Document (SBD).

Step 2 — Compress

The SBD is compressed with GZIP — payload size matters when you process thousands of documents a day, and it has to happen now, before encryption turns the bytes into incompressible noise.

Step 3 — Generate a session key

C2 generates a fresh, random 128-bit AES key for this specific message. It is used once, for this document only, then discarded. This is called a session key.

Why not just encrypt everything with C3's public key directly? Because public key encryption (RSA or EC) is slow and has size limits. It is designed for small payloads — like a key, not a document. AES-128-GCM, by contrast, is fast and handles arbitrarily large data. So you use AES for the bulk content and RSA/EC for the key itself. This pattern is called hybrid encryption.

Step 4 — Encrypt the document

The compressed SBD is encrypted with the AES session key using AES-128-GCM. The result is opaque ciphertext. This travels as a separate MIME attachment, outside the SOAP body.

Step 5 — Lock the key using C3's certificate

Here is where the second G3 certificate does its job.

C2 encrypts the AES session key using C3's AP G3 leaf certificate public key — the one it retrieved from the SMP in Touchpoint 1. The algorithm is RSA-OAEP-MGF1-SHA256, which is a secure padding scheme for RSA encryption.

The encrypted session key travels in the SOAP header as <xenc:EncryptedKey>. Only C3's private key — which never leaves C3's server — can open it, and with it, the invoice.

AES-128-GCM ciphertexttravels as a MIME attachmentGZIPcompress BEFORE encryptingSBDSBDH — routing headersender · receiver · doc typeUBL invoiceAES-128 session keyfresh per message, then discardedencryptsRSA-OAEP-MGF1-SHA256with C3’s public key(SMP transport cert)<xenc:EncryptedKey>only C3’s private key opens it→ SOAP headerorder is mandatory: wrap → compress → sign (FIG 6) → encrypt — ciphertext does not compress
The invoice is sealed twice over: bulk-encrypted with a one-shot AES key, and that key is itself locked with C3’s public key from the SMP. If the SMP served a stale certificate, this is the moment the exchange is already doomed — C3 will fail to decrypt at FIG 7.

Touchpoint 4 — Signing your name — message signing with C2's certificate

The sealing machinery is in place. Now C2 must prove that it — and only it — sent this message. Nobody else should be able to claim they sent it. This is done by digitally signing the message.

Think of a digital signature like a wax seal on the envelope. If the seal is intact when it arrives, the recipient knows two things: you sent it, and it has not been tampered with since you sealed it.

In WS-Security terms the profile is sign before encrypt — the eDelivery AS4 policy Peppol builds on declares SignBeforeEncrypting explicitly. The digests are computed over the ebMS header and the compressed plaintext payload, the signature is applied, and only then is the payload encrypted. Integrity is still airtight: AES-GCM authenticates the ciphertext, so tampering in transit fails decryption outright at C3 — and anything that somehow survived would still break the digest comparison after decryption. Signing the plaintext is also what makes the Receipt meaningful later: the digests C3 echoes back (Touchpoint 6) prove receipt of the actual business document, not of an opaque blob.

What gets signed

The XML digital signature (XML-DSIG) references three parts:

  1. The <eb:Messaging> element — the ebMS3 header carrying message IDs, sender/receiver party identifiers, action, service type, and collaboration info.
  2. The payload MIME attachment — digested in its compressed, pre-encryption form.
  3. The SOAP Body — empty in Peppol AS4, but the security policy signs it anyway, so a third (trivial) reference rides along.

Each part is digested with SHA-256; the digests land in a structure called <ds:SignedInfo>, and <ds:SignedInfo> itself is signed using C2's AP G3 private key with RSA-SHA256. The two digests that carry the meaning are the header's (call it d1) and the payload's (d2).

Where it all lives in the message

soap:Envelopesoap:Headereb:Messagingmessage IDs · parties · service · actiond1wsse:Securitywsse:BinarySecurityTokenC2’s AP G3 leaf, Base64 DERxenc:EncryptedKeysession key, locked for C3 (FIG 5)ds:SignatureSignedInfo{ d1, d2 } · RSA-SHA256, C2 private keysoap:Body — intentionally emptyMIME attachmentciphertext on the wire — d2 was digested pre-encryptiond2signature referencesd1 + d2 (+ empty Body)— one flipped bytebreaks itPartyId = Subject CNof the AP leaf certe.g. POP000123
What the signature covers: the SHA-256 digests d1 (the ebMS3 header) and d2 (the compressed payload — digested before encryption, per the profile’s sign-then-encrypt order), plus a third reference over the empty SOAP Body — all sealed with C2’s private key, RSA-SHA256. C2’s own leaf certificate rides along in the BinarySecurityToken.

The SOAP body stays empty by design — the ciphertext rides as a MIME attachment, keeping binary data out of the XML. C2 also embeds its own AP G3 leaf certificate in <wsse:BinarySecurityToken>, so C3 can verify the signature without looking anything up. And party identification is certificate-based too: C2 and C3 are identified by the Subject Common Name (CN) of their AP leaf certs — something like POP000123 — tying every message to a specific accredited Peppol AP. That CN is your Seat ID: P + your Peppol Authority's code + six digits (POP… = OpenPeppol, PFI… = the Finnish authority), and it stays the same across test and production — only the issuing CA and its OU markers tell the environments apart.

Touchpoint 5 — C3 receives: verify, unlock, deliver

C3 receives the multipart MIME message over the HTTPS connection. It does not touch the business document yet. Security checks come first. If any check fails, the message is rejected before any invoice data is processed.

chain-validateBST → AP CA→ Root CA G3revocationCRL / OCSPstill valid?verify DSIGSignedInfo + d1header intact?decrypt keyC3 private keyopens EncryptedKeyunpack + deliverdecrypt · check d2gunzip · SBDH → C4PASS →EBMS:0101FailedAuthenticationEBMS:0102FailedDecryption← the classic failure:cert rotated, SMP not updated firstany failure → reject the whole message;the invoice is never parsedD2 IS CHECKED AFTER DECRYPTION — THE SIGNATURE WAS MADE BEFORE ENCRYPTION
Four gates, in order, before a single byte of invoice data is processed. The gate-4 failure is the classic production error on the network: C3 rotated its certificate but the SMP still announced the old one, so C2 locked the session key to a key C3 no longer uses.

Step 1 — Identify the sender

C3 pulls C2's AP G3 leaf certificate out of <wsse:BinarySecurityToken> and builds the trust chain: C2 leaf → AP Intermediate CA → Root CA G3, anchored in C3's trust store.

C3 also checks revocation — has this certificate been revoked? This is done via CRL (a published list of revoked certs) or OCSP (a real-time query). If the cert is revoked, C3 rejects the message with EBMS error code 0101 — FailedAuthentication.

Step 2 — Verify the signature

Using C2's public key (from the cert just validated), C3 verifies the signature over <ds:SignedInfo> and recomputes the SHA-256 digest of <eb:Messaging> (d1). The payload digest (d2) cannot be checked yet — it was taken over the plaintext before encryption, so it is verified right after decryption in Step 4.

If the header was modified in transit — even a single byte — the digest will not match. Rejection, EBMS 0101.

Step 3 — Unlock the session key

C3 takes the <xenc:EncryptedKey> from the SOAP header and decrypts it using C3's own AP G3 private key — the key that corresponds to the transport certificate published in the SMP. The result is the AES session key that C2 generated.

If C3 has recently rotated its certificate but forgot to update the SMP, the key C2 encrypted to no longer matches C3's current private key. Decryption fails. EBMS 0102 — FailedDecryption. This is one of the most common production failures on the Peppol network. The fix is always the same: update the SMP first, rotate the cert second — and verify by fetching your own SMP entry and comparing certificate fingerprints before you call it done.

Step 4 — Decrypt, verify the payload, extract the document

With the session key recovered, C3 decrypts the MIME attachment using AES-128-GCM — the GCM authentication tag itself proves the ciphertext wasn't tampered with. C3 now verifies the payload digest (d2) from the signature against the decrypted, still-compressed payload, then decompresses the GZIP output. The SBDH emerges. C3 reads the receiver from the SBDH (the same value the AS4 header carries as the finalRecipient message property) to know which C4 client to deliver to. The UBL invoice is extracted and forwarded.

Touchpoint 6 — The signed receipt: proof you actually got it

Here is something that surprises people who are new to Peppol: a successful HTTP 200 response is not enough. C3 must send back a cryptographically signed AS4 Receipt — a Signal Message — before C2 has any proof of delivery.

This is mandatory. Not optional. If C3 accepts the message but does not send a valid signed Receipt, C2 is in the dark.

What the Receipt contains

The AS4 Receipt is an <eb:SignalMessage> containing an <eb:Receipt> element. Inside the Receipt is something called <ebbp:NonRepudiationInformation>.

This element quotes back the <ds:Reference> entries from C2's original signature — the digests of the messaging header, the payload, and the empty Body. By including these, C3 is saying: "I received exactly this message. Here are the fingerprints. I can prove it."

This is Non-Repudiation of Receipt. It means C3 cannot later claim it never received the document. The signed Receipt is the evidence — signed with C3's own AP G3 private key, its leaf certificate embedded in the Signal Message's WS-Security header, same structure as the outbound message.

What C2 checks on the Receipt

When C2 receives the Receipt, it does not just accept it and move on. It validates:

  1. Chain-validate C3's embedded cert — C3 leaf → AP Intermediate CA → Root CA G3 — and check revocation.
  2. Verify the XML-DSIG signature on the Receipt itself.
  3. Confirm the <ebbp:NonRepudiationInformation> contains the expected message references (the same d1 + d2 that were signed on the way out).

A useful extra sanity check many APs run: compare the Receipt's signing certificate against the one the SMP announces for C3 — a mismatch usually means a rotation in flight or a misconfiguration. The normative requirement, though, is a valid, unrevoked Peppol AP certificate.

C2 · Sender APC3 · Receiver APAS4 message · signed digests:d1d2eb:SignalMessage / eb:Receipt · NonRepudiationInformation:d1d2← the same digests, quoted backC2 validates the Receipt:✓ chain: C3 leaf → AP CA → Root CA G3✓ revocation: CRL / OCSP still valid✓ XML-DSIG on the Receipt itself✓ references match d1 + d2archive the Receiptyour proof of delivery —lose it, lose the evidenceno valid signed Receipt → no proof of delivery — retry or escalate per your policy
The Receipt’s NonRepudiationInformation quotes back the exact signed digests from the original message — d1 and d2 must match — signed with C3’s own AP certificate. HTTP 200 alone proves nothing; the archived Receipt is the legal evidence.

C2 archives the validated Receipt: the Peppol network's equivalent of a signed delivery confirmation.

Why G2 had to go — the plain truth

G2 was the previous generation of Peppol certificates, running from 2018 until it was fully retired on April 1, 2026, when every remaining G2 certificate — test and production — was revoked.

Here is the part that surprises people: G2 was not cryptographically broken. G2 already used SHA-256 signatures and RSA 2048-bit keys — and G3 uses the same profile. The real story is more mundane, and more instructive.

The platform under the CA reached end of life

OpenPeppol does not run its own certificate factory. The Peppol CAs are operated on DigiCert infrastructure — and DigiCert sunset the legacy Managed PKI v8 (MPKI8) platform that the entire G2 chain was issued from, replacing it with DigiCert ONE / Trust Lifecycle Manager.

Certificates cannot be "moved" to a new platform. A trust chain is anchored by root certificates that every Access Point and SMP pins by fingerprint in its trust store. New platform means new roots, new intermediates, and a new leaf certificate for every single AP and SMP operator on the network — a full, coordinated re-keying of the trust fabric. That is what G3 is.

Fresh roots buy another decade

The G2 roots were also approaching the end of their lifetime. The G3 Root CA is valid from 2025 to 2035 — a clean ten-year runway on modern infrastructure.

The migration itself was the hard part

Rotating an entire network's PKI without stopping invoice traffic is a distributed-systems problem, solved with a dual-trust window:

  • T0 — August 11, 2025: the G3 CA chains were published.
  • T1 — February 11, 2026: every Service Provider had to support both chains — G2 and G3 roots side by side in every trust store — while operators swapped their leaf certificates at their own pace.
  • T2 — April 1, 2026: every remaining G2 certificate was revoked.

Anyone who followed the timeline migrated with zero downtime. Anyone who did not lost network connectivity outright — an AP that cannot chain-validate its peer rejects every message (Touchpoint 5).

What goes wrong — and what the error actually means

What failedWhat you seeThe real cause
SMP signature invalidSignatureValidationExceptionSMP cert revoked, chain breaks, or the XML was modified in transit
G3 root not in trust store"Trust anchor not found"You are still running a G2-only trust store
Wrong cert in SMPEBMS:0102 FailedDecryptionC3 rotated their cert without updating the SMP transport certificate first
Sender cert revokedEBMS:0101 FailedAuthenticationC2's AP leaf cert has been revoked — check CRL/OCSP
Signature mismatchEBMS:0101 FailedAuthenticationMessage was tampered with in transit, or the wrong cert was used for signing
Receipt signature invalidReject the ReceiptNot signed by a valid, unrevoked Peppol AP cert — or C3 is mid-rotation; re-verify before treating the message as delivered

The EBMS error codes are standard. When you see them, you know exactly which security layer they came from.

The full journey in six sentences

  1. C2 looks up C3's address in a signed DNS-backed directory, and checks the directory's signature before trusting anything it reads.
  2. C2 wraps and compresses the invoice, then signs it with its own private key — digests over the header and the plaintext payload — proving identity and integrity.
  3. C2 then seals the payload with a one-time key that only C3 can unlock, because C3's public certificate is used to lock it.
  4. C3 verifies the signature, unlocks the package with its private key, decompresses the invoice, and delivers it.
  5. C3 sends back a signed Receipt containing the cryptographic fingerprints of the original message — non-repudiation of receipt.
  6. Every certificate in every step traces back to one offline Root CA G3 — the single, shared trust anchor for the entire network.

Three certificate types. Six touchpoints. One root of trust.

Where the libraries stop

Here is the good news: everything in Touchpoints 1–6 — the discovery, the chain and revocation checks, the sign-before-encrypt dance, generating and validating the signed Receipt — is implemented for you by two mature open-source stacks: phase4 (an embeddable Java library, the de-facto reference implementation) and Oxalis-NG (a deployable access point). When a gate fails, the library gives you the EBMS code; the touchpoints above give you the diagnosis.

What no library can do for you: manage your keys, sequence a certificate rotation, deliver to C4, or archive your Receipts. Those stay yours — and they are where the failures in the table above are born.


Understanding this end to end is not an academic exercise. When things go wrong in a Peppol implementation — and they will — the failure almost always lives at one of these six touchpoints. Knowing what each certificate does, and why, turns a cryptic EBMS error code into a solvable problem.

Up next: the same instinct, one layer up — verifying machine-written code. A walk through the AI build factory I run: how a written spec becomes a released tool, the gates every build has to clear on the way, and what convinced me to add each one.

References