Business Documents Beyond Invoices
GoRoute validates, sends and receives the post-award documents that Norway's EHF Post-Award G3 specifications define, Peppol BIS Self-Billing, and Peppol Logistics โ alongside ordinary Peppol BIS Billing invoices and credit notes.
Every document is checked against the official validation artefacts before it is sent, in the same three layers as Norway's own validator:
- Identification โ the root element,
cbc:CustomizationIDandcbc:ProfileIDmust name one supported transaction. - UBL schema โ the OASIS UBL 2.4 schemas (UBL minor versions are backward compatible, so 2.1โ2.4 documents are all accepted).
- Schematron โ the transaction's official rules, in the order the specification's validator runs them.
A document that fails any layer is not sent, and the response lists every rule it broke.
What is supportedโ
| Specification | Document | Send as | Peppol network |
|---|---|---|---|
| Peppol BIS Self-Billing 3.0 (EHF Selvfakturering) | Self-billing invoice | JSON self_billing_invoice or XML | Yes |
| Peppol BIS Self-Billing 3.0 (EHF Selvfakturering) | Self-billing credit note | JSON self_billing_credit_note or XML | Yes |
| EHF Reminder 3.0 | Reminder | JSON reminder or XML | Yes |
| EHF Forward Billing 3.0 | Forward billing invoice | JSON forward_billing_invoice or XML | Yes |
| EHF Forward Billing 3.0 | Forward billing credit note | JSON forward_billing_credit_note or XML | Yes |
| EHF Payment Request 3.0 | Payment request | JSON payment_request or XML | Yes |
| EHF Catalogue 3.0 | Catalogue | XML | Yes |
| EHF Catalogue 3.0 | Catalogue response | XML | Yes |
| EHF Ordering 3.0 | Order | XML | Yes |
| EHF Ordering 3.0 | Order response | XML | Yes |
| EHF Order Agreement 3.0 | Order agreement | XML | Yes |
| EHF Punch Out 3.0 | Punch out | XML | No โ see note |
| EHF Despatch Advice 3.0 | Despatch advice | XML | Yes |
| EHF Advanced Ordering 3.0 | Order initiation | XML | Yes |
| EHF Advanced Ordering 3.0 | Order change | XML | Yes |
| EHF Advanced Ordering 3.0 | Order cancellation | XML | Yes |
| EHF Advanced Ordering 3.0 | Order response | XML | Yes |
| Peppol Logistics | Advanced despatch advice (T120) | XML | Yes |
| Peppol Logistics | Weight statement (T122) | XML | Yes |
| Peppol Logistics | Transport execution plan request (T123) | XML | Yes |
| Peppol Logistics | Transport execution plan (T124) | XML | Yes |
| Peppol Logistics | Waybill (T125) | XML | Yes |
| Peppol Logistics | Transportation status request (T126) | XML | Yes |
| Peppol Logistics | Transportation status (T127) | XML | Yes |
| Peppol Logistics | Receipt advice (T128) | XML | Yes |
| Peppol Logistics | Logistics application response (T129) | XML | Yes |
Rule sources: EHF Post-Award G3 release 2026-08-13 (anskaffelser.dev), Peppol Logistics 2025-Q4 (docs.peppol.eu) and Peppol BIS Self-Billing 3.0.2 (docs.peppol.eu). Network identifiers come from the Peppol Code Lists v9.7.
The Peppol Code Lists register no document type or process for EHF Punch Out, so it cannot be addressed over the Peppol network. The specification allows the seller's web shop to transfer it to the buyer's purchasing system directly (HTTP). GoRoute validates Punch Out documents for that; a send request for one is refused with this explanation.
EHF Ordering (profile 02) and EHF Advanced Ordering (profile 09) use the same document type
identifiers for Order and Order Response. The cbc:ProfileID inside your document decides
which rules apply, and a receiver publishes which of the two processes it accepts.
List the supported typesโ
GET /api/v1/business-documents/types โ requires the invoices:read permission.
curl https://app.goroute.ai/peppol-api/api/v1/business-documents/types \
-H "X-API-Key: $GOROUTE_API_KEY"
Each entry gives the customization_id and profile_ids a document must declare, and the
document_type_id and process_ids it travels under.
Validate without sendingโ
POST /api/v1/business-documents/validate โ requires the invoices:read permission.
curl -X POST https://app.goroute.ai/peppol-api/api/v1/business-documents/validate \
-H "X-API-Key: $GOROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"document": "<Order xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Order-2\" ...>...</Order>"}'
The response names the transaction it identified, whether it is valid, and each error and
warning with its rule identifier (for example EHF-T01-B00102) and location.
POST /api/v1/documents/validate gives the same verdict for these documents in its usual
response shape.
Send a document you have built (XML)โ
Post the UBL document to the ordinary document endpoint. Leave document_type and
process_id out: GoRoute reads them from the document and uses the identifiers the Peppol
Code Lists register.
curl -X POST https://app.goroute.ai/peppol-api/api/v1/documents \
-H "X-API-Key: $GOROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"receiver_scheme": "0192",
"receiver_id": "910000055",
"document": "<Order xmlns=\"urn:oasis:names:specification:ubl:schema:xsd:Order-2\" ...>...</Order>"
}'
If you do pass document_type or process_id and they contradict the document, the send is
refused rather than transmitted under the wrong identifier.
Send from JSONโ
The invoice-family documents can be sent from the same JSON as an invoice through
POST /api/v1/invoices, by setting invoice.document_type:
document_type | What changes from an invoice |
|---|---|
self_billing_invoice | The buyer issues it: type code 389, and it travels from the buyer to the seller. |
self_billing_credit_note | Type code 261. Set preceding_invoice. |
reminder | No type code. List the reminded invoices in preceding_invoice and billing_references; a reminder fee is a charge with reason_code REM. Item descriptions are not part of a reminder. |
forward_billing_invoice | Set invoice_type_code where your case needs another code (the published nettleie examples use 82). |
forward_billing_credit_note | Set preceding_invoice. |
payment_request | Not a VAT document: no VAT breakdown, no tax categories and no VAT or legal-entity blocks on either party. Totals are the line total, any prepaid amount and the payable amount. |
Outside Australia, New Zealand and Oman, self_billing_invoice and self_billing_credit_note
produce Peppol BIS Self-Billing 3.0. In those three countries they produce the country's PINT
self-billing profile, as before.
POST /api/v1/invoices/validate/deep runs each of these types against its own official rules.
Receive these documentsโ
A participant only receives a document type it publishes on the SMP. These types are never published by default; add them to the participant's selection when you register it:
curl -X POST https://app.goroute.ai/peppol-api/api/v1/participants/{participant_id}/register \
-H "X-API-Key: $GOROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"document_types": ["<document_type_id>", "..."]}'
The selection is the complete set the participant publishes: include the invoice and
credit note document types too, or they are withdrawn. The document types available for a
country are listed by GET /peppol/doc-types?country=NO. Note the address: this one sits
outside /api/v1, and it needs no API key, so the whole call is
https://app.goroute.ai/peppol-api/peppol/doc-types?country=NO. EHF types are offered to
Norwegian participants, Peppol BIS Self-Billing outside Australia and New Zealand, and Peppol
Logistics everywhere.
Received documents arrive like any other: stored, listed under transactions, and announced by
the transaction.received webhook with their document_type.
Until today the four curl examples on this page were addressed to
peppol-api.goroute.ai. That hostname has never existed โ it has no DNS entry, so the
commands failed on your own machine with "could not resolve host" and never reached GoRoute.
They now use app.goroute.ai, which is the host every other example on this site uses. If
you copied a command from this page before today, change the hostname and it will work; the
paths were always right.