# Billing documents

LedgerBee has four customer-facing documents, all built on the same line model
and rendered to PDF. Two are **booked** accounting documents and two are
**pre-sales** documents that convert forward into a booked invoice:

| Document | Booked? | Page |
|---|---|---|
| Invoice | yes — posts to the books on send | [Invoices](/guides/billing-documents/invoices) |
| Credit note | yes — posts to the books on send | [Credit notes](/guides/billing-documents/credit-notes) |
| Quote | no — a price offer | [Quotes](/guides/billing-documents/quotes) |
| Order confirmation | no — confirms an agreed order | [Order confirmations](/guides/billing-documents/order-confirmations) |

All endpoints live under `https://api.ledgerbee.com/api/v1` and authenticate with
the `x-api-key` header. Full request/response schemas live in the
[API Reference](/api). This page covers what the four share; each document's own
page covers its lifecycle, creation, and type-specific operations.

## Scopes

Each resource has its own scope pair (see [API Keys](/guides/api-keys)). Invoices
and credit notes share one pair:

| Resource | Read | Write |
|---|---|---|
| Invoices & credit notes | `invoices-read` | `invoices-write` |
| Quotes | `quotes-read` | `quotes-write` |
| Order confirmations | `order-confirmations-read` | `order-confirmations-write` |

Read scopes cover list, get, and PDF; write scopes cover create, update, send,
and convert.

## Document lines

A line is one of two kinds, and what you send depends on the kind. The same rules
apply to invoices, credit notes, quotes, and order confirmations.

| Line kind | How to send it | Amounts & VAT |
| --- | --- | --- |
| Product line | Set `priceId` (required) and `quantity`. Optionally override `unitPrice`, and set `description` for custom line text. | Derived server-side: `totalPrice = quantity * unitPrice`, VAT from the product and the customer's VAT zone. Do not send `totalPrice` / `vatRate` / `vatAmount`. |
| Text / separator line | Set `lineType` to `text` or `separator`. `priceId` and `quantity` are not required for these lines — omit them. | None — do not send `totalPrice` / `vatRate` / `vatAmount`. |

Every billable line must reference a `priceId` from the
[product catalogue](/guides/products-pricing). A document must contain at least
one product line; text / separator lines may accompany it but do not satisfy the
rule on their own. There is no hand-typed amount line — a billable line always
bills a catalogue price.

Lines are returned in the **order you list them in the `lines` array**: the API
stamps your submission order onto each line. There is no separate sort field; to
reorder, send the array in the order you want.

Creation does not dedupe retried requests. When a timeout leaves the outcome
unknown, list recently created documents before re-creating. See
[Idempotency](/guides/idempotency).

## Reading documents

Every resource exposes the same read surface:

| Action | Path |
|---|---|
| List | `GET /v1/{resource}` |
| Get one | `GET /v1/{resource}/{id}` |
| Download PDF | `GET /v1/{resource}/{id}/pdf` |

Lists paginate (`page`, default 1; `limit`, default 25, max 100) and filter by
`customerId` and `status` (plus free-text `search` on invoices/credit notes, and
`sortBy` / `sortOrder` on quotes/order confirmations). The `status` filter matches
the **display** status, so server-derived states work too — each document page
lists its own status values. List items omit the `lines` breakdown; get a single
document to read its lines. Every `{id}` path segment is a UUID.

`GET /v1/{resource}/{id}/pdf` streams `application/pdf` as an attachment. Pass
`?draft=true` to render a watermarked draft preview before the document is sent.

## Sending

`POST /v1/{resource}/{id}/send` allocates the document number (if not already
set), renders the PDF, and delivers it over the chosen channel. The body's
`deliveryType` selects the channel:

| `deliveryType` | Behaviour |
|---|---|
| `Manual` | Allocates the number without delivering. Download the PDF and deliver it yourself. |
| `Email` | Emails the rendered PDF. The recipient resolves from the request's email field, else the customer contact, else the customer record. |
| `Sproom` | **Invoices and credit notes only.** Delivers over the Sproom e-invoicing network. There is no legal e-invoice type for a quote or order confirmation. |

When you send by email to an address that isn't already a contact of the customer,
that email is created as a customer contact and linked to the document (matching
the gated app); an email that already matches a contact reuses it.
`documentTemplateId` overrides the PDF template for a single send. The exact
recipient field names differ by resource — see each document's page.

## Errors

| Condition | Response | Fix |
|---|---|---|
| Invalid request (e.g. non-UUID `{id}`) | `400` | Pass a UUID id and a body matching the schema. |
| Invalid or missing API key | `401` | Send a valid `x-api-key` header. |
| API key missing required scopes | `403` | Grant the key the resource's read / write scope. |
| Email send with no resolvable recipient | the send fails | Pass the recipient email, or set an email on the customer / contact. |

Type-specific errors (conversion, locked-after-convert, …) are on each document's
page.
