Delivery and Formats
Every invoice you send answers two questions: which format the document is written in, and which way it travels to the buyer. Until now GoRoute answered both for you โ Peppol BIS 3.0 UBL, over the Peppol network. You can now say what you want instead, and there is a second route: a PDF you send by email, with the machine-readable invoice embedded inside it.
Two fields on POST /api/v1/invoices control this, and a delivery object in the response tells
you what was decided. This page covers both, the rules that decide when you leave the choice to
us, and the cases where a delivery is refused because the law does not allow it.
The two request fields, the delivery response object, the issued status and the hybrid PDF
were released on 7 September 2026. Before that date POST /api/v1/invoices had no format or
channel field, every document went over the Peppol network, and there was no delivery object in
the response.
Everything on this page was read from the product source in this repository and cross-checked
against the machine-readable description that the test service publishes, on 7 September 2026.
The production service does not publish its description, and both services report their version as
1.0.0, so we cannot tell them apart by asking. Our release record pins the same build to
production, but that is a record, not a probe. If your integration depends on this and you are
calling production, confirm with support before you build on it.
The two fieldsโ
Both go at the top level of the POST /api/v1/invoices body, beside invoice, and both default
to auto.
{
"invoice": { "...": "your canonical invoice" },
"document_format": "auto",
"delivery_channel": "auto"
}
document_format โ which syntax we renderโ
| Value | What you get |
|---|---|
auto | The default. UBL, in the profile the buyer's country and Peppol entry call for. This is what you got before this release. |
ubl | Peppol BIS 3.0, or PINT UBL where the country uses it. |
xrechnung | The German public-sector customisation, KoSIT XRechnung 3.0, rendered in UBL. Use it for a German public buyer that asks for the German profile. |
cii | EN 16931 in the CII syntax โ the XML that goes inside a ZUGFeRD or Factur-X PDF. This is an email format: see the refusal below. |
zugferd | Exactly the same as cii. It is a spelling, not a different document. |
delivery_channel โ which way it travelsโ
| Value | What happens |
|---|---|
auto | The default. We look the buyer up on the Peppol network. If they are registered for this document, it goes over the network; if not, and email is lawful for your country, the document is issued for you to email. |
peppol | Over the network, with no lookup. The buyer's participant identifier must be on the invoice. |
email | The document is built, stored, and handed back to you to send. The transaction status becomes issued and GoRoute never transmits it. |
email and only have the buyer's VAT numberEvery document GoRoute files is addressed to a participant identifier, even one that never goes on
the network. When you set delivery_channel to email and the buyer has no peppol_id but does
have a vat_number, we derive an identifier from that VAT number using the standard scheme for
the country, and record the document under it. This is the same derivation the WooCommerce plugin
makes, so the same buyer always ends up as the same receiver. It happens only when you ask for
email explicitly, not under auto.
The delivery object in the responseโ
A successful POST /api/v1/invoices now carries a delivery object saying what was decided and
why.
{
"transaction_id": "550e8400-e29b-41d4-a716-446655440000",
"status": "issued",
"message": "Invoice validated and issued for delivery by email: send the buyer the PDF from GET /transactions/{id}/pdf (a PDF/A-3 hybrid with the e-invoice embedded)",
"delivery": {
"channel": "email",
"format": "cii",
"profile": "urn:cen.eu:en16931:2017#compliant#urn:fdc:peppol.eu:2017:poacc:billing:3.0",
"hybrid_pdf": true,
"hybrid_profile": "zugferd",
"buyer_on_network": false,
"reason": "The buyer is not on the Peppol network; the document goes by email."
}
}
profile is the customisation identifier of the UBL document GoRoute renders and stores as
the record, which is why a Peppol BIS 3.0 identifier appears here beside "format": "cii". The
stored document of record is always UBL; the CII is produced from the same invoice when the
hybrid PDF or the CII download is asked for.
| Field | Meaning |
|---|---|
channel | peppol โ the document was queued for transmission. email โ it was issued and stored, and you send it. |
format | The syntax of the deliverable: ubl, xrechnung (also UBL), or cii (the XML inside the hybrid PDF). |
profile | The customisation identifier, BT-24, of the document that was rendered. |
hybrid_pdf | true when GET /api/v1/transactions/{transaction_id}/pdf will give you a PDF/A-3 with the invoice XML embedded. |
hybrid_profile | The name your seller's market knows the hybrid by: zugferd for a German or Austrian seller, factur-x for a French one, en16931 everywhere else it is produced, and absent when no hybrid is made. |
buyer_on_network | What the Peppol lookup concluded, or null when no lookup was made. true means the buyer is registered. false means either that the buyer was not found, or that they were found but do not accept this document type and the document is going by email instead. Because one value covers both, read channel and reason for what actually happened rather than treating this as a plain "is my customer on Peppol" answer. |
reason | One sentence explaining the choice, when it is not the obvious one. null otherwise. |
The status changes too. When channel is email, the response status is issued rather
than queued, and the transaction stays issued forever. Nothing will submit, deliver or fail
it. If you poll for status, treat issued as a third ending โ
see Tracking Delivery.
GoRoute can send the email for you. POST /api/v1/transactions/{transaction_id}/email
(an API key with the invoices:send permission) mails up to five addresses from GoRoute's
verified sender with the same PDF the download gives you โ the hybrid for an EU seller, the
plain PDF otherwise โ plus the XML document. The body takes to (one to five addresses), and
optionally reply_to, sender_name (a display name only, up to 120 characters โ the From
address stays GoRoute's verified sender), message and lang (en, ar, de, nl, fr).
message is the seller's own note to the buyer: plain text, up to 2,000 characters, carried in
the mail. It answers 202 with sent_to and message_id, and records each send under the
transaction's metadata.emails.
A sending domain of your own does not change this call. If you have registered and
verified your own domain โ see
Sending Invoice Email from Your Own Domain โ it
changes the From address of the draft invoice emails,
POST /api/v1/drafts/{draft_id}/send-via-goroute and
POST /api/v1/drafts/{draft_id}/resend, and of nothing else. This call still sends from
GoRoute's verified sender.
The attached PDF is only ever English or Arabic. lang sets the language of the email
itself. The attachment is produced in Arabic when you ask for ar, and in English for every
other value โ so a German, Dutch or French email carries an English PDF.
Refusals. These are checked in the order listed, so a transaction with nothing stored is refused before the rate limit is consulted.
| Status | error_code | When |
|---|---|---|
| 404 | TRANSACTION_NOT_FOUND | No transaction with that id in your organisation |
| 409 | NO_DOCUMENT | There is no stored document to attach. An inbound transaction โ one somebody sent you โ answers this too |
| 503 | MAIL_NOT_ENABLED | Email sending is not switched on in this environment |
| 429 | EMAIL_RATE_LIMITED | The same transaction has already been emailed three times in the last 24 hours |
| 500 | PDF_GENERATION_FAILED | The PDF could not be produced |
| 502 | EMAIL_SEND_FAILED | The mail provider would not accept the message |
Treat the 429 as a temporary refusal rather than a failed send: the limit is three emails per
transaction per 24 hours, and nothing is wrong with the invoice.
What auto actually decidesโ
This is the rule in the order it is applied. Every step below is checked before the one under it.
- An Oman document goes over the network as PINT OM, always. If either party is in Oman, no other format or channel applies, and asking for one is refused.
cii(orzugferd) means email. CII is the syntax that travels inside a PDF; over Peppol the document is UBL. Asking forciiwithdelivery_channel: peppolis refused. Asking forciion its own sets the channel to email for you.- If the channel is email, is email lawful for the seller's country? If not, the send is refused in words. If it is, the document is issued.
- If you named a channel of
peppol, or named any format other thanauto, the document goes over the network with no lookup, and the buyer's participant identifier must be present. - Otherwise โ
autoandautoโ the buyer's own Peppol entry decides:- No participant identifier on the invoice at all: email, where email is lawful.
- Registered, and accepts this document type: over Peppol, as UBL.
- Registered, and accepts XRechnung but not the ordinary Peppol profile: over Peppol, as XRechnung. The reason field says so.
- Registered, but does not accept this document type: email. This is the case that surprises people โ the buyer is on the network, and the document still goes by email, because over Peppol it would be rejected by their own service entry and by email it reaches them. Where email is not lawful, the send over Peppol is attempted anyway so that a genuine problem is visible rather than silently rerouted.
- Not registered: email where lawful, otherwise the send over Peppol is attempted and fails visibly.
- The lookup itself failed (the network could not be asked): over Peppol, exactly as before this release. A network problem never quietly changes how your invoice is delivered.
When a delivery is refusedโ
All of these come back as HTTP 400 with a body of error, error_code and message. The
message is written for a person and can be shown to one.
{
"error": "delivery_refused",
"error_code": "EMAIL_NOT_ALLOWED",
"message": "Belgian businesses must exchange structured e-invoices over Peppol since 1 January 2026; an invoice to a Belgian business cannot be delivered by email. Ask the buyer for the identifier their software receives e-invoices under."
}
error_code | When |
|---|---|
OMAN_PINT_ONLY | Either party is in Oman and you asked for a format other than auto or ubl, or for the email channel. Omani documents are PINT OM, over the network, reported to the Tax Authority. |
CII_IS_EMAIL_ONLY | You asked for cii or zugferd together with delivery_channel: peppol. Over Peppol the document is UBL. For a public buyer that wants the German profile, use document_format: xrechnung. |
EMAIL_NOT_ALLOWED | The seller's country does not permit an invoice to be handed to the buyer outside the network. See the table below. |
BUYER_IDENTIFIER_REQUIRED | The document is going over Peppol, and invoice.buyer.peppol_id is missing. |
BAD_DOCUMENT_FORMAT | document_format is not one of the five allowed values. |
BAD_DELIVERY_CHANNEL | delivery_channel is not one of the three allowed values. |
document_format and delivery_channel are constrained in the request schema, so a value outside
the allowed list โ including a correct value in the wrong case, such as UBL โ is rejected by
request validation with 422 Unprocessable Entity before the delivery rule ever runs. The two
codes above exist behind that check. Handle 422 for a bad value; do not build a branch that waits
for BAD_DOCUMENT_FORMAT.
Where email delivery is refusedโ
GoRoute refuses an email delivery for sellers in four countries. These are statements of what GoRoute enforces, and why โ they are not a complete account of any country's e-invoicing law, and you should not read them as legal advice for your own situation.
| Seller country | What GoRoute says |
|---|---|
| ๐ง๐ช Belgium | Belgian businesses must exchange structured e-invoices over Peppol since 1 January 2026, so an invoice to a Belgian business cannot be delivered by email. Ask the buyer for the identifier their software receives e-invoices under. |
| ๐ด๐ฒ Oman | Omani invoices are reported to the Tax Authority. A buyer not on the network is filed under the substitute address, never emailed. |
| ๐ฎ๐น Italy | Italian invoices go through the SDI exchange system, not by email. |
| ๐ต๐ฑ Poland | Polish invoices go through KSeF, not by email. |
Every other seller country GoRoute serves may deliver by email when the buyer is not on Peppol.
The rule looks at the seller, not the buyer. The messages are worded around the buyer โ the
Belgian one says "an invoice to a Belgian business" โ but what GoRoute actually checks is the
country on invoice.seller. So a Belgian seller invoicing a buyer anywhere is refused the email
channel, and a seller elsewhere invoicing a Belgian buyer is not. Read the refusal as being about
your own establishment.
The hybrid PDFโ
A hybrid is an ordinary, readable PDF with the machine-readable invoice attached inside it, so one
file satisfies both a person and an accounting system. It is written as PDF/A-3, the embedded file
is called factur-x.xml, and it is EN 16931 CII at conformance level EN 16931. Germany calls
this ZUGFeRD, France calls it Factur-X; the file GoRoute produces is the same document under both
names. The Extended profile is deliberately not offered.
You get the hybrid from the ordinary PDF download:
GET /api/v1/transactions/{transaction_id}/pdf
response = requests.get(
f"https://app.goroute.ai/peppol-api/api/v1/transactions/{transaction_id}/pdf",
headers={"X-API-Key": "your_api_key"},
)
with open("invoice.pdf", "wb") as f:
f.write(response.content)
Replace {transaction_id} with the transaction_id the send returned โ a UUID.
| Point | Detail |
|---|---|
hybrid | Defaults to true. Pass hybrid=false for a plain PDF with nothing embedded. |
| Permission | transactions:export, which is not implied by transactions:read. |
| Which documents | Invoices and credit notes whose seller is in one of the countries below, and which GoRoute holds as structured invoice data. |
The hybrid is a superset of the plain PDF, so it is not only for email. A document you sent over Peppol also comes back as a hybrid, which is what German buyers' software expects when a PDF arrives alongside the network copy.
Which sellers get oneโ
Thirty-two seller countries: the European Union, plus Iceland, Liechtenstein and Norway, plus Switzerland and the United Kingdom. That is wider than the EU, and it is worth saying plainly because a British or Swiss seller reading "EU" concludes the opposite.
Austria, Belgium, Bulgaria, Croatia, Cyprus, Czechia, Denmark, Estonia, Finland, France, Germany, Greece, Hungary, Iceland, Ireland, Italy, Latvia, Liechtenstein, Lithuania, Luxembourg, Malta, Netherlands, Norway, Poland, Portugal, Romania, Slovakia, Slovenia, Spain, Sweden, Switzerland, United Kingdom.
Outside that list the PDF is the plain one. Australia and New Zealand have no CII convention, and an Oman document never becomes a hybrid.
The one case where you ask for a hybrid and get a plain PDFโ
The embedded XML is rendered from the canonical invoice GoRoute stored with the document. Not every send stores one.
- Sends that do store it, and therefore produce a hybrid:
POST /api/v1/invoices, a saved draft you send, a CSV or Excel import, a batch send, and documents pulled in by a connector. - The send that does not: raw UBL posted to
POST /api/v1/documents. That path keeps only the XML you supplied and the metadata you sent with it.
When there is nothing to render from, the download quietly gives you the plain PDF. It does not fail and it does not warn you. If your customers expect a ZUGFeRD or Factur-X file, send invoices as structured data rather than as raw UBL.
Getting the XML on its ownโ
To fetch just the machine-readable invoice, without the PDF around it:
GET /api/v1/transactions/{transaction_id}/document/content
Add syntax=cii for the EN 16931 CII โ the same XML that goes inside the hybrid โ or syntax=ubl
for the stored UBL. With neither, you get whichever syntax was delivered: CII for a document
issued for email, UBL for everything else.
If no CII can be produced โ because the canonical invoice was never stored, or because it is an
Oman document โ the call answers 404 with the code CII_NOT_AVAILABLE.
Related pagesโ
- Tracking Delivery โ the
issuedstatus,delivery_channelon a transaction, and polling that terminates - Germany โ XRechnung, the Leitweg-ID and ZUGFeRD
- France โ Factur-X
- Country guides overview โ which validation rule packs run