Skip to main content

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โ€‹

DocumentWhat it is forPrices shown by default
Pro forma invoiceA priced offer sent before payment โ€” the document a European B2B buyer asks for so they can raise a bank transfer.Yes
Delivery noteA 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.

Two unrelated meanings share one address

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โ€‹

CallWhat it doesScope
POST /api/v1/documents/proformaCreate a pro forma invoicesend
POST /api/v1/documents/delivery-noteCreate a delivery notesend
GET /api/v1/documentsList your non-fiscal documentsread
GET /api/v1/documents/{document_id}Fetch one, including the stored contentread
GET /api/v1/documents/{document_id}/pdfDownload the PDFread
POST /api/v1/documents/{document_id}/emailEmail it to the buyersend
DELETE /api/v1/documents/{document_id}Delete it outrightsend

{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โ€‹

FieldTypeNotes
documentobjectRequired. 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.
notestring, max 2000Free text printed under the lines.
metadataobjectYour own metadata. Stored with the document and never printed.

Pro forma onlyโ€‹

FieldTypeNotes
valid_untildateThe date the quoted prices lapse. Printed as "Valid until".

Two fields behave differently from an invoiceโ€‹

  • number is optional, and is not the document's number. The document is numbered from its own PF- or DN- sequence. If you send a number anyway it is kept as your own reference and appears on the fetched record as caller_reference โ€” it never becomes the document's number, because no invoice number may be consumed by a document that is not an invoice.
  • document_type is 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
}'
FieldTypeNotes
invoice_referencestring, max 150The 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_datedateThe date the goods left. Defaults to the issue date on the document.
tracking_referencestring, max 150Carrier consignment or tracking number.
show_pricesbooleanDefault 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 parameterNotes
kindproforma or delivery_note. Omit for both. Anything else is 422 UNKNOWN_DOCUMENT_KIND.
pageDefault 1.
page_sizeDefault 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 parameterValuesNotes
langen, ar, de, nl, frDefault en.
currency_displayauto, sign, code, symbolDefault 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-..."
}
One attachment, not two

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โ€‹

Statuserror_codeWhen
403INSUFFICIENT_SCOPEThe API key lacks the send or read scope the route needs.
404DOCUMENT_NOT_FOUNDNo such document for your organisation. Another organisation's document id is a 404, not a 403.
422UNKNOWN_DOCUMENT_KINDkind on the list call is neither proforma nor delivery_note.
429EMAIL_RATE_LIMITEDA fourth email of the same document within 24 hours.
500PDF_GENERATION_FAILEDThe PDF could not be rendered.
502EMAIL_SEND_FAILEDThe mail provider rejected the message.
503MAIL_NOT_ENABLEDEmail delivery is not enabled in this environment.
  • 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