Overview
The e-invoice.be API allows you to create invoices and credit notes that comply with the European e-invoicing standard (EN 16931) and transmit them via the Peppol network.
Workflow
Creating and sending an e-invoice involves these steps:
Validate your JSON invoice data (required during development)
Create the document - only valid invoices can be created
Send the document via Peppol
You must validate your invoice JSON before creating a document. The API only accepts invoices that can be converted into valid UBL BIS Billing 3.0 format. Use /api/validate/json during development to test your payload.
Step 1: Validate Your Invoice Data (Required)
Before creating an invoice, validate your JSON payload using POST /api/validate/json:
curl -X POST "https://api.e-invoice.be/api/validate/json" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_type": "INVOICE",
"invoice_id": "INV-2024-001",
"invoice_date": "2024-10-24",
"due_date": "2024-11-24",
"currency": "EUR",
"purchase_order": "PO-12345",
"vendor_name": "E-INVOICE BV",
"vendor_tax_id": "BE1018265814",
"vendor_address": "Brusselsesteenweg 119/A, 1980 Zemst, Belgium",
"vendor_email": "[email protected] ",
"customer_name": "OpenPeppol VZW",
"customer_tax_id": "BE0848934496",
"customer_address": "Robert Schumainplein 6 bus 5, 1040 Brussel, Belgium",
"items": [
{
"description": "Professional Services",
"quantity": 10,
"unit": "C62",
"unit_price": 100.00,
"amount": 1000.00,
"tax_rate": "21.00"
}
],
"payment_term": "Payment due within 30 days",
"payment_details": [
{
"iban": "BE68539007547034",
"swift": "GEBABEBB",
"payment_reference": "INV-2024-001"
}
]
}'
Validation Response
Success - Ready to create:
{
"valid" : true ,
"message" : "Invoice JSON is valid and can be converted to UBL BIS Billing 3.0"
}
Validation errors:
{
"valid" : false ,
"errors" : [
{
"field" : "vendor_tax_id" ,
"message" : "Invalid tax ID format. Expected format: country code + number (e.g., BE1018265814 for Belgium)"
},
{
"field" : "items[0].tax_rate" ,
"message" : "Invalid tax rate format. Must be a percentage string (e.g., '21.00')"
}
]
}
Use /api/validate/json extensively during development. This endpoint does not create any documents - it only validates that your JSON can be converted to valid UBL format. See the Validation Guide for more details.
Step 2: Create the Invoice
Once validation passes, use the exact same JSON payload with POST /api/documents/:
curl -X POST "https://api.e-invoice.be/api/documents/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"document_type": "INVOICE",
"invoice_id": "INV-2024-001",
"invoice_date": "2024-10-24",
"due_date": "2024-11-24",
"currency": "EUR",
"purchase_order": "PO-12345",
"vendor_name": "E-INVOICE BV",
"vendor_tax_id": "BE1018265814",
"vendor_address": "Brusselsesteenweg 119/A, 1980 Zemst, Belgium",
"vendor_email": "[email protected] ",
"customer_name": "OpenPeppol VZW",
"customer_tax_id": "BE0848934496",
"customer_address": "Robert Schumainplein 6 bus 5, 1040 Brussel, Belgium",
"items": [
{
"description": "Professional Services",
"quantity": 10,
"unit": "C62",
"unit_price": 100.00,
"amount": 1000.00,
"tax_rate": "21.00"
}
],
"payment_term": "Payment due within 30 days",
"payment_details": [
{
"iban": "BE68539007547034",
"swift": "GEBABEBB",
"payment_reference": "INV-2024-001"
}
]
}'
Response
{
"id" : "doc_abc123" ,
"document_type" : "INVOICE" ,
"state" : "DRAFT" ,
"invoice_id" : "INV-2024-001" ,
"invoice_date" : "2024-10-24" ,
"invoice_total" : 1210.00 ,
"total_tax" : 210.00 ,
"created_at" : 1729468923 ,
"updated_at" : 1729468923
}
Understanding the Invoice Structure
Required Fields
Only the items array is strictly required. All other fields are optional but recommended for complete invoices:
Field Description Required
itemsArray of invoice line items Yes (min 1)document_typeDocument type: INVOICE, CREDIT_NOTE, or DEBIT_NOTE No (default: INVOICE) invoice_idYour unique invoice number Recommended invoice_dateInvoice date (ISO 8601: YYYY-MM-DD) Recommended currencyCurrency code (e.g., EUR, USD, GBP) No (default: EUR)
Vendor (Supplier) Fields
Information about your company (the seller):
Field Description Example
vendor_nameYour company name "E-INVOICE BV"vendor_tax_idYour VAT/Tax ID "BE1018265814"vendor_addressYour full address "Brusselsesteenweg 119/A, 1980 Zemst, Belgium"vendor_emailYour contact email "[email protected] "
The vendor_tax_id is your company’s VAT or tax identification number (not the Peppol ID).
For Belgian companies: Use the full VAT number including ‘BE’ prefix (e.g., BE1018265814)
The API will automatically convert this to the appropriate Peppol ID format when transmitting via Peppol
Customer Fields
Information about your customer (the buyer):
Field Description Example
customer_nameCustomer company name "OpenPeppol VZW"customer_tax_idCustomer VAT/Tax ID "BE0848934496"customer_addressCustomer full address "Robert Schumainplein 6 bus 5, 1040 Brussel, Belgium"customer_emailCustomer contact email "[email protected] "
Line Items
Each line item in the items array represents a product or service:
{
"description" : "Product/Service description" , // What is being sold
"quantity" : 10 , // Quantity
"unit" : "C62" , // Unit of measure (C62 = pieces/units)
"unit_price" : 100.00 , // Price per unit (excluding VAT)
"amount" : 1000.00 , // Line total (quantity × unit_price)
"tax_rate" : "21.00" // VAT percentage as string
}
Required item fields:
At least description or unit_price should be provided for meaningful invoices
Common unit codes:
C62 - Units/pieces
HUR - Hours
DAY - Days
MTR - Meters
KGM - Kilograms
Tax rate format:
Must be a string representing a percentage
Examples: "21.00", "6.00", "0.00"
Standard Belgian VAT rates: "21.00" (standard), "6.00" (reduced), "0.00" (zero-rated)
Optional Fields
{
"payment_term" : "Net 30 days" ,
"payment_details" : [
{
"iban" : "BE68539007547034" ,
"swift" : "GEBABEBB" ,
"payment_reference" : "INV-2024-001"
}
]
}
{
"billing_address" : "Billing Street 1, 1000 Brussels, Belgium" ,
"billing_address_recipient" : "Accounts Payable Department" ,
"shipping_address" : "Delivery Street 2, 2000 Antwerp, Belgium" ,
"shipping_address_recipient" : "Warehouse Manager" ,
"service_address" : "Service Location 3, 3000 Leuven, Belgium"
}
{
"allowances" : [
{
"amount" : 50.00 ,
"reason" : "Early payment discount" ,
"tax_code" : "S" ,
"tax_rate" : "21.00"
}
],
"charges" : [
{
"amount" : 25.00 ,
"reason" : "Shipping costs" ,
"tax_code" : "S" ,
"tax_rate" : "21.00"
}
]
}
See the Advanced Invoicing Guide for more details.
{
"purchase_order" : "PO-12345" ,
"note" : "Thank you for your business"
}
Step 3: Send via Peppol
Once your invoice is created, send it to the recipient using POST /api/documents/{document_id}/send:
curl -X POST "https://api.e-invoice.be/api/documents/doc_abc123/send" \
-H "Authorization: Bearer YOUR_API_KEY"
Response
{
"id" : "doc_abc123" ,
"state" : "TRANSIT" ,
"message" : "Document queued for transmission"
}
Document States
State Description
DRAFTCreated but not sent TRANSITBeing transmitted via Peppol SENTSuccessfully delivered to recipient FAILEDTransmission failed RECEIVEDReceived from another party
Automatic Retries : Documents in TRANSIT use an exponential backoff strategy with multiple retry attempts over 24 hours before transitioning to FAILED. This maximizes delivery success during temporary network issues.Track delivery status using webhooks or by polling GET /api/documents/{document_id}
Complete Example
Here’s a complete Node.js example:
const axios = require ( 'axios' );
const api = axios . create ({
baseURL: 'https://api.e-invoice.be' ,
headers: {
'Authorization' : `Bearer ${ process . env . E_INVOICE_API_KEY } ` ,
'Content-Type' : 'application/json'
}
});
async function createAndSendInvoice () {
const invoiceData = {
document_type: 'INVOICE' ,
invoice_id: 'INV-2024-001' ,
invoice_date: '2024-10-24' ,
due_date: '2024-11-24' ,
currency: 'EUR' ,
vendor_name: 'E-INVOICE BV' ,
vendor_tax_id: 'BE1018265814' ,
vendor_address: 'Brusselsesteenweg 119/A, 1980 Zemst, Belgium' ,
vendor_email: '[email protected] ' ,
customer_name: 'OpenPeppol VZW' ,
customer_tax_id: 'BE0848934496' ,
customer_address: 'Robert Schumainplein 6 bus 5, 1040 Brussel, Belgium' ,
items: [
{
description: 'Professional Services' ,
quantity: 10 ,
unit: 'C62' ,
unit_price: 100.00 ,
amount: 1000.00 ,
tax_rate: '21.00'
}
],
payment_term: 'Net 30 days' ,
payment_details: [
{
iban: 'BE68539007547034' ,
swift: 'GEBABEBB' ,
payment_reference: 'INV-2024-001'
}
]
};
try {
// 1. Validate JSON (during development)
const validation = await api . post ( '/api/validate/json' , invoiceData );
if ( ! validation . data . valid ) {
console . error ( 'Validation failed:' , validation . data . errors );
return ;
}
console . log ( '✓ Invoice JSON is valid' );
// 2. Create invoice (uses same payload)
const invoice = await api . post ( '/api/documents/' , invoiceData );
console . log ( '✓ Invoice created:' , invoice . data . id );
// 3. Send via Peppol
const result = await api . post ( `/api/documents/ ${ invoice . data . id } /send` );
console . log ( '✓ Invoice sent:' , result . data . state );
} catch ( error ) {
console . error ( 'Error:' , error . response ?. data || error . message );
}
}
createAndSendInvoice ();
Working with Credit Notes
Credit notes follow the same structure, but set type: "CREDIT_NOTE":
{
"type" : "CREDIT_NOTE" ,
"invoice_number" : "CN-2024-001" ,
"billing_reference" : "INV-2024-001" , // Original invoice reference
// ... rest of the structure
}
Next Steps