Reference
PeppolFlow API
Create, issue, and deliver EN 16931 / Peppol BIS 3.0 invoices programmatically. All responses are JSON, all requests are authenticated with an API key scoped to a single organization.
Authentication
All requests require an API key issued from Settings → API Keys. Keys look like ifk_live_… and are shown exactly once at creation time — store them securely. Keys are scoped to a single organization and can be revoked individually.
Pass the key as a bearer token (preferred) or as an X-Api-Key header:
# Bearer (preferred)
curl https://peppolflow.eu/api/v1/health \
-H "Authorization: Bearer ifk_live_..."
# X-Api-Key (convenience)
curl https://peppolflow.eu/api/v1/health \
-H "X-Api-Key: ifk_live_..."Errors & status codes
Errors return a JSON body with an error field. Validation errors return a structured Zod error tree.
| Code | Meaning |
|---|---|
| 200 | Success. |
| 201 | Resource created. |
| 400 | Bad request — typically a validation error. |
| 401 | Missing, invalid, or revoked API key. |
| 404 | Resource not found (or not in your org). |
| 502 | Upstream failure (Peppol AP, email provider). |
| 503 | Feature disabled (provider not configured). |
Endpoints
Verify your API key is active. Returns the organization id and key prefix.
Example request
curl https://peppolflow.eu/api/v1/health \
-H "Authorization: Bearer ifk_live_..."Example response
{
"ok": true,
"organizationId": "clx9ab...",
"apiKeyPrefix": "ifk_live_Xy",
"version": "v1"
}List invoices for your organization, most recent first.
Query parameters
| status | string | Filter: DRAFT | ISSUED | SENT | PAID | CANCELLED |
| limit | number | Max results (default 50, max 200) |
| cursor | string | Invoice id for pagination (pass nextCursor from previous response) |
Example request
curl "https://peppolflow.eu/api/v1/invoices?status=SENT&limit=20" \
-H "Authorization: Bearer ifk_live_..."Example response
{
"invoices": [
{
"id": "clx9ab...",
"number": "INV-2026-0042",
"status": "SENT",
"issueDate": "2026-04-20T00:00:00.000Z",
"dueDate": "2026-05-20T00:00:00.000Z",
"total": 1210,
"customer": { "id": "...", "name": "Acme GmbH", "email": "ap@acme.de", "peppolId": "9930:DE123456789" },
"lines": [ ... ]
}
],
"pagination": { "limit": 20, "nextCursor": "clx9ab...", "hasMore": true }
}Create a DRAFT invoice. Call /issue to generate UBL, archive the XML, and deliver.
Example request
curl -X POST https://peppolflow.eu/api/v1/invoices \
-H "Authorization: Bearer ifk_live_..." \
-H "Content-Type: application/json" \
-d '{
"customerId": "clx9ab...",
"issueDate": "2026-04-23",
"dueDate": "2026-05-23",
"currency": "EUR",
"paymentTerms": "Net 30",
"lines": [
{
"description": "Consulting services — April",
"quantity": 10,
"unitPrice": 120,
"vatRate": 21
}
]
}'Example response
{
"invoice": {
"id": "clx9ab...",
"number": "INV-2026-0043",
"status": "DRAFT",
"subtotal": 1200,
"taxTotal": 252,
"total": 1452,
"lines": [ ... ]
}
}Fetch a single invoice, including its line items, customer, and supplier snapshot.
Example request
curl https://peppolflow.eu/api/v1/invoices/clx9ab... \
-H "Authorization: Bearer ifk_live_..."Issue a DRAFT invoice. This builds the UBL XML, archives it (Invoice.ublXml — the 10-year archival requirement depends on this write), flips status to ISSUED, and triggers delivery: • deliveryMethod = PEPPOL: hands off to Storecove. Response includes peppol.guid. • deliveryMethod = EMAIL: emails the customer (HTML body + PDF + UBL attachments) and flips status to SENT.
Example request
curl -X POST https://peppolflow.eu/api/v1/invoices/clx9ab.../issue \
-H "Authorization: Bearer ifk_live_..."Example response
{
"invoice": { "id": "clx9ab...", "status": "SENT", "deliveredAt": "2026-04-23T22:30:00Z", ... },
"peppol": { "attempted": false, "ok": false, "reason": "Delivery method is not PEPPOL" },
"email": { "attempted": true, "ok": true, "id": "resend_msg_...", "recipient": "ap@acme.de" }
}Create a fresh DRAFT invoice from an existing one. Copies customer, currency, line items, notes, and payment terms. Generates a new invoice number. Original payment term in days is preserved (today + termDays).
Example request
curl -X POST https://peppolflow.eu/api/v1/invoices/clx9ab.../duplicate \
-H "Authorization: Bearer ifk_live_..."Example response
{
"invoice": {
"id": "clxNEW...",
"number": "INV-2026-0044",
"status": "DRAFT",
"issueDate": "2026-04-23T...",
"dueDate": "2026-05-23T...",
"lines": [ ... ]
}
}List customers for your organization. VAT numbers are auto-validated against VIES when added via the dashboard.
Example request
curl https://peppolflow.eu/api/v1/customers \
-H "Authorization: Bearer ifk_live_..."