Skip to content

Send an Invoice

Send invoices to the Peppol network with attachments, allowances, charges, and delivery details.

POST /api/v1/invoices #

Send a Peppol invoice. The API validates the payload against BIS 3.0 business rules, generates UBL XML, and delivers it to the buyer's access point.

Parties

Both from (seller) and to (buyer) require a name, peppolId, and country. Add vatNumber and address for full compliance.

Line Items

Each line needs description, quantity, unitPrice, and vatRate. Amounts are calculated automatically — no need for manual totals.

Payment

Add paymentTerms and paymentIban to include payment instructions. Strongly recommended for Belgian and French mandates.

Parameters

NameTypeRequiredDescription
numberstringRequiredUnique invoice number (e.g. INV-2026-042)
fromPartyRequiredSeller details: name, peppolId, country
toBuyerPartyRequiredBuyer details: name, peppolId, street, city, postalCode, country
linesInvoiceLine[]RequiredLine items with description, quantity, unitPrice, vatRate
issueDatestringOptionalISO 8601 date (defaults to today)
dueDatestringOptionalISO 8601 payment due date
currencystringOptionalISO 4217 currency code (default: "EUR")
paymentTermsstringOptionalPayment terms description
paymentIbanstringOptionalIBAN for bank transfer
attachmentsAttachment[]OptionalEmbedded or external file attachments
allowancesAllowanceCharge[]OptionalDocument-level discounts
chargesAllowanceCharge[]OptionalDocument-level surcharges
deliveryDeliveryOptionalDelivery date and address
invoicePeriodInvoicePeriodOptionalBilling period (start/end dates)
notestringOptionalFree-text note for the buyer
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_live_..." });

const result = await peppol.invoices.send({
  number: "INV-2026-042",

  // Seller (you)
  from: {
    name: "Stark Industries BVBA",
    peppolId: "0208:BE0476748862",
    vatNumber: "BE0476748862",
    address: { street: "Rue de la Loi 1", city: "Brussels", postalCode: "1000", country: "BE" },
  },

  // Buyer
  to: {
    name: "Wayne Enterprises NV",
    peppolId: "0208:BE0123456789",
    country: "BE",
    buyerReference: "PO-2026-007",
  },

  // Line items
  lines: [
    { description: "Arc Reactor Maintenance Q1", quantity: 1, unitPrice: 50_000, vatRate: 21 },
    { description: "Vibranium Shield Polish",    quantity: 3, unitPrice: 250,    vatRate: 21 },
  ],

  // Payment
  paymentTerms: "Net 30 days",
  paymentIban: "BE68539007547034",

  // Optional
  issueDate: "2026-03-01",
  dueDate: "2026-03-31",
  note: "Thank you for your business!",
});

console.log(`Sent! ID: ${result.id}, Status: ${result.status}`);

Attachments

Attach supporting documents to your invoices — PDF copies, timesheets, contracts, or any file. Supports both embedded (base64) and external URL references.

Embedded

Provide filename, mimeType, and base64-encoded content. The file is included directly in the UBL XML.

External URL

Provide a url instead. The buyer's access point will fetch the document. Make sure the URL is publicly accessible.

Max embedded attachment size is 10 MB. For larger files, use an external URL.
import { Peppol } from "@getpeppr/sdk";
import { readFileSync } from "fs";

const peppol = new Peppol({ apiKey: "sk_live_..." });

const result = await peppol.invoices.send({
  number: "INV-2026-043",
  from: { name: "Acme BVBA", peppolId: "0208:BE0456789012", country: "BE" },
  to:   { name: "Globex NV", peppolId: "0208:BE0987654321", street: "Rue de la Loi 200", city: "Brussels", postalCode: "1000", country: "BE" },
  lines: [
    { description: "Consulting Q1", quantity: 40, unitPrice: 125, vatRate: 21 },
  ],

  // Embed a PDF copy of the invoice
  attachments: [
    {
      id: "ATT-001",
      filename: "invoice-2026-043.pdf",
      mimeType: "application/pdf",
      content: readFileSync("./invoice.pdf").toString("base64"),
    },
    // Or reference an external document
    {
      id: "ATT-002",
      description: "Detailed timesheet",
      url: "https://acme.com/docs/timesheet-q1.pdf",
    },
  ],
});

Allowances & Charges

Apply discounts (allowances) and surcharges to invoices at both the document level and line level.

Document-level

Use allowances for discounts and charges for surcharges that apply to the entire invoice. Each requires reason, amount, and vatRate.

Line-level

Add allowances or charges to individual line items. Line-level adjustments only need reason and amount.

Allowances and charges follow BIS 3.0 business groups BG-20 (document allowances), BG-21 (document charges), BG-27 (line allowances), and BG-28 (line charges). See Type Definitions for the full interface.
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_live_..." });

const result = await peppol.invoices.send({
  number: "INV-2026-044",
  from: { name: "Acme BVBA", peppolId: "0208:BE0456789012", country: "BE" },
  to:   { name: "Globex NV", peppolId: "0208:BE0987654321", street: "Rue de la Loi 200", city: "Brussels", postalCode: "1000", country: "BE" },

  lines: [
    {
      description: "Consulting hours",
      quantity: 40,
      unitPrice: 125,
      vatRate: 21,
      // Line-level discount
      allowances: [{ reason: "Loyalty discount", amount: 200 }],
    },
  ],

  // Document-level discount (applies to entire invoice)
  allowances: [
    { reason: "Early payment discount (2%)", amount: 100, vatRate: 21 },
  ],

  // Document-level surcharge
  charges: [
    { reason: "Express delivery fee", amount: 50, vatRate: 21 },
  ],
});

Delivery & Period

Specify delivery details and billing periods for invoices that cover goods delivery or service periods.

Delivery

Add a delivery object with an optional date and address. Some EU countries (e.g. Italy, Spain) require delivery information on invoices.

Invoice Period

Use invoicePeriod with startDate and endDate for subscriptions, retainers, or any service billed over a time range.

For SaaS and subscription billing, always include invoicePeriod — it's required by some national rules and improves reconciliation for your buyers.
import { Peppol } from "@getpeppr/sdk";

const peppol = new Peppol({ apiKey: "sk_live_..." });

const result = await peppol.invoices.send({
  number: "INV-2026-045",
  from: { name: "Acme BVBA", peppolId: "0208:BE0456789012", country: "BE" },
  to:   { name: "Globex NV", peppolId: "0208:BE0987654321", street: "Rue de la Loi 200", city: "Brussels", postalCode: "1000", country: "BE" },
  lines: [
    { description: "Server hardware", quantity: 10, unitPrice: 2500, vatRate: 21 },
  ],

  // Delivery details (mandatory in some EU countries)
  delivery: {
    date: "2026-03-15",
    address: {
      street: "Rue de la Science 14",
      city: "Brussels",
      postalCode: "1000",
      country: "BE",
    },
  },

  // Billing period (common for SaaS / subscriptions)
  invoicePeriod: {
    startDate: "2026-01-01",
    endDate: "2026-03-31",
  },
});