Send an invoice over Peppol
One REST call delivers a compliant e-invoice to any Peppol participant. This is the happy path in four
steps, from a cold start to a document.delivered webhook.
1 · Register the sender
One-time per company. Creates the company, enriches it from the VAT number, and publishes it to the Peppol SMP so it can both send and receive.
curl -X POST …/v1/companies \
-H "Authorization: Bearer $FLOWIE_KEY" \
-d '{"vatNumber":"BE0123456789"}'
If the company already exists on another platform, use
POST /v1/companies/import instead, then
POST /v1/companies/{id}/register to
activate it on Peppol.
2 · Verify the recipient
Always verify before sending. A recipient that is not registered for your document type will bounce, and the bounce arrives asynchronously — minutes after you thought the invoice was gone.
curl -X POST …/v1/directory/verify \
-H "Authorization: Bearer $FLOWIE_KEY" \
-d '{"peppolId":"0208:9876543210","documentType":"INVOICE"}'
Check canReceive in the response before continuing.
3 · Send the invoice
Describe the invoice as JSON and we render, sign and route the UBL for you. Pass a persistent
Idempotency-Key — generate it before the first attempt, from your own database row id, so a
crash between generation and the HTTP call is still recoverable.
curl -X POST …/v1/documents/send \
-H "Authorization: Bearer $FLOWIE_KEY" \
-H "Idempotency-Key: inv-2026-001" \
-d '{
"type": "invoice",
"from": "comp_abc123",
"to": "0208:9876543210",
"document": {
"number": "INV-2026-001",
"issueDate": "2026-04-25",
"dueDate": "2026-05-25",
"currency": "EUR",
"lines": [{
"description": "Consulting, April 2026",
"quantity": 10, "unit": "hours",
"unitPrice": 150.00, "vatRate": 21
}]
}
}'
Already have UBL XML or a Factur-X PDF? Send it as-is with the xml or file field
instead of document — see
the endpoint reference for the payload matrix.
4 · Watch the delivery
The response returns immediately with status: "sent"; delivery is asynchronous. A
subscribed webhook receives document.delivered once the
recipient's access point confirms, or document.failed with an error code if it does not.
POST /v1/documents/validate
in CI. It catches BIS rule violations (BR-*), unreachable recipients and currency mismatches without touching
Peppol.
Next
- Receive invoices — the other half of the exchange.
- ERP webhooks → send — wire D365, SAP or NetSuite as the inbound source.
- Go-live checklist — prove you are production-ready.
- Compliance — what changes per country.