Pro Forma Invoices & Delivery Notes
Neither of these documents is sent over Peppol, and neither is a tax document. They are commercial paperwork: a pro forma is what a buyer asks for before paying by bank transfer, and a delivery note is the slip that travels with the goods. GoRoute numbers them, renders them as branded PDFs and emails them, and stops there.
Everything else on this page follows from that one fact, so it is worth stating in full. A pro forma invoice or a delivery note is never:
- transmitted over the Peppol network,
- reported to a tax authority,
- included in a VAT or tax report,
- given a number from your invoice sequence,
- counted against your plan's document allowance.
A merchant who goes looking for a pro forma in a VAT report will not find it, and that is correct behaviour rather than a bug.
When to use whichโ
| Document | What it is for | Prices shown by default |
|---|---|---|
| Pro forma invoice | A priced offer sent before payment โ the document a European B2B buyer asks for so they can raise a bank transfer. | Yes |
| Delivery note | A record of what was despatched, travelling with the goods. Also called a packing list. | No |
The delivery note hides prices by default because the person receiving the pallet is not the
person who agreed the price. Set show_prices to true for a priced packing list.
POST /api/v1/documents sends a real invoice over the Peppol network. It has nothing to
do with this page โ see Sending an Invoice.
GET /api/v1/documents lists your pro forma invoices and delivery notes, which is the
call described below.
Same path, different methods, unrelated behaviour. This is deliberate in the product, but it catches people out, so check the method before you copy an address from one page to another.
The seven callsโ
| Call | What it does | Scope |
|---|---|---|
POST /api/v1/documents/proforma | Create a pro forma invoice | send |
POST /api/v1/documents/delivery-note | Create a delivery note | send |
GET /api/v1/documents | List your non-fiscal documents | read |
GET /api/v1/documents/{document_id} | Fetch one, including the stored content | read |
GET /api/v1/documents/{document_id}/pdf | Download the PDF | read |
POST /api/v1/documents/{document_id}/email | Email it to the buyer | send |
DELETE /api/v1/documents/{document_id} | Delete it outright | send |
{document_id} is the UUID returned when the document is created.
About the scope columnโ
These routes check the scope list on your API key rather than the permission list most of
the API uses. Keys are issued with send and read, and onboarding issues read, write
and send, so an ordinary key already satisfies every row above. A key that has been narrowed
to exclude the scope a route needs gets 403 INSUFFICIENT_SCOPE.
Creating a pro forma invoiceโ
The body is the same Canonical Invoice Model payload POST /api/v1/invoices takes, so a
connector builds it once and reuses it here.
curl -X POST https://app.goroute.ai/peppol-api/api/v1/documents/proforma \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"document": {
"seller": {
"name": "Acme BV",
"vat_number": "NL123456789B01",
"address": {
"street": "Keizersgracht 1",
"city": "Amsterdam",
"postal_code": "1015 CJ",
"country": "NL"
}
},
"buyer": {
"name": "Kunde GmbH",
"vat_number": "DE811234567",
"address": {
"street": "Hauptstr. 5",
"city": "Koeln",
"postal_code": "50667",
"country": "DE"
}
},
"issue_date": "2026-09-08",
"currency": "EUR",
"lines": [
{
"description": "Widget, blue",
"quantity": 10,
"unit": "EA",
"unit_price": 25.00,
"tax_category": "standard",
"tax_rate": 21
}
],
"totals": {
"net_amount": 250.00,
"tax_amount": 52.50,
"gross_amount": 302.50,
"payable_amount": 302.50
}
},
"valid_until": "2026-10-08"
}'
Response โ 201 Created:
{
"document_id": "9f1c2b6e-4a7d-4f9e-b0a1-5c3d2e1f0a9b",
"kind": "proforma",
"number": "PF-2026-00001",
"issue_date": "2026-09-08",
"currency": "EUR",
"total": 302.50
}
Fields shared by both kindsโ
| Field | Type | Notes |
|---|---|---|
document | object | Required. The Canonical Invoice Model payload. |
totals_authority | "system" or "client" | Default "system", which recalculates the totals from the lines. "client" prints the totals exactly as you supplied them. |
note | string, max 2000 | Free text printed under the lines. |
metadata | object | Your own metadata. Stored with the document and never printed. |
Pro forma onlyโ
| Field | Type | Notes |
|---|---|---|
valid_until | date | The date the quoted prices lapse. Printed as "Valid until". |
Two fields behave differently from an invoiceโ
numberis optional, and is not the document's number. The document is numbered from its ownPF-orDN-sequence. If you send anumberanyway it is kept as your own reference and appears on the fetched record ascaller_referenceโ it never becomes the document's number, because no invoice number may be consumed by a document that is not an invoice.document_typeis ignored. There is no canonical document type for a pro forma or a delivery note; that is part of what makes them non-fiscal.
delivery_channel and document_format are ignored as well. Nothing is transmitted, so
there is no channel to honour and no wire format to choose. A caller reusing an invoice body
verbatim does not have to strip them.
Creating a delivery noteโ
curl -X POST https://app.goroute.ai/peppol-api/api/v1/documents/delivery-note \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"document": { "...": "the same Canonical Invoice Model payload" },
"invoice_reference": "INV-2026-00042",
"despatch_date": "2026-09-08",
"tracking_reference": "3SABCD1234567",
"show_prices": false
}'
| Field | Type | Notes |
|---|---|---|
invoice_reference | string, max 150 | The transaction id or invoice number this despatch relates to. Free text, and never resolved โ the invoice usually does not exist yet when the goods leave, so GoRoute prints what you send and looks nothing up. |
despatch_date | date | The date the goods left. Defaults to the issue date on the document. |
tracking_reference | string, max 150 | Carrier consignment or tracking number. |
show_prices | boolean | Default false. |
The response is the same shape as the pro forma response, with "kind": "delivery_note" and
a DN- number.
Numberingโ
Numbers look like PF-2026-00001 and DN-2026-00001. Each sequence is per organisation,
per calendar year, per kind, and all of them are independent of your invoice numbers. The
prefix is deliberate: an accountant who finds one of these in a folder can see at a glance
that it is not part of the fiscal sequence.
Deleting the most recent document frees its number. That is intended here โ deleting a pro forma means "that one was wrong, do it again", and the corrected document should carry the number the customer was already quoted. Only the tail behaves this way. Delete an older document and the sequence carries on from the highest that remains, so a number still in use is never reissued and nothing is renumbered.
Listing and fetchingโ
curl -G https://app.goroute.ai/peppol-api/api/v1/documents \
--data-urlencode "kind=proforma" \
-H "X-API-Key: your-api-key"
| Query parameter | Notes |
|---|---|
kind | proforma or delivery_note. Omit for both. Anything else is 422 UNKNOWN_DOCUMENT_KIND. |
page | Default 1. |
page_size | Default 50, maximum 200. |
Documents come back newest first, as items alongside page, page_size and total.
GET /api/v1/documents/{document_id} returns the stored record: the summary fields plus
the parties, the amounts, the kind-specific fields, your note and metadata, your
caller_reference, the canonical document the PDF renders from, and an emails list with
one entry per send.
The PDFโ
curl -G https://app.goroute.ai/peppol-api/api/v1/documents/9f1c2b6e-4a7d-4f9e-b0a1-5c3d2e1f0a9b/pdf \
--data-urlencode "lang=de" \
-H "X-API-Key: your-api-key" \
--output PF-2026-00001.pdf
| Query parameter | Values | Notes |
|---|---|---|
lang | en, ar, de, nl, fr | Default en. |
currency_display | auto, sign, code, symbol | Default auto, which uses the Rial sign for OMR. |
The document is rendered through the same pipeline as an invoice PDF, with your logo and brand colour. Everything fiscal is suppressed:
- no QR code and no document UUID,
- no "tax invoice" wording in any language โ the only place the phrase appears at all is in the notice saying this is not one,
- a printed line stating that no VAT is due. On a pro forma it adds that the document gives no right to deduct input tax and that a tax invoice will follow when the supply is made; on a delivery note it adds that the document is not a request for payment.
An Omani seller's document is bilingual Arabic/English, laid out exactly as an Omani invoice is, with the Arabic leading.
Emailing the documentโ
curl -X POST https://app.goroute.ai/peppol-api/api/v1/documents/9f1c2b6e-4a7d-4f9e-b0a1-5c3d2e1f0a9b/email \
-H "X-API-Key: your-api-key" \
-H "Content-Type: application/json" \
-d '{
"to": ["accounts@kunde.example.com"],
"reply_to": "sales@acme.example.com",
"sender_name": "Acme BV",
"message": "As discussed โ the pro forma for your bank transfer.",
"lang": "en"
}'
The request body is the same one POST /api/v1/transactions/{transaction_id}/email takes:
to (one to five addresses), optional reply_to, sender_name (a display name only โ the
From address stays GoRoute's verified sender), message (plain text, up to 2000 characters,
shown set apart as your own note) and lang.
The subject is Pro forma invoice <number> from <sender name>, or Delivery note <number> from <sender name>. A pro forma email states above the summary, in the same language as the
PDF, that the document is not a tax invoice and that no VAT is due on it.
Response โ 202 Accepted:
{
"document_id": "9f1c2b6e-4a7d-4f9e-b0a1-5c3d2e1f0a9b",
"sent_to": ["accounts@kunde.example.com"],
"message_id": "0100018f2c4a1b2c-..."
}
An invoice email carries the PDF and the XML, because the XML is the legal electronic invoice. There is no XML here โ neither a pro forma nor a delivery note is an electronic invoice โ so one file is attached and the email body says so, rather than leaving the recipient to notice something missing.
Each send is recorded on the document under emails. The same document may be emailed
three times in 24 hours; the fourth attempt is refused with 429.
Deleting a documentโ
curl -X DELETE https://app.goroute.ai/peppol-api/api/v1/documents/9f1c2b6e-4a7d-4f9e-b0a1-5c3d2e1f0a9b \
-H "X-API-Key: your-api-key"
204 No Content. The document is deleted outright, not soft-deleted, and its archived copy
goes with it.
This is allowed precisely because nothing legal depends on either kind: they are never transmitted, never reported and never part of the fiscal invoice sequence, so removing one leaves no gap an auditor can ask about. An invoice is retained by contrast, and can only ever be soft-deleted by a GoRoute administrator.
Refusalsโ
| Status | error_code | When |
|---|---|---|
403 | INSUFFICIENT_SCOPE | The API key lacks the send or read scope the route needs. |
404 | DOCUMENT_NOT_FOUND | No such document for your organisation. Another organisation's document id is a 404, not a 403. |
422 | UNKNOWN_DOCUMENT_KIND | kind on the list call is neither proforma nor delivery_note. |
429 | EMAIL_RATE_LIMITED | A fourth email of the same document within 24 hours. |
500 | PDF_GENERATION_FAILED | The PDF could not be rendered. |
502 | EMAIL_SEND_FAILED | The mail provider rejected the message. |
503 | MAIL_NOT_ENABLED | Email delivery is not enabled in this environment. |
Relatedโ
- Sending an Invoice โ for a document that really does go over Peppol
- Document Types โ the Peppol document types, including the Despatch Advice, which is a different thing from the delivery note here
- Validation โ none of it applies to these documents; no Peppol validation runs on a pro forma or a delivery note