How to send a Peppol invoice via API
Peppol is the network European governments and businesses use to exchange e-invoices. This guide sends one compliant invoice from your own code: one JSON call in, validated UBL and network delivery out. No UBL knowledge required.
1. Get a sandbox API key
Create a free account at nordinvoice.com/register. The dashboard gives you a working nord_test_ key in seconds. Sandbox keys deliver to a simulated network, so you can integrate end to end before anything real leaves the building.
2. Send your first invoice
One call does everything: it validates the draft against EN 16931 and the Peppol BIS rules, generates the UBL document, and queues delivery to the buyer's Peppol address.
curl -X POST "https://nordinvoice.com/api/v1/invoices?send=true" \
-H "Authorization: Bearer nord_test_..." \
-H "Content-Type: application/json" \
-d '{
"invoiceNumber": "INV-2026-001",
"issueDate": "2026-08-10",
"dueDate": "2026-09-09",
"currency": "EUR",
"buyerReference": "PO-2026-001",
"seller": {
"name": "Demo Supplier BV", "street": "Keizersgracht 1",
"city": "Amsterdam", "postalCode": "1015 CC", "countryCode": "NL",
"vatNumber": "NL123456789B01",
"electronicAddress": "12345678", "electronicAddressScheme": "0106"
},
"buyer": {
"name": "Demo Buyer GmbH", "street": "Unter den Linden 5",
"city": "Berlin", "postalCode": "10117", "countryCode": "DE",
"vatNumber": "DE123456789",
"electronicAddress": "991234567", "electronicAddressScheme": "0204"
},
"paymentIban": "NL91ABNA0417164300",
"lines": [{ "description": "Consultancy", "quantity": 10,
"unitCode": "C62", "unitPrice": 100, "vatPercent": 21 }]
}'
With the official SDKs the same call looks like this:
# npm install nordinvoice
import { NordInvoice } from 'nordinvoice'
const nord = new NordInvoice({ apiKey: 'nord_test_...' })
const result = await nord.invoices.create(draft, { send: true })
console.log(result.readyToSend, result.job?.id)
# pip install nordinvoice
from nordinvoice import NordInvoice
nord = NordInvoice(api_key="nord_test_...")
result = nord.invoices.create(draft, send=True)
print(result["readyToSend"], result["job"]["id"])
3. Track the delivery
The response contains a job. Poll it until the shipment reports DELIVERED:
curl "https://nordinvoice.com/api/v1/jobs/JOB_ID" \
-H "Authorization: Bearer nord_test_..."
Prefer push over polling? Register a webhook and NordInvoice calls your endpoint on every status change.
What the API checks for you
- EN 16931 and Peppol BIS validation: every rule, before anything is sent.
- Receiver lookup: the buyer's Peppol address is verified on the network first.
- UBL generation: the compliant XML is built for you and stays downloadable.
Ready-made UBL already in hand? Post the XML to the same endpoint, or use nord.invoices.submitUbl(xml).