Skip to content

Peppol for your sellers

Peppol delivers invoices straight into the recipient's accounting, without e-mail or portals. Our Peppol access point sends the XRechnung we generated and archived for the invoice, unchanged. Every seller that sends over Peppol is registered there once.

Activate

Requirements: a plan with real Peppol (Growth or higher), a verified seller in Germany and, as its Peppol address, its VAT ID with scheme 9930 (for example 9930:DE136695976).

# Admin live key; 201 on the first call, then 200 with the same registration
curl -s -X POST $BASE/sellers/<sellerId>/peppol -H "Authorization: Bearer $KEY" \
  -H 'Content-Type: application/json' -d '{"receive": false}'
curl -s $BASE/sellers/<sellerId>/peppol -H "Authorization: Bearer $KEY"     # status

The answer has status (pending, verified, rejected, error), for errors statusReason and statusMessage, and explanation in German and English. Every change sends the webhook event seller.status_changed.

The identity-check link

Before a seller can send, an authorised representative of the company (for example a managing director) confirms their identity. The link is in verificationUrl; only admin keys see it. Pass it only to that person: it is valid for this company.

curl -s -X POST $BASE/sellers/<sellerId>/peppol/verification -H "Authorization: Bearer $KEY"   # new link

A new link is possible at most every 10 minutes and five times a day (429 peppol.link-limit with Retry-After). When the seller's VAT ID or register number changes, a new check starts; until it passed, real Peppol deliveries answer 409 peppol.identity-check-pending.

Send only, or receive as well

Sellers are registered for sending only. Receiving is a separate decision: a Peppol address can receive invoices at one provider only. If the seller already receives through other software, switching would end receiving there.

curl -s -X POST $BASE/sellers/<sellerId>/peppol/receiving -H "Authorization: Bearer $KEY"     # receive as well

Receiving starts only after the identity check passed and only if no other provider serves the address; otherwise receivingBlocked names that provider. We never take over receiving without being asked.

Delivering and the statuses

curl -s -X POST $BASE/invoices/<id>/deliveries -H "Authorization: Bearer $KEY" \
  -H 'Idempotency-Key: inv-2026-0042-peppol' -H 'Content-Type: application/json' \
  -d '{"channel":"peppol","recipient":"0204:04011000-12345-34"}'
  • PENDING: waiting to be sent.
  • SENT: accepted by the access point, on its way.
  • DELIVERED: arrived at the recipient's access point.
  • FAILED / REJECTED: did not arrive; failure gives the reason.
  • OUTCOME_UNKNOWN: the send did not answer clearly. We look for the invoice at the access point and adopt it if it is there. Only if it is still missing after 30 minutes do we send it once more, never blindly twice, so the recipient does not book it twice.
  • UNCONFIRMED: no confirmation within 72 hours; sending again needs "resend": true.

Changes arrive as delivery.updated webhooks.

Failure messages

A delivery that did not arrive has a failure with a stable code and texts in German (de) and English (en) that you can show to your users:

codeMeaningWhat to do
not-on-peppolThe recipient cannot be reached over Peppol.Check the address or use fallbackEmail.
format-not-supportedThe recipient does not accept this format.Ask the recipient; send by e-mail.
validationThe access point refused the document.Check with /validate, correct, issue again.
transportThe transmission failed.Send again later.
recipient-rejectedThe recipient rejected the invoice.Settle it with the recipient.
duplicateThis invoice was sent before.Nothing; it is not sent again.
sender-not-registeredThe seller is not registered (yet).Activate Peppol, complete the identity check.
otherAnother reason (see the text).Read the text; ask support if needed.

Errors when creating the delivery: 409 peppol.not-activated (activate Peppol for the seller first), 409 peppol.identity-check-pending, 503 delivery.peppol-unavailable (no access point is set up on this installation). If the access point is only temporarily not usable, the delivery stays PENDING and goes out once it works again.

Receiving and invoice.received

We check received documents on arrival with the same check as /validate and store them unchanged with the result (validation: valid or invalid) and the report, also when they have errors.

curl -s "$BASE/received-documents?sellerId=<sellerId>&validation=invalid" -H "Authorization: Bearer $KEY"
curl -s $BASE/received-documents/<id>/content -H "Authorization: Bearer $KEY" -o received.xml
curl -s $BASE/received-documents/<id>/report -H "Authorization: Bearer $KEY"
curl -s $BASE/received-documents/<id>/pdf -H "Authorization: Bearer $KEY" -o received.pdf

Every received document sends document.received (documentId, sellerId, sender); invoices and credit notes also send invoice.received with documentId, sellerId, kind (invoice or credit-note), validation and sender. Other document types (orders, responses) are stored with kind other.