Welcome to Recommand's Peppol API documentation. This guide will help you set up and start using our API for Peppol document exchange.
Overview
Recommand's Peppol API provides a simple and effective way to integrate Peppol document exchange into your existing systems. The API supports document creation, sending, receiving, and management through simple REST endpoints.
Prerequisites
Before you begin, ensure you have:
- A Recommand account (sign up at peppol.recommand.eu/signup)
- Your API key and secret, available from your dashboard
- A development environment capable of making HTTP requests
Authentication
All API requests require Basic Authentication:
# Your API key as username, API secret as password
curl -X GET https://peppol.recommand.eu/api/peppol/{teamId}/companies \
-u key_xxx:secret_xxx
// Node.js example
const response = await fetch(
"https://peppol.recommand.eu/api/peppol/{teamId}/companies",
{
headers: {
Authorization:
"Basic " + Buffer.from("key_xxx:secret_xxx").toString("base64"),
},
}
);
Core Concepts
Companies
Companies represent businesses that can send or receive Peppol documents. Each company must be registered before sending documents using the companies endpoint:
const response = await fetch(
"https://peppol.recommand.eu/api/peppol/{teamId}/companies",
{
method: "POST",
headers: {
Authorization:
"Basic " + Buffer.from("key_xxx:secret_xxx").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify({
name: "ACME Corporation",
address: "123 Main Street",
postalCode: "1000",
city: "Brussels",
country: "BE",
enterpriseNumber: "0123456789",
vatNumber: "BE0123456789",
}),
}
);
Sending Invoices
The primary function is sending Peppol-compliant invoices using the sendDocument endpoint.
A few things to note:
- Remember to replace
{companyId}
with the correct company ID of the sender - Use your own API credentials, as explained above
- The
recipient
field is the Peppol address of the recipient. In the example below, it's0208:987654321
, where0208
is the Belgian Peppol Electronic Address Scheme and987654321
is the recipient's enterprise number. - If you want to send a test invoice, you can simply register a new company and use it as both the sender and recipient.
const response = await fetch(
"https://peppol.recommand.eu/api/peppol/{companyId}/sendDocument",
{
method: "POST",
headers: {
Authorization:
"Basic " + Buffer.from("key_xxx:secret_xxx").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify({
recipient: "0208:987654321", // Peppol address of recipient
documentType: "invoice",
document: {
invoiceNumber: "INV-2025-001",
issueDate: "2024-05-15",
dueDate: "2024-06-15",
buyer: {
vatNumber: "BE0987654321",
name: "Customer Company",
street: "Customer Street 1",
city: "Antwerp",
postalZone: "2000",
country: "BE",
},
paymentMeans: [
{
iban: "BE1234567890",
},
],
lines: [
{
name: "Consulting Services",
netPriceAmount: "100.00",
vat: {
percentage: "21.00",
},
},
],
},
}),
}
);
You can also easily test the API with our interactive API docs.
Verifying Recipients
Before sending documents, you can verify if the recipient is registered in the Peppol network using the verify endpoint. This will be done automatically as well when you send a document.
const response = await fetch("https://peppol.recommand.eu/api/peppol/verify", {
method: "POST",
headers: {
Authorization:
"Basic " + Buffer.from("key_xxx:secret_xxx").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify({
peppolAddress: "0208:987654321",
}),
});
console.log(await response.json());
For valid recipients, you should get a response like this:
{
"success": true,
"isValid": true,
"smpUrl": "http://B-c6451d3d5bd755bb0c2576c41fea37fb.iso6523-actorid-upis.edelivery.tech.ec.europa.eu/iso6523-actorid-upis::0208%3A1012081766",
}
Retrieving Documents
Access received documents through the inbox endpoint:
const response = await fetch(
"https://peppol.recommand.eu/api/peppol/{teamId}/inbox",
{
headers: {
Authorization:
"Basic " + Buffer.from("key_xxx:secret_xxx").toString("base64"),
},
}
);
When having processed a document in your system, you can mark it as read using the markAsRead endpoint. This will prevent it from being shown in the inbox again.
Setting Up Webhooks
Webhooks notify your system about new documents using the webhooks endpoint. Webhooks can also be created and managed from the dashboard.
const response = await fetch(
"https://peppol.recommand.eu/api/peppol/{teamId}/webhooks",
{
method: "POST",
headers: {
Authorization:
"Basic " + Buffer.from("key_xxx:secret_xxx").toString("base64"),
"Content-Type": "application/json",
},
body: JSON.stringify({
url: "https://your-service.com/peppol-webhook", // Try this out for real with a service like RequestBin (https://requestbin.whapi.cloud)
companyId: "company_123", // Optional: specific company
}),
}
);
When a document is received, Recommand will send a POST request to your webhook URL with document details. This request will look something like this:
{
"eventType":"document.received",
"id":"doc_xxx",
"teamId":"team_xxx",
"companyId":"c_xxx"
}
From here, you can use the id
to retrieve the document details using the getDocument endpoint.
Error Handling
The API returns structured error responses:
{
"success": false,
"errors": {
"invoiceNumber": ["Invoice number is required"],
"buyer.vatNumber": ["Invalid VAT number format"]
}
}
Before processing results, always check the HTTP status code or the success
property.
Complete Invoice Example
Here's a complete invoice example with all supported fields. You can view it in more detail in our interactive API docs.
const invoice = {
invoiceNumber: "INV-2025-001",
issueDate: "2024-05-15",
dueDate: "2024-06-15",
note: "Thank you for your business",
buyerReference: "PO-2024-001",
seller: {
vatNumber: "BE0123456789",
name: "Your Company",
street: "Your Street 1",
city: "Brussels",
postalZone: "1000",
country: "BE",
},
buyer: {
vatNumber: "BE0987654321",
name: "Customer Company",
street: "Customer Street 1",
city: "Antwerp",
postalZone: "2000",
country: "BE",
},
paymentMeans: [
{
paymentMethod: "credit_transfer",
reference: "INV-2025-001",
iban: "BE1234567890",
},
],
paymentTerms: {
note: "Net 30",
},
lines: [
{
name: "Consulting Services",
description: "Professional consulting services",
sellersId: "CS-001",
quantity: "10.00",
unitCode: "HUR", // Hours
netPriceAmount: "100.00",
netAmount: "1000.00",
vat: {
category: "S",
percentage: "21.00",
},
},
],
attachments: [
{
id: "ATT-001",
documentType: "130",
mimeCode: "application/pdf",
filename: "contract.pdf",
embeddedDocument: "base64encodeddocument...",
},
],
};
Next Steps
Now that you've sent your first document, explore these resources:
- Authentication Guide (API Reference)
- Sending Invoices (API Reference)
- Managing Companies (API Reference)
- Verifying Recipients (API Reference)
- Working with Webhooks (API Reference)
- UBL Format Guide - Learn about the UBL document structure
- Complete API Reference
Support
If you encounter any issues or have questions, our support team is here to help:
- Email: support@recommand.eu
- GitHub Issues: github.com/brbxai/recommand-peppol/issues