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
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.
Code
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.
Code
Code
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.
Errors
| Condition | Response | Fix |
|---|---|---|
| Missing or wrong scope | 403 | Grant the matching read or write scope. |
| Non-UUID id / unknown id | 400 / 404 | Pass a UUID id that exists for your tenant. |
| Email send with no resolvable recipient | 400 SALES_DOCUMENT_MISSING_RECIPIENT | Pass recipientEmail, or set an email on the customer or contact. |
| Edit or send a converted document | 400 SALES_DOCUMENT_LOCKED_CONVERTED | Act on the document the conversion produced instead. |
| Re-converting | 400 SALES_DOCUMENT_ALREADY_CONVERTED_TO_DOCUMENT or SALES_DOCUMENT_ALREADY_CONVERTED_TO_INVOICE | Read convertedToDocumentId / convertedToInvoiceId on the source. |
| Converting a still-draft document | 400 SALES_DOCUMENT_CONVERT_REQUIRES_SENT | Send 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.
| Topic | Fires when |
|---|---|
quote.sent | Fired when a quote is sent to the customer. |
quote.converted | Fired when a quote is converted into an order confirmation or an invoice. |