Quotes
List Quotes
List quotes (paginated) using Spatie QueryBuilder.
Create Quote
Creates a quote with lines. Prices are resolved from the customer's pricing tier when `unit_price` is omitted and a `product_id` is given; totals are computed server-side.
Get Quote
Returns a single quote with its lines and customer summary.
Update Quote
Updates a quote's header fields and recomputes totals. Partial payload — only provided fields are applied. The quote must be editable (status draft or revised).
Delete Quote
Soft-deletes a quote and cascades to its lines, versions, and events.
Add Quote Line
Adds a line to an editable quote and recomputes totals.
Remove Quote Line
Removes a line from an editable quote and recomputes totals.
Update Quote Line
Update a single quote line. All fields optional — send only what changed. Editing quantity/unit_price/discount recalculates the quote totals.
Send Quote
Snapshots an immutable version, issues a public token, sets status to `sent`, and stamps `sent_at` / `valid_until`. The quote must be editable.
Accept Quote
Marks an issued quote `accepted` and pins the accepted version (price-lock source for conversion).
Decline Quote
Marks a quote `declined` with an optional reason.
Expire Quote
Marks a quote `expired`.
Revise Quote
Reopens an issued/expired quote as a new editable working copy (status `revised`).
Convert Quote
Converts an accepted quote into a draft sales order with price-locked lines (line unit prices are copied verbatim from the frozen quote lines — never re-resolved against the catalog). The order is stamped with `quote_id` and the accepted `quote_version_id`.
Create Sales Order from Quote
Creates a draft sales order from an accepted quote with price-locked lines (line unit prices are copied verbatim from the frozen quote lines — never re-resolved against the catalog). The quote is the independent source record and is never consumed; the order is stamped with quote_id + the accepted quote_version_id for provenance. Pass line_ids to order a subset (partial/progressive ordering — one quote may yield several orders). Requires Bearer token + the quotes.create-order permission. The quote must be in accepted status.
Bulk Set Line Warehouse
Set the allocation warehouse on many product lines at once — the 'send the whole order from one warehouse' convenience for large quotes.
Set Quote Inventory Allocation
Toggle whether the quote holds inventory, applying the side effect immediately so this is the single control for allocation:
Bulk Archive Quotes
Archives multiple quotes (sets `archived_at`). Archived quotes are hidden from the default list and reappear under `?archived=only`.
Bulk Unarchive Quotes
Restores multiple archived quotes (clears `archived_at`).
Bulk Delete Quotes
Soft-deletes multiple quotes. Releases any allocated inventory for quotes that opted into allocation.
Bulk Send Quotes
Sends multiple quotes to their customers. Only quotes in a sendable (draft/revised) state are sent; the rest are skipped. Inventory is allocated for quotes that opted in. The response reports how many were sent vs. skipped.
Bulk Expire Quotes
Expires multiple quotes. Only issued (sent/viewed) quotes are expired; the rest are skipped. Allocated inventory is released. The response reports how many were expired vs. skipped.
Bulk Update Lines
Apply the same field changes to many lines at once (bulk-edit). Body: line_ids (int[], required) and any of discount_type (none|percentage|fixed_amount), discount_value (numeric|null), tax_rate_id (int|null). Recalculates totals.
Convert Line to Revenue
Strip the product from a line so it becomes a revenue (product-less) line, releasing any inventory it held. Description, quantity and price are preserved.
Reorder Lines
Persist a new line ordering. Body: ordered_ids (int[], required) — line ids in the desired order. Lines not listed keep their relative order after the listed set.
Get Quote Analytics
Aggregate quote analytics for a date range: status counts, issued count, win rate, quote-to-order conversion rate, average quote value, average discount percentage, average days to acceptance, and the number of issued quotes expiring within the next 7 days.
Duplicate Quote
Clone a quote into a fresh editable draft. The duplicate gets a new quote number, `draft` status, and copies of the customer, addresses, terms, discounts, deposit settings, and every line. Lifecycle fields (sent/viewed/accepted timestamps, versions, acceptance records) are NOT copied.
Get Quote PDF
Render the quote as a PDF document using the tenant's quote template and return the file inline.
Select Quote Line
Mark an optional or single-select quote line as selected or deselected. Selection controls which lines the customer is accepting and which lines convert to the sales order.
List Quote Comments
List the quote's negotiation thread — comments left by staff and by the customer, oldest first. System entries (e.g. automatic status notes) are flagged with `is_system`.
Add Quote Comment
Add a staff comment to the quote's negotiation thread. The comment is attributed to the authenticated user.
Record Quote Acceptance
Record the customer's acceptance of an issued quote (sent or viewed status) together with the signer's details, and transition the quote to `accepted`. The signer's IP address and user agent are captured automatically from the request.
Record Quote Deposit Payment
Record a deposit payment against the quote — used for manual/offline payments taken by staff. Payment gateway webhooks record their own payments through the same mechanism.
Sync Quote to Accounting
Push the quote to the connected accounting integration (e.g. as an estimate) and return the accounting reference. When no accounting integration is connected or the sync is skipped, `synced` is false and `reference` is null.
Request Quote Discount Approval
Request managerial approval for the quote's current discount level. The quote's totals are recalculated, the effective discount percentage is captured, and a pending approval is created attributed to the authenticated user.
Approve Quote Discount
Approve the quote's pending discount approval. The approval is marked approved and attributed to the authenticated user, and the refreshed quote is returned.
Reject Quote Discount
Reject the quote's pending discount approval, optionally recording a reason. The approval is marked rejected and the refreshed quote is returned.