Overview
The e-invoice.be API allows you to create documents directly from PDF files. This is useful when:
You have existing PDF invoices you want to send via Peppol
Your system generates PDF invoices but not structured data
You want to digitize paper invoices
You’re migrating from traditional PDF invoicing to e-invoicing
How It Works
There are two modes for PDF document creation:
PDF with JSON metadata - Provide both PDF and structured data
PDF with auto-extraction - Let AI extract invoice data from the PDF (optional feature)
This is the recommended approach - you provide both the PDF and the structured invoice data.
Step 1: Prepare Your Data
You’ll need:
The PDF file
Invoice data in JSON format (same as regular invoice creation)
curl -X POST "https://api.e-invoice.be/api/documents/pdf" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "[email protected] " \
-F 'data={
"document_type": "INVOICE",
"invoice_id": "INV-2024-001",
"invoice_date": "2024-10-24",
"currency": "EUR",
"vendor_name": "Your Company BVBA",
"vendor_tax_id": "0208:0123456789",
"vendor_address": "Main Street 123, 1000 Brussels, Belgium",
"customer_name": "Customer Company NV",
"customer_tax_id": "0208:0987654321",
"customer_address": "Customer Lane 456, 2000 Antwerp, Belgium",
"items": [
{
"description": "Professional Services",
"quantity": 10,
"unit": "C62",
"unit_price": 100.00,
"tax_rate": "21.00"
}
]
}'
Response
{
"id" : "doc_abc123" ,
"type" : "INVOICE" ,
"state" : "DRAFT" ,
"invoice_number" : "INV-2024-001" ,
"has_pdf" : true ,
"created_at" : 1729468923
}
Step 3: Send via Peppol
curl -X POST "https://api.e-invoice.be/api/documents/doc_abc123/send" \
-H "Authorization: Bearer YOUR_API_KEY"
PDF auto-extraction is an optional feature that requires AI-powered data extraction. Contact [email protected] to enable this feature for your account.
With auto-extraction enabled, you can upload a PDF and have the system extract invoice data automatically.
curl -X POST "https://api.e-invoice.be/api/documents/pdf" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "[email protected] " \
-F "auto_extract=true"
Response
{
"id" : "doc_abc123" ,
"type" : "INVOICE" ,
"state" : "DRAFT" ,
"invoice_number" : "INV-2024-001" ,
"extracted_data" : {
"invoice_number" : "INV-2024-001" ,
"issue_date" : "2024-10-24" ,
"total_amount" : 1210.00 ,
"supplier_name" : "Your Company" ,
"customer_name" : "Customer Company"
},
"extraction_confidence" : 0.95 ,
"requires_review" : false
}
Auto-extracted data should always be reviewed before sending, especially for the first few invoices. The extraction_confidence score indicates how confident the system is in the extracted data.
Code Examples
const axios = require ( 'axios' );
const FormData = require ( 'form-data' );
const fs = require ( 'fs' );
async function uploadPDFInvoice ( pdfPath , invoiceData ) {
const formData = new FormData ();
// Add PDF file
formData . append ( 'pdf' , fs . createReadStream ( pdfPath ));
// Add invoice data as JSON
formData . append ( 'data' , JSON . stringify ( invoiceData ));
try {
const response = await axios . post (
'https://api.e-invoice.be/api/documents/pdf' ,
formData ,
{
headers: {
'Authorization' : `Bearer ${ process . env . E_INVOICE_API_KEY } ` ,
... formData . getHeaders ()
}
}
);
console . log ( 'Document created:' , response . data . id );
return response . data ;
} catch ( error ) {
console . error ( 'Error:' , error . response ?. data || error . message );
}
}
// Usage
const invoiceData = {
document_type: 'INVOICE' ,
invoice_id: 'INV-2024-001' ,
invoice_date: '2024-10-24' ,
currency: 'EUR' ,
vendor_name: 'Your Company BVBA' ,
vendor_tax_id: '0208:0123456789' ,
vendor_address: 'Main Street 123, 1000 Brussels, Belgium' ,
customer_name: 'Customer Company NV' ,
customer_tax_id: '0208:0987654321' ,
customer_address: 'Customer Lane 456, 2000 Antwerp, Belgium' ,
items: [
{
description: 'Professional Services' ,
quantity: 10 ,
unit: 'C62' ,
unit_price: 100.00 ,
tax_rate: '21.00'
}
]
};
uploadPDFInvoice ( './invoice.pdf' , invoiceData );
import requests
import os
import json
API_KEY = os.environ.get( 'E_INVOICE_API_KEY' )
BASE_URL = 'https://api.e-invoice.be'
def upload_pdf_invoice ( pdf_path , invoice_data ):
headers = {
'Authorization' : f 'Bearer { API_KEY } '
}
files = {
'pdf' : open (pdf_path, 'rb' ),
'data' : ( None , json.dumps(invoice_data), 'application/json' )
}
try :
response = requests.post(
f ' { BASE_URL } /api/documents/pdf' ,
headers = headers,
files = files
)
response.raise_for_status()
print ( f 'Document created: { response.json()[ "id" ] } ' )
return response.json()
except Exception as error:
print ( f 'Error: { error } ' )
# Usage
invoice_data = {
'document_type' : 'INVOICE' ,
'invoice_id' : 'INV-2024-001' ,
'invoice_date' : '2024-10-24' ,
'currency' : 'EUR' ,
'vendor_name' : 'Your Company BVBA' ,
'vendor_tax_id' : '0208:0123456789' ,
'vendor_address' : 'Main Street 123, 1000 Brussels, Belgium' ,
'customer_name' : 'Customer Company NV' ,
'customer_tax_id' : '0208:0987654321' ,
'customer_address' : 'Customer Lane 456, 2000 Antwerp, Belgium' ,
'items' : [
{
'description' : 'Professional Services' ,
'quantity' : 10 ,
'unit' : 'C62' ,
'unit_price' : 100.00 ,
'tax_rate' : '21.00'
}
]
}
upload_pdf_invoice( './invoice.pdf' , invoice_data)
const axios = require ( 'axios' );
const FormData = require ( 'form-data' );
const fs = require ( 'fs' );
async function uploadPDFWithAutoExtraction ( pdfPath ) {
const formData = new FormData ();
formData . append ( 'pdf' , fs . createReadStream ( pdfPath ));
formData . append ( 'auto_extract' , 'true' );
try {
const response = await axios . post (
'https://api.e-invoice.be/api/documents/pdf' ,
formData ,
{
headers: {
'Authorization' : `Bearer ${ process . env . E_INVOICE_API_KEY } ` ,
... formData . getHeaders ()
}
}
);
console . log ( 'Document created:' , response . data . id );
console . log ( 'Extraction confidence:' , response . data . extraction_confidence );
if ( response . data . requires_review ) {
console . log ( '⚠️ Please review extracted data before sending' );
console . log ( 'Extracted data:' , response . data . extracted_data );
}
return response . data ;
} catch ( error ) {
console . error ( 'Error:' , error . response ?. data || error . message );
}
}
// Usage
uploadPDFWithAutoExtraction ( './invoice.pdf' );
Complete Workflow Example
Here’s a complete example that validates, creates, and sends a PDF invoice:
const axios = require ( 'axios' );
const FormData = require ( 'form-data' );
const fs = require ( 'fs' );
const api = axios . create ({
baseURL: 'https://api.e-invoice.be' ,
headers: {
'Authorization' : `Bearer ${ process . env . E_INVOICE_API_KEY } `
}
});
async function createAndSendPDFInvoice ( pdfPath , invoiceData ) {
try {
// 1. Validate JSON data first
console . log ( 'Validating invoice data...' );
const validation = await api . post ( '/api/validate/json' , invoiceData );
if ( ! validation . data . valid ) {
console . error ( 'Validation failed:' , validation . data . errors );
return ;
}
console . log ( '✓ Invoice data is valid' );
// 2. Upload PDF with metadata
console . log ( 'Uploading PDF invoice...' );
const formData = new FormData ();
formData . append ( 'pdf' , fs . createReadStream ( pdfPath ));
formData . append ( 'data' , JSON . stringify ( invoiceData ));
const document = await api . post ( '/api/documents/pdf' , formData , {
headers: formData . getHeaders ()
});
console . log ( '✓ Document created:' , document . data . id );
// 3. Send via Peppol
console . log ( 'Sending document...' );
const result = await api . post ( `/api/documents/ ${ document . data . id } /send` );
console . log ( '✓ Document sent:' , result . data . state );
return document . data ;
} catch ( error ) {
console . error ( 'Error:' , error . response ?. data || error . message );
}
}
// Usage
const invoiceData = {
document_type: 'INVOICE' ,
invoice_id: 'INV-2024-001' ,
invoice_date: '2024-10-24' ,
currency: 'EUR' ,
vendor_name: 'Your Company BVBA' ,
vendor_tax_id: '0208:0123456789' ,
vendor_address: 'Main Street 123, 1000 Brussels, Belgium' ,
customer_name: 'Customer Company NV' ,
customer_tax_id: '0208:0987654321' ,
customer_address: 'Customer Lane 456, 2000 Antwerp, Belgium' ,
items: [
{
description: 'Professional Services' ,
quantity: 10 ,
unit: 'C62' ,
unit_price: 100.00 ,
tax_rate: '21.00'
}
]
};
createAndSendPDFInvoice ( './invoice.pdf' , invoiceData );
PDF Requirements
Format : PDF (Portable Document Format)
Max size : 10 MB
Version : PDF 1.4 or higher
Content : Must contain readable text (not just images)
Scanned PDFs (images only) require OCR processing. For best results with auto-extraction, use PDFs generated from digital sources.
Best Practices for PDFs
Use text-based PDFs : Generated from software rather than scanned
Clear layout : Structured format with clear sections
Readable fonts : Standard fonts, minimum 8pt size
Complete information : All required invoice fields visible
Single invoice per PDF : Don’t combine multiple invoices
Attachments vs PDF Documents
There’s a difference between:
PDF as document (POST /api/documents/pdf) - PDF is the main invoice
PDF as attachment (POST /api/documents/{id}/attachments) - Adding supporting PDFs to existing documents
Adding PDF Attachments to Existing Documents
# First create the document (JSON or UBL)
curl -X POST "https://api.e-invoice.be/api/documents/" \
-H "Authorization: Bearer YOUR_API_KEY" \
-d '{ invoice data }'
# Then add PDF as attachment
curl -X POST "https://api.e-invoice.be/api/documents/doc_abc123/attachments" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "[email protected] " \
-F "description=Invoice PDF copy"
Retrieving PDF Documents
Get Document with PDF
curl -X GET "https://api.e-invoice.be/api/documents/doc_abc123" \
-H "Authorization: Bearer YOUR_API_KEY"
Response includes has_pdf flag:
{
"id" : "doc_abc123" ,
"type" : "INVOICE" ,
"invoice_number" : "INV-2024-001" ,
"has_pdf" : true ,
"pdf_url" : "https://api.e-invoice.be/api/documents/doc_abc123/pdf"
}
Download PDF
curl -X GET "https://api.e-invoice.be/api/documents/doc_abc123/pdf" \
-H "Authorization: Bearer YOUR_API_KEY" \
--output invoice.pdf
When using auto-extraction, the system returns a confidence score:
Confidence Meaning Action 0.95 - 1.0 Very High Generally safe to use 0.80 - 0.94 High Review key fields (amounts, dates) 0.60 - 0.79 Medium Manual review required < 0.60 Low Manual data entry recommended
if ( response . data . extraction_confidence < 0.80 ) {
console . warn ( 'Low confidence - manual review required' );
// Present extracted data to user for verification
reviewExtractionData ( response . data . extracted_data );
} else {
// Proceed with extracted data
sendDocument ( response . data . id );
}
Common Issues
PDF Too Large
Error : File size exceeds maximum limit
Solution :
Compress the PDF
Use a lower resolution for images within the PDF
Split into multiple documents if necessary
Error : Invalid PDF file or corrupted
Solution :
Ensure file is a valid PDF
Try re-generating the PDF
Check for file corruption
Error : Could not extract data from PDF
Solution :
Provide JSON metadata instead
Ensure PDF contains readable text
Check if PDF is encrypted or password-protected
Missing Required Fields
Error : Missing required field: customer_tax_id
Solution : Ensure all required Peppol fields are in the JSON metadata:
Vendor and customer Peppol IDs (vendor_tax_id, customer_tax_id)
Invoice ID, date, currency
At least one item with description, quantity, unit price, and tax rate
Best Practices
Always Provide Structured Data
Even if using auto-extraction, providing complete JSON metadata ensures:
Accurate UBL generation
Proper Peppol compliance
Faster processing
No extraction errors
// ✓ Good: Provide complete data
formData . append ( 'data' , JSON . stringify ( completeInvoiceData ));
// ✗ Risky: Rely only on extraction
formData . append ( 'auto_extract' , 'true' );
Validate your JSON data before uploading: // Validate first
await api . post ( '/api/validate/json' , invoiceData );
// Then upload PDF
await api . post ( '/api/documents/pdf' , formData );
Store original PDFs for audit purposes: const backup = `./backup/ ${ invoiceNumber } .pdf` ;
fs . copyFileSync ( pdfPath , backup );
Use Descriptive File Names
Name PDFs clearly for tracking: ✓ Good: INV-2024-001_CustomerName.pdf
✗ Poor: invoice.pdf
Monitor Auto-Extraction Quality
Next Steps