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.

Version: v1
Base URL: https://peppolflow.eu/api/v1
Content-Type: application/json

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.

CodeMeaning
200Success.
201Resource created.
400Bad request — typically a validation error.
401Missing, invalid, or revoked API key.
404Resource not found (or not in your org).
502Upstream failure (Peppol AP, email provider).
503Feature disabled (provider not configured).

Endpoints

GET/api/v1/health

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"
}
GET/api/v1/invoices

List invoices for your organization, most recent first.

Query parameters

statusstringFilter: DRAFT | ISSUED | SENT | PAID | CANCELLED
limitnumberMax results (default 50, max 200)
cursorstringInvoice 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 }
}
POST/api/v1/invoices

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": [ ... ]
  }
}
GET/api/v1/invoices/:id

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_..."
POST/api/v1/invoices/:id/issue

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" }
}
POST/api/v1/invoices/:id/duplicate

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": [ ... ]
  }
}
GET/api/v1/customers

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_..."