Send one PDF. Peppox does the Peppol work.
Your system sends a single PDF file. Peppox securely extracts the data, creates the UBL XML, applies the Peppol standards and validates the document.
- 1 · Upload PDF
- 2 · Check
- 3 · Confirm
- 4 · Send to Peppol
Choose the route that matches your system. Every identifier, request and next action is explained from the first API call to delivery tracking.
Complete the account and supplier configuration first. Your application can then reuse the same credentials for every document.
Register the legal company that will send documents.
Company, VAT, bank and Peppol routing data are loaded from your registered account.
Use the dashboard tools to test calls safely before production.
Keep it on your server. Never expose it in browser or mobile application code.
Your system sends a single PDF file. Peppox securely extracts the data, creates the UBL XML, applies the Peppol standards and validates the document.
Use the endpoint series when your ERP or software owns the invoice data and needs precise control over the header, lines, PDF attachment and UBL XML.
This is the most direct documented route when your system already produces invoices as PDF files.
Send a file, Base64 content or a remote URL. Save the returned queue_guid.
POST/pdf2peppol/addPoll until processing is complete, then review buyer, totals, VAT and lines.
GET/pdf2peppol/checkConfirm only after the extracted invoice data is correct.
POST/pdf2peppol/confirmDispatch the confirmed document. Save the returned document GUID.
POST/pdf2peppol/sendReplace the placeholders with your real key and the identifiers returned by the previous call.
curl -X POST "https://api.peppox.com/pdf2peppol/add/" \
-F "supplier_id=YOUR_SUPPLIER_ID" \
-F "document_type_code=380" \
-F "pdf_file=@invoice.pdf"
# Save queue_guid, then check it
curl "https://api.peppox.com/pdf2peppol/check/?supplier_id=YOUR_SUPPLIER_ID&queue_guid=QUEUE_GUID"
curl -X POST "https://api.peppox.com/pdf2peppol/confirm/" \
-d "supplier_id=YOUR_SUPPLIER_ID" \
-d "queue_guid=QUEUE_GUID"
curl -X POST "https://api.peppox.com/pdf2peppol/send/" \
-d "supplier_id=YOUR_SUPPLIER_ID" \
-d "queue_guid=QUEUE_GUID"Ideal when your ERP already stores every invoice field and line in a structured format.
Send customer, dates, currency, payment and delivery data. Save invoice_guid.
POST/invoice/addRepeat the call for each product or service line.
POST/invoice_line/addAdd the human-readable invoice by file, Base64 or URL.
POST/invoice_attach_pdf/addPeppox creates the UBL XML for an invoice or credit note. If it is valid, the configured Peppox flow sends it to Peppol; no separate structured /send call is needed.
POST/xml/generateInspect the document and its status from the dashboard or sent-document APIs.
GET/doc-sent/header/listImportant: /xml/generate/ is shared by invoices and credit notes. A successful XML_BUILT response means Peppox has generated the document and continues the configured Peppol dispatch. There is no additional structured-data /send endpoint.
Parameters, valid formats, copy-ready requests and representative successful responses. Technical field names intentionally remain in English so they match the API exactly.
POST/pdf2peppol/add/
Upload a PDF and create the conversion queue+
supplier_idstringAccount API key.PDF sourcefile or stringProvide exactly one: multipart pdf / file / invoice_pdf / document / pdf_file; or pdf_base64 / content_base64; or pdf_url / file_url / document_url / url.document_type_code380 or 381380 by default; 381 is a credit note. Aliases: invoice_type_code, document_type, type.networkproduction or integrationproduction by default. Aliases: net_work, environment.filenamestringUsed with a Base64 or URL source; a .pdf extension is normalised.curl -X POST "https://api.peppox.com/pdf2peppol/add/" \
-F "supplier_id=YOUR_API_KEY" \
-F "document_type_code=380" \
-F "network=integration" \
-F "pdf_file=@invoice.pdf"<?php
$fields = [
'supplier_id' => 'YOUR_API_KEY',
'document_type_code' => '380',
'network' => 'integration',
'pdf_file' => new CURLFile(__DIR__ . '/' . 'invoice.pdf', 'application/pdf'),
];
$ch = curl_init('https://api.peppox.com/pdf2peppol/add/');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $fields, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append("supplier_id", "YOUR_API_KEY");
form.append("document_type_code", "380");
form.append("network", "integration");
form.append("pdf_file", new Blob([await readFile("invoice.pdf")], {type: 'application/pdf'}), "invoice.pdf");
const response = await fetch("https://api.peppox.com/pdf2peppol/add/", {method: 'POST', body: form});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
data = json.loads(r'''{
"supplier_id": "YOUR_API_KEY",
"document_type_code": "380",
"network": "integration"
}''')
files = {
"pdf_file": open("invoice.pdf", 'rb')
}
try:
response = requests.post('https://api.peppox.com/pdf2peppol/add/', data=data, files=files, timeout=30)
response.raise_for_status()
print(response.json())
finally:
if files:
for file in files.values(): file.close() {
"success": true,
"queue_guid": "pdf-…",
"status": "pending",
"document_type_code": "380",
"network": "integration",
"monthly_limit": {"limit": 50, "used": 3}
}GET/pdf2peppol/check/
Read extraction results and Peppol readiness+
supplier_idstringSame value used at upload.queue_guidstringThe queue GUID returned by /pdf2peppol/add/. Alias: guid.curl "https://api.peppox.com/pdf2peppol/check/?supplier_id=YOUR_API_KEY&queue_guid=QUEUE_GUID"<?php
$response = file_get_contents('https://api.peppox.com/pdf2peppol/check/?supplier_id=YOUR_API_KEY&queue_guid=QUEUE_GUID');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/pdf2peppol/check/?supplier_id=YOUR_API_KEY&queue_guid=QUEUE_GUID");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/pdf2peppol/check/?supplier_id=YOUR_API_KEY&queue_guid=QUEUE_GUID', timeout=30)
response.raise_for_status()
print(response.json()) {
"success": true,
"queue": {"queue_guid": "pdf-…", "confirmed": false},
"peppol_readiness": {"ready_for_peppol": true, "missing_required_fields": []},
"converted_data": {"header": {}, "lines_count": 2, "lines": []}
}POST/pdf2peppol/confirm/
Confirm the converted document+
supplier_idstringSame account key.queue_guidstringThe queue GUID returned by upload. Alias: guid.curl -X POST "https://api.peppox.com/pdf2peppol/confirm/" \
-d "supplier_id=YOUR_API_KEY" \
-d "queue_guid=QUEUE_GUID"<?php
$form = array (
'supplier_id' => 'YOUR_API_KEY',
'queue_guid' => 'QUEUE_GUID',
);
$ch = curl_init('https://api.peppox.com/pdf2peppol/confirm/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($form),
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const form = new URLSearchParams({
"supplier_id": "YOUR_API_KEY",
"queue_guid": "QUEUE_GUID"
});
const response = await fetch("https://api.peppox.com/pdf2peppol/confirm/", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: form,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
form = json.loads(r'''{
"supplier_id": "YOUR_API_KEY",
"queue_guid": "QUEUE_GUID"
}''')
response = requests.post('https://api.peppox.com/pdf2peppol/confirm/', data=form, timeout=30)
response.raise_for_status()
print(response.json()) {
"success": true,
"verification_confirmed": true,
"ready_for_peppol": true,
"send_status": "ready",
"missing_fields": []
}POST/pdf2peppol/send/
Send the confirmed document through Peppol+
supplier_idstringSame account key.queue_guidstringA confirmed and ready queue GUID. Alias: guid.curl -X POST "https://api.peppox.com/pdf2peppol/send/" \
-d "supplier_id=YOUR_API_KEY" \
-d "queue_guid=QUEUE_GUID"<?php
$form = array (
'supplier_id' => 'YOUR_API_KEY',
'queue_guid' => 'QUEUE_GUID',
);
$ch = curl_init('https://api.peppox.com/pdf2peppol/send/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($form),
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const form = new URLSearchParams({
"supplier_id": "YOUR_API_KEY",
"queue_guid": "QUEUE_GUID"
});
const response = await fetch("https://api.peppox.com/pdf2peppol/send/", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: form,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
form = json.loads(r'''{
"supplier_id": "YOUR_API_KEY",
"queue_guid": "QUEUE_GUID"
}''')
response = requests.post('https://api.peppox.com/pdf2peppol/send/', data=form, timeout=30)
response.raise_for_status()
print(response.json()) {
"success": true,
"queue_guid": "pdf-…",
"peppox_document_guid": "…",
"send_status": "sent",
"steps": {"document_create": "ok", "xml_generate": "ok"}
}POST/invoice/add/
Create an invoice header+
apikeystringAccount API key.inv_idstringYour unique invoice number; needed before UBL generation.issue_dateYYYY-MM-DDInvoice issue date.customer.endpoint_idstringBuyer Peppol endpoint identifier.customer.namestringBuyer legal or trading name.customer.street / city / postal / countrystringsBuyer postal address; needed for a Peppol-ready document.due_dateYYYY-MM-DDDefaults to issue_date at XML generation if omitted.invoice_type_code380380 by default for a sales invoice.currencyISO 4217EUR by default.buyer_reference, accounting_coststringAccounting references.payment.*objectmeans_code, payment_id, iban, account_name, bic, terms_note.delivery.*objectdate, location_scheme, location_id, street, city, postal, country, party_name.networkstringAlias: net_work. Supplier identity and bank IBAN come from the Company profile.curl -X POST "https://api.peppox.com/invoice/add/" \
-H "Content-Type: application/json" \
-d '{
"apikey": "YOUR_API_KEY",
"inv_id": "INV-2026-0042",
"issue_date": "2026-09-11",
"currency": "EUR",
"customer": {
"endpoint_scheme": "0208",
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
}'<?php
$payload = <<<'JSON'
{
"apikey": "YOUR_API_KEY",
"inv_id": "INV-2026-0042",
"issue_date": "2026-09-11",
"currency": "EUR",
"customer": {
"endpoint_scheme": "0208",
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
}
JSON;
$ch = curl_init('https://api.peppox.com/invoice/add/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const payload = {
"apikey": "YOUR_API_KEY",
"inv_id": "INV-2026-0042",
"issue_date": "2026-09-11",
"currency": "EUR",
"customer": {
"endpoint_scheme": "0208",
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
};
const response = await fetch("https://api.peppox.com/invoice/add/", {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
payload = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"inv_id": "INV-2026-0042",
"issue_date": "2026-09-11",
"currency": "EUR",
"customer": {
"endpoint_scheme": "0208",
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
}''')
response = requests.post('https://api.peppox.com/invoice/add/', json=payload, timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"invoice_guid": "…",
"status": "DRAFT"
}POST/invoice_line/add/
Add one sales invoice line+
apikeystringAccount API key.invoice_guidstringGUID returned by /invoice/add/. Alias: guid.quantitydecimalQuantity for the line.unit_codeUNECE unit codeFor example C62 for one unit.price_amountdecimalUnit price excluding VAT.item_description / item_namestringLine description and item name.tax_percentdecimalVAT rate; the API maps positive rates to category S and 0 to Z.line_idstringAlias: order_line_id; a GUID is generated if omitted.seller_item_idstringAliases: seller_id, sku.std_item_idstringAliases: gtin, ean.std_item_id_schemestring0088 by default.origin_countryISO country codeAlias: country.curl -X POST "https://api.peppox.com/invoice_line/add/" \
-H "Content-Type: application/json" \
-d '{
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID",
"line_id": "1",
"quantity": "2",
"unit_code": "C62",
"price_amount": "49.50",
"item_name": "Consulting",
"item_description": "Consulting service",
"tax_percent": "21"
}'<?php
$payload = <<<'JSON'
{
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID",
"line_id": "1",
"quantity": "2",
"unit_code": "C62",
"price_amount": "49.50",
"item_name": "Consulting",
"item_description": "Consulting service",
"tax_percent": "21"
}
JSON;
$ch = curl_init('https://api.peppox.com/invoice_line/add/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const payload = {
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID",
"line_id": "1",
"quantity": "2",
"unit_code": "C62",
"price_amount": "49.50",
"item_name": "Consulting",
"item_description": "Consulting service",
"tax_percent": "21"
};
const response = await fetch("https://api.peppox.com/invoice_line/add/", {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
payload = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID",
"line_id": "1",
"quantity": "2",
"unit_code": "C62",
"price_amount": "49.50",
"item_name": "Consulting",
"item_description": "Consulting service",
"tax_percent": "21"
}''')
response = requests.post('https://api.peppox.com/invoice_line/add/', json=payload, timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"line_guid": "…"
}POST/invoice_attach_pdf/add/
Attach or replace the invoice PDF+
apikeystringAccount API key.invoice_guidstringGUID returned by /invoice/add/. Alias: guid.PDF sourcefile or stringProvide one: multipart file; content_base64 / pdf_base64; or file_url / pdf_url (HTTP or HTTPS).doc_idstringDefaults to inv_id or a generated UUID.filenamestringattachment.pdf by default.mimestringapplication/pdf by default.curl -X POST "https://api.peppox.com/invoice_attach_pdf/add/" \
-F "apikey=YOUR_API_KEY" \
-F "invoice_guid=INVOICE_GUID" \
-F "file=@invoice.pdf"<?php
$fields = [
'apikey' => 'YOUR_API_KEY',
'invoice_guid' => 'INVOICE_GUID',
'file' => new CURLFile(__DIR__ . '/' . 'invoice.pdf', 'application/pdf'),
];
$ch = curl_init('https://api.peppox.com/invoice_attach_pdf/add/');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $fields, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append("apikey", "YOUR_API_KEY");
form.append("invoice_guid", "INVOICE_GUID");
form.append("file", new Blob([await readFile("invoice.pdf")], {type: 'application/pdf'}), "invoice.pdf");
const response = await fetch("https://api.peppox.com/invoice_attach_pdf/add/", {method: 'POST', body: form});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
data = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID"
}''')
files = {
"file": open("invoice.pdf", 'rb')
}
try:
response = requests.post('https://api.peppox.com/invoice_attach_pdf/add/', data=data, files=files, timeout=30)
response.raise_for_status()
print(response.json())
finally:
if files:
for file in files.values(): file.close() {
"ok": true,
"invoice_guid": "…",
"doc_id": "INV-2026-0042",
"filename": "invoice.pdf",
"mime": "application/pdf",
"size_bytes": 248512
}POST/xml/generate/
Generate XML and submit a sales invoice to Peppol+
apikeystringAccount API key.invoice_guidstringRequired for an invoice. Use the GUID returned by /invoice/add/; guid is accepted as an alias.networkstringStored operational network value.curl -X POST "https://api.peppox.com/xml/generate/" \
-d "apikey=YOUR_API_KEY" \
-d "invoice_guid=INVOICE_GUID"<?php
$form = array (
'apikey' => 'YOUR_API_KEY',
'invoice_guid' => 'INVOICE_GUID',
);
$ch = curl_init('https://api.peppox.com/xml/generate/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($form),
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const form = new URLSearchParams({
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID"
});
const response = await fetch("https://api.peppox.com/xml/generate/", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: form,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
form = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"invoice_guid": "INVOICE_GUID"
}''')
response = requests.post('https://api.peppox.com/xml/generate/', data=form, timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"status": "XML_BUILT",
"xml_path": "…",
"document_type": "INVOICE"
}POST/creditnote/add/
Create a credit note header+
apikeystringAccount API key.creditnote_idstringCredit note number. Aliases: cn_id, credit_note_id, inv_id.issue_dateYYYY-MM-DDCredit note issue date.customer.endpoint_id / name / addressobjectBuyer endpoint, name, street, city, postal code and country.invoice_type_code381381 by default for a credit note.due_date, currency, buyer_reference, accounting_costvaluesSame meaning as /invoice/add/.payment.*, delivery.*, networkobjects / stringSame field structure as /invoice/add/.curl -X POST "https://api.peppox.com/creditnote/add/" \
-H "Content-Type: application/json" \
-d '{
"apikey": "YOUR_API_KEY",
"creditnote_id": "CN-2026-001",
"issue_date": "2026-09-11",
"customer": {
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
}'<?php
$payload = <<<'JSON'
{
"apikey": "YOUR_API_KEY",
"creditnote_id": "CN-2026-001",
"issue_date": "2026-09-11",
"customer": {
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
}
JSON;
$ch = curl_init('https://api.peppox.com/creditnote/add/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const payload = {
"apikey": "YOUR_API_KEY",
"creditnote_id": "CN-2026-001",
"issue_date": "2026-09-11",
"customer": {
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
};
const response = await fetch("https://api.peppox.com/creditnote/add/", {
method: 'POST',
headers: {'Content-Type': 'application/json'},
body: JSON.stringify(payload),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
payload = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"creditnote_id": "CN-2026-001",
"issue_date": "2026-09-11",
"customer": {
"endpoint_id": "0123456789",
"name": "Buyer Ltd",
"street": "Main Street 1",
"city": "Brussels",
"postal": "1000",
"country": "BE"
}
}''')
response = requests.post('https://api.peppox.com/creditnote/add/', json=payload, timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"invoice_guid": "…",
"document_type": "CREDIT_NOTE",
"status": "DRAFT"
}POST/creditnote_line/add/
Add one credit note line+
apikeystringAccount API key.creditnote_guidstringGUID returned by /creditnote/add/. Aliases: invoice_guid, guid.quantitydecimalRequired.price_amountdecimalRequired unit price.unit_code, item_name, item_description, tax_percentvaluesUse the same structure as /invoice_line/add/.line_id, seller_item_id, std_item_id, std_item_id_scheme, origin_countryvaluesSame aliases and defaults as sales invoice lines.curl -X POST "https://api.peppox.com/creditnote_line/add/" \
-d "apikey=YOUR_API_KEY" \
-d "creditnote_guid=CREDITNOTE_GUID" \
-d "quantity=1" -d "unit_code=C62" \
-d "price_amount=49.50" -d "item_name=Refund" \
-d "item_description=Service refund" -d "tax_percent=21"<?php
$form = array (
'apikey' => 'YOUR_API_KEY',
'creditnote_guid' => 'CREDITNOTE_GUID',
'quantity' => '1',
'unit_code' => 'C62',
'price_amount' => '49.50',
'item_name' => 'Refund',
'item_description' => 'Service refund',
'tax_percent' => '21',
);
$ch = curl_init('https://api.peppox.com/creditnote_line/add/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($form),
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const form = new URLSearchParams({
"apikey": "YOUR_API_KEY",
"creditnote_guid": "CREDITNOTE_GUID",
"quantity": "1",
"unit_code": "C62",
"price_amount": "49.50",
"item_name": "Refund",
"item_description": "Service refund",
"tax_percent": "21"
});
const response = await fetch("https://api.peppox.com/creditnote_line/add/", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: form,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
form = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"creditnote_guid": "CREDITNOTE_GUID",
"quantity": "1",
"unit_code": "C62",
"price_amount": "49.50",
"item_name": "Refund",
"item_description": "Service refund",
"tax_percent": "21"
}''')
response = requests.post('https://api.peppox.com/creditnote_line/add/', data=form, timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"line_guid": "…"
}POST/creditnote_attach_pdf/add/
Attach or replace the credit note PDF+
apikeystringAccount API key.creditnote_guidstringCredit note GUID. Aliases: invoice_guid, guid.PDF sourcefile or stringmultipart file, content_base64 / pdf_base64, or HTTP(S) file_url / pdf_url.doc_id, filename, mimevaluesSame meaning and defaults as the sales invoice attachment endpoint.curl -X POST "https://api.peppox.com/creditnote_attach_pdf/add/" \
-F "apikey=YOUR_API_KEY" \
-F "creditnote_guid=CREDITNOTE_GUID" \
-F "file=@credit-note.pdf"<?php
$fields = [
'apikey' => 'YOUR_API_KEY',
'creditnote_guid' => 'CREDITNOTE_GUID',
'file' => new CURLFile(__DIR__ . '/' . 'credit-note.pdf', 'application/pdf'),
];
$ch = curl_init('https://api.peppox.com/creditnote_attach_pdf/add/');
curl_setopt_array($ch, [CURLOPT_POST => true, CURLOPT_POSTFIELDS => $fields, CURLOPT_RETURNTRANSFER => true, CURLOPT_TIMEOUT => 30]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));import { readFile } from 'node:fs/promises';
const form = new FormData();
form.append("apikey", "YOUR_API_KEY");
form.append("creditnote_guid", "CREDITNOTE_GUID");
form.append("file", new Blob([await readFile("credit-note.pdf")], {type: 'application/pdf'}), "credit-note.pdf");
const response = await fetch("https://api.peppox.com/creditnote_attach_pdf/add/", {method: 'POST', body: form});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
data = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"creditnote_guid": "CREDITNOTE_GUID"
}''')
files = {
"file": open("credit-note.pdf", 'rb')
}
try:
response = requests.post('https://api.peppox.com/creditnote_attach_pdf/add/', data=data, files=files, timeout=30)
response.raise_for_status()
print(response.json())
finally:
if files:
for file in files.values(): file.close() {
"ok": true,
"creditnote_guid": "…",
"doc_id": "CN-2026-001",
"filename": "credit-note.pdf",
"size_bytes": 194221
}POST/xml/generate/
Generate XML and submit a credit note to Peppol+
apikeystringAccount API key.creditnote_guidstringRequired for a credit note. Use the GUID returned by /creditnote/add/; invoice_guid or guid are accepted aliases.networkstringStored operational network value.curl -X POST "https://api.peppox.com/xml/generate/" \
-d "apikey=YOUR_API_KEY" \
-d "creditnote_guid=CREDITNOTE_GUID"<?php
$form = array (
'apikey' => 'YOUR_API_KEY',
'creditnote_guid' => 'CREDITNOTE_GUID',
);
$ch = curl_init('https://api.peppox.com/xml/generate/');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => http_build_query($form),
CURLOPT_HTTPHEADER => ['Content-Type: application/x-www-form-urlencoded'],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_TIMEOUT => 30,
]);
$response = curl_exec($ch);
if ($response === false) { throw new RuntimeException(curl_error($ch)); }
curl_close($ch);
print_r(json_decode($response, true, 512, JSON_THROW_ON_ERROR));const form = new URLSearchParams({
"apikey": "YOUR_API_KEY",
"creditnote_guid": "CREDITNOTE_GUID"
});
const response = await fetch("https://api.peppox.com/xml/generate/", {
method: 'POST',
headers: {'Content-Type': 'application/x-www-form-urlencoded'},
body: form,
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
console.log(await response.json());import json
import requests
form = json.loads(r'''{
"apikey": "YOUR_API_KEY",
"creditnote_guid": "CREDITNOTE_GUID"
}''')
response = requests.post('https://api.peppox.com/xml/generate/', data=form, timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"status": "XML_BUILT",
"xml_path": "…",
"document_type": "CREDIT_NOTE"
}GET/invoice/list/
List stored structured invoice records+
apikeystringAccount API key.profilemini | customer | fullSelects a field preset.fieldscomma-separated namesOverrides the preset with allowed fields.invoice_guid, inv_id, status, networkstringsExact filters.from, toYYYY-MM-DDIssue-date range.limit, offsetintegerslimit defaults to 100 and is capped at 500.pretty1Pretty-prints JSON.curl "https://api.peppox.com/invoice/list/?apikey=YOUR_API_KEY&profile=mini&status=XML_BUILT&limit=50"<?php
$response = file_get_contents('https://api.peppox.com/invoice/list/?apikey=YOUR_API_KEY&profile=mini&status=XML_BUILT&limit=50');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/invoice/list/?apikey=YOUR_API_KEY&profile=mini&status=XML_BUILT&limit=50");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/invoice/list/?apikey=YOUR_API_KEY&profile=mini&status=XML_BUILT&limit=50', timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"count": 1,
"fields": ["invoice_guid", "inv_id", "status"],
"filters": {"status": "XML_BUILT", "limit": 50},
"data": [{"invoice_guid": "…", "inv_id": "INV-2026-0042", "status": "XML_BUILT"}]
}GET/doc-sent/header/list/
List sent document headers+
supplier_idstringAccount API key / supplier identifier.page, per_pageintegerspage defaults to 1; per_page defaults to 300 and is capped at 300.qstringKeyword search across indexed document fields.date, date_from, date_toYYYY-MM-DDExact day or date range.date_fieldfield nameissue_date, due_date, delivery_date, xml_built_at, sent_at, created_at, updated_at or status_from_peppol_date; sent_at by default.status_from_peppol / statusstring or CSVOne or more Peppol statuses.local_statusstring or CSVOne or more local invoice statuses.include_raw, search_raw1 / trueInclude or search raw upstream fields.sort_by, sort_dirfield / ASC|DESCsent_at and DESC by default.curl "https://api.peppox.com/doc-sent/header/list/?supplier_id=YOUR_API_KEY&page=1&per_page=50&status=accepted&date_from=2026-09-01"<?php
$response = file_get_contents('https://api.peppox.com/doc-sent/header/list/?supplier_id=YOUR_API_KEY&page=1&per_page=50&status=accepted&date_from=2026-09-01');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/doc-sent/header/list/?supplier_id=YOUR_API_KEY&page=1&per_page=50&status=accepted&date_from=2026-09-01");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/doc-sent/header/list/?supplier_id=YOUR_API_KEY&page=1&per_page=50&status=accepted&date_from=2026-09-01', timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"endpoint": "doc-sent/header/list",
"pagination": {"page": 1, "per_page": 50, "total": 1, "has_next": false},
"data": [{"invoice_guid": "…", "inv_id": "INV-2026-0042", "status_from_peppol": "accepted"}]
}GET/doc-sent/lines/list/
List lines of one sent document+
supplier_idstringAccount API key / supplier identifier.invoice_guidstringGUID returned by the sent-header list.qstringSearch line fields.page, per_pageintegerspage 1 and per_page 300 by default; maximum 300.curl "https://api.peppox.com/doc-sent/lines/list/?supplier_id=YOUR_API_KEY&invoice_guid=INVOICE_GUID&page=1&per_page=100"<?php
$response = file_get_contents('https://api.peppox.com/doc-sent/lines/list/?supplier_id=YOUR_API_KEY&invoice_guid=INVOICE_GUID&page=1&per_page=100');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/doc-sent/lines/list/?supplier_id=YOUR_API_KEY&invoice_guid=INVOICE_GUID&page=1&per_page=100");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/doc-sent/lines/list/?supplier_id=YOUR_API_KEY&invoice_guid=INVOICE_GUID&page=1&per_page=100', timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"invoice": {"invoice_guid": "…", "inv_id": "INV-2026-0042"},
"pagination": {"page": 1, "total": 2},
"data": [{"line_id": "1", "quantity": "2", "price_amount": "49.50"}]
}GET/doc-received/header/list/
List received document headers+
supplier_idstringAccount API key / supplier identifier.page, per_pageintegerspage 1 and per_page 300 by default; maximum 300.qstringKeyword search.date, date_from, date_toYYYY-MM-DDExact day or range.date_fieldfield nameapi_created_at by default; issue_date, due_date, tax_point_date, created_at and updated_at are supported.import_status / statusstring or CSVOne or more import statuses.document_type_code / type_codestring or CSVFilter by document type, for example 380 or 381.include_raw, search_raw1 / trueInclude or search raw XML/parser fields.sort_by, sort_dirfield / ASC|DESCapi_created_at and DESC by default.curl "https://api.peppox.com/doc-received/header/list/?supplier_id=YOUR_API_KEY&document_type_code=380&date_from=2026-09-01&per_page=50"<?php
$response = file_get_contents('https://api.peppox.com/doc-received/header/list/?supplier_id=YOUR_API_KEY&document_type_code=380&date_from=2026-09-01&per_page=50');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/doc-received/header/list/?supplier_id=YOUR_API_KEY&document_type_code=380&date_from=2026-09-01&per_page=50");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/doc-received/header/list/?supplier_id=YOUR_API_KEY&document_type_code=380&date_from=2026-09-01&per_page=50', timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"endpoint": "doc-received/header/list",
"pagination": {"page": 1, "per_page": 50, "total": 1},
"data": [{"document_id": "…", "document_number": "SUP-1048", "supplier_name": "Supplier Ltd", "payable_amount": "1250.00"}]
}GET/doc-received/lines/list/
List lines of one received document+
supplier_idstringAccount API key / supplier identifier.document_idstringflowin_document_id returned by /doc-received/header/list/.qstringSearch line fields.page, per_pageintegerspage 1 and per_page 300 by default; maximum 300.include_raw, search_raw1 / trueInclude or search raw_line_xml and parser_json.sort_by, sort_dirfield / ASC|DESCline_no and ASC by default.curl "https://api.peppox.com/doc-received/lines/list/?supplier_id=YOUR_API_KEY&document_id=DOCUMENT_ID&per_page=100"<?php
$response = file_get_contents('https://api.peppox.com/doc-received/lines/list/?supplier_id=YOUR_API_KEY&document_id=DOCUMENT_ID&per_page=100');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/doc-received/lines/list/?supplier_id=YOUR_API_KEY&document_id=DOCUMENT_ID&per_page=100");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/doc-received/lines/list/?supplier_id=YOUR_API_KEY&document_id=DOCUMENT_ID&per_page=100', timeout=30)
response.raise_for_status()
print(response.json()) {
"ok": true,
"invoice": {"document_id": "…", "document_number": "SUP-1048"},
"data": [{"line_id": "1", "item_name": "Service", "quantity": "1", "unit_price": "1250.00", "vat_rate": "21"}]
}GET/ap/get/
Check a Peppol participant and discover endpoint information+
schemestringParticipant identifier scheme, for example 0208.valuestringParticipant identifier value.smldigitprod or digittestdigitprod by default for the SMP query.withEndpointsbooleantrue by default; set false to skip endpoint lookup.prettyyes / true / 1Returns a simplified result.onlynameWith pretty enabled, returns only the entity name.curl "https://api.peppox.com/ap/get/?scheme=0208&value=0123456789&sml=digitprod&pretty=1"<?php
$response = file_get_contents('https://api.peppox.com/ap/get/?scheme=0208&value=0123456789&sml=digitprod&pretty=1');
if ($response === false) { throw new RuntimeException('Peppox request failed'); }
$result = json_decode($response, true, 512, JSON_THROW_ON_ERROR);
print_r($result);const response = await fetch("https://api.peppox.com/ap/get/?scheme=0208&value=0123456789&sml=digitprod&pretty=1");
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await response.json();
console.log(result);import requests
response = requests.get('https://api.peppox.com/ap/get/?scheme=0208&value=0123456789&sml=digitprod&pretty=1', timeout=30)
response.raise_for_status()
print(response.json()) {
"name_entity": "Example Company",
"serviceDescription": "…",
"technicalContactUrl": "…"
}The Peppox dashboard provides guided forms that call the APIs for you. They make it easy to discover required parameters, test realistic documents and understand the JSON response before connecting your ERP.
invoice_guidLinks a structured header, lines, PDF and generated XML.
queue_guidLinks the four PDF2Peppol calls while extraction is in progress.
document GUIDLinks the final document to delivery tracking and reconciliation.
Send, receive and monitor Peppol documents through one secure API and one clear dashboard.