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

Quotes

A quote is a customer-facing price offer. It produces no journal entry and is never booked; it converts forward into an order confirmation or a booked invoice. Reads require the quotes-read scope and writes quotes-write. The shared line model, list/get/PDF reads, and email delivery are in Billing documents.

Lifecycle

Code
draft → sent → accepted / rejected │ (a sent quote past validUntil displays as "expired") └─ convert → order confirmation OR invoice

The stored status covers draft / sent / accepted / rejected; displayStatus adds the server-derived converted and expired states (so the status list filter accepts all six: draft, sent, accepted, rejected, expired, converted). A converted quote is read-only — it cannot be edited, re-sent, or converted again. The invoice it ultimately produces is the booked document.

Create a draft

POST /v1/quotes requires customerId, date, and lines; validUntil is quote-only. The document must carry at least one product line (see Document lines). Document totals (subtotal / vat / amount) are computed from the line items, and the documentNumber stays null until the document is sent.

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

PATCH /v1/quotes/{id} updates a draft by replacing the editable fields and line items wholesale — send the full intended set. This is also how you change a quote's validUntil.

Send

POST /v1/quotes/{id}/send allocates the document number (if not already set), renders the PDF, and marks the quote sent. deliveryType is Manual (default) or Email; Sproom / e-invoicing does not apply — there is no legal e-invoice type for a quote. On an email send, the recipient resolves from recipientEmail, else the customer contact, else the customer email; a recipientEmail that isn't already a contact is created as one and linked to the document. To preview before sending, GET /v1/quotes/{id}/pdf?draft=true streams a watermarked draft.

Convert

Converting moves a quote forward in the pre-sales chain and is the only way it reaches the books. A quote converts with target: "orderConfirmation" or target: "invoice". It must be sent first (or accepted) — converting a draft returns 400 SALES_DOCUMENT_CONVERT_REQUIRES_SENT.

TerminalCode
curl -X POST 'https://api.ledgerbee.com/api/v1/quotes/0197a943-2325-7829-b835-b6c71a293066/convert' \ -H 'x-api-key: <your-key>' \ -H 'Content-Type: application/json' \ -d '{ "target": "orderConfirmation" }'
Code
{ "targetType": "orderConfirmation", "targetId": "0197a943-2325-7829-b835-b6c71a29306a" }

By default the source's fields and line items are copied verbatim; supply an optional document payload to adjust the target before finalizing. A document converts only once — the source becomes read-only, and its convertedToDocumentId / convertedToInvoiceId fields point at what it produced.

The converted document carries the quote's discounts and keeps the quote's date for checking them, so a discount that applied when the quote was dated still applies on conversion and on later edits of the converted document. A discount since made inactive or deleted is refused.

When a discount on a quote stops applying before the quote expires, the create and update responses carry a warnings entry with the code DISCOUNT_ENDS_BEFORE_QUOTE_EXPIRY, the discount's endsAt and the quote's validUntil. The save goes through: the quoted price, discount included, holds until the quote expires. Move validUntil to endsAt if the offer should end with the discount. Reads carry no warnings.

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.
Email send with no resolvable recipient400 SALES_DOCUMENT_MISSING_RECIPIENTPass recipientEmail, or set an email on the customer or contact.
Edit or send a converted document400 SALES_DOCUMENT_LOCKED_CONVERTEDAct on the document the conversion produced instead.
Re-converting400 SALES_DOCUMENT_ALREADY_CONVERTED_TO_DOCUMENT or SALES_DOCUMENT_ALREADY_CONVERTED_TO_INVOICERead convertedToDocumentId / convertedToInvoiceId on the source.
Converting a still-draft document400 SALES_DOCUMENT_CONVERT_REQUIRES_SENTSend the quote first via POST /{id}/send; a quote may also be converted once accepted.

Webhooks

See Webhooks for endpoint setup, the signed envelope, and signature verification.

TopicFires when
quote.sentFired when a quote is sent to the customer.
quote.convertedFired when a quote is converted into an order confirmation or an invoice.
Last modified on November 6, 2026
Credit notesOrder confirmations
On this page
  • Lifecycle
  • Create a draft
  • Send
  • Convert
  • Errors
  • Webhooks
JSON