Documentation

API Reference

Our comprehensive API reference documentation.

Visit API Reference
Back to documentation

Getting Started with Recommand Peppol API

Getting Started

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:

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
bash
// 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"),
    },
  }
);
javascript

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",
    }),
  }
);
javascript

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's 0208:987654321, where 0208 is the Belgian Peppol Electronic Address Scheme and 987654321 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",
            },
          },
        ],
      },
    }),
  }
);
javascript

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());
javascript

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",
}
json

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"),
    },
  }
);
javascript

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
    }),
  }
);
javascript

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"
}
json

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"]
  }
}
json

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...",
    },
  ],
};
javascript

Next Steps

Now that you've sent your first document, explore these resources:

Support

If you encounter any issues or have questions, our support team is here to help: