Skip to main content

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:
  1. Validate your JSON invoice data (required during development)
  2. Create the document - only valid invoices can be created
  3. 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:
FieldDescriptionRequired
itemsArray of invoice line itemsYes (min 1)
document_typeDocument type: INVOICE, CREDIT_NOTE, or DEBIT_NOTENo (default: INVOICE)
invoice_idYour unique invoice numberRecommended
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):
FieldDescriptionExample
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):
FieldDescriptionExample
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

StateDescription
DRAFTCreated but not sent
TRANSITBeing transmitted via Peppol
SENTSuccessfully delivered to recipient
FAILEDTransmission failed
RECEIVEDReceived from another party
Outbound document state flow
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