LedgerBee Developer
  • Getting started
  • Conventions
  • Products
  • Configuration
  • API Reference
Subscriptions
Payment flowCard paymentsProducts & PricingProduct Entitlements
Billing documents
    OverviewInvoicesCredit notesQuotesOrder confirmationsDocument templates
Accounting
WebhooksPartner-Hosted Checkout
Customer Portal
Billing documents

Invoices

An invoice is a booked accounting document: sending allocates its number and posts it to the books. Reads require the invoices-read scope and writes invoices-write — one scope pair covers invoices and credit notes. The shared line model, list/get/PDF reads, and send channels are in Billing documents; this page covers what is specific to invoices.

Lifecycle

PhaseWhat happens
CreatePOST /v1/invoices returns a draft. The draft has no number yet (number is null).
SendPOST /v1/invoices/{id}/send books the document, allocates the invoice number, and delivers it over the chosen channel.
DownloadGET /v1/invoices/{id}/pdf streams the rendered PDF at any point. Before send, pass ?draft=true for a watermarked preview.
TrackGET /v1/invoices/{id}/delivery-status returns the aggregate send summary plus a per-attempt log.

Create an invoice

POST /v1/invoices returns the draft as PublicInvoice. customerId is required, and the document must carry at least one product line (see Document lines). A billable line sends a priceId and a quantity; you may override unitPrice (it defaults to the price's current amount in the document currency). totalPrice (= quantity * unitPrice) and VAT (vatRate / vatAmount, derived from the product and the customer's VAT zone) are computed server-side — do not send them. The invoice number stays null until the document is sent.

dueDate is optional. When omitted it is derived from the payment terms (date plus paymentTerms days; for cash terms the due date is the invoice date). An explicit dueDate may equal date but must not be earlier — see Errors.

TerminalCode
curl -X POST 'https://api.ledgerbee.com/api/v1/invoices' \ -H 'x-api-key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "customerId": "0197a943-2325-7829-b835-b6c71a293065", "date": "2026-01-15", "dueDate": "2026-02-14", "currency": "DKK", "paymentTerms": 30, "lines": [ { "priceId": "0197a943-2325-7829-b835-b6c71a293099", "quantity": 2 } ] }'

Status values

Invoice status is one of draft, scheduled, sending, sent, paid, partially_paid, cancelled, uncollectible, credited.

Send

POST /v1/invoices/{id}/send books the document and allocates its number. What happens next is the deliveryType channel's business — Manual stops there and leaves delivery to you. Invoices accept every channel; see Sending.

TerminalCode
curl -X POST 'https://api.ledgerbee.com/api/v1/invoices/0197a943-2325-7829-b835-b6c71a293066/send' \ -H 'x-api-key: YOUR_API_KEY' \ -H 'Content-Type: application/json' \ -d '{ "deliveryType": "Email", "overrideEmail": "billing@acme.example" }'

overrideEmail and overrideEanNumber apply to the single send unless updateCustomerRecord is true, which persists them onto the customer record. documentTemplateId overrides the PDF template for this send. The response carries success, deliveryType, and sproomDocumentId (the id of the document created on the Sproom network, for a Sproom send).

Delivery status

GET /v1/invoices/{id}/delivery-status returns a summary (send count, last channel, last recipient, last send time) and a chronological entries log of every attempt with its status (success / failed), deliveryType, recipient, sentAt, and errorCode on failure.

A Sproom send rejected by the network does not fail the request synchronously; it records a failed delivery entry with its errorCode. Poll delivery-status after a Sproom send to confirm the outcome.

Errors

ConditionResponseFix
Missing or wrong scope403Grant the matching read or write scope.
Non-UUID id / unknown id400 / 404Pass a UUID id that exists for your tenant.
dueDate earlier than date400 INVOICE_DUE_DATE_BEFORE_ISSUE_DATESend a due date on or after the invoice date, or omit dueDate to derive it from the payment terms.
scheduledSendAt on cash payment terms400 INVOICE_CASH_CANNOT_BE_SCHEDULEDCash invoices are paid on send; remove scheduledSendAt or use day-count terms.
Card payment providers with no customer400 INVOICE_CARD_PAY_REQUIRES_CUSTOMERSet customerId when enabling allowedPaymentProviders.

Subscription and billing-group invoices

Three fields on an invoice say who it bills:

FieldSet when
customerSubscriptionIdThe invoice bills exactly one subscription.
billingGroupIdThe invoice is a billing group's shared document. Never set together with customerSubscriptionId.
isConsolidatedSeveral subscriptions bill onto this one document: a billing group's shared invoice, or a parent customer's invoice covering its child customers' subscriptions. With both ids null it is the parent-paid kind.

A manually created invoice carries neither id. List a group's documents with GET /v1/invoices?billingGroupId=<uuid>.

Webhook events

Subscription-driven invoices (those the billing engine sends) emit the billing.invoice_sent topic. On a billing group's shared invoice the payload's subscriptionId is null; read the invoice for its billingGroupId. Invoices you create and send directly over this API are booked the same way but are not subscription events. Webhooks covers endpoint setup, the signed-envelope format, and the full topic list.

Last modified on September 13, 2026
OverviewCredit notes
On this page
  • Lifecycle
  • Create an invoice
  • Status values
  • Send
  • Delivery status
  • Errors
  • Subscription and billing-group invoices
  • Webhook events