Quotes
A priced proposal sent to a customer before a sale is committed — with line items, a tax rate, an expiry date, and a one-click conversion to a sales order.
A quote is a formal price proposal you send to a customer before committing to a sale. It carries a list of line items (Products, quantities, and prices), an optional tax rate, an optional expiry date, and moves through a clearly defined lifecycle from Draft through to Accepted or Converted. Once a customer accepts, you convert the quote to a sales order in a single click — the line items carry across and the quote is marked Converted automatically.
Quotes are non-committing proposals. No inventory is reserved and no charges are raised until the quote is converted into a sales order.
Creating a quote #
New quotes are created from Sales → Quotes → New Quote. The quote number is
auto-generated (Q-0001, Q-0002, …) but can be overridden if you have your own
numbering scheme.
Key fields on the header form:
- Customer — required. Pick from the shared customer directory or create a new customer inline from the same form.
- Contact — optional. Scoped to the selected customer's contacts. You can create a contact inline here too.
- Quote Number — auto-generated if left blank; override to match your external system.
- Status — defaults to Draft. See Quote statuses below.
- Valid Until — the date after which the quote is no longer valid. Displayed on the PDF and visible in the list so you can chase quotes before they lapse. It pre-fills from a per-location default (set Default Quote Validity under Location → Sales); leave that location setting blank for quotes that never expire, or clear the date on an individual quote.
- Tax Rate — choose from your configured tax rates. The total and tax amount recalculate automatically whenever the tax rate changes.
- Notes — free-text internal notes that appear on the quote PDF.
- Custom fields — any custom attributes defined for quotes appear at the bottom of the form. See Custom Fields.
The Total Amount on the form is read-only — it is the sum of line items plus tax and updates automatically as you save changes.
Quote statuses #
Every quote has a status badge that tracks where it is in the sales conversation:
- Draft — being prepared; not yet sent to the customer.
- Sent — delivered to the customer, awaiting a response.
- Accepted — the customer has agreed to the terms.
- Declined — the customer turned it down.
- Expired — the expiry date has passed without a decision.
- Converted — accepted and turned into a sales order (see Converting a quote).
You can set the status directly on the edit form, or use the dedicated action buttons on the quote's detail page: Mark as Sent, Mark as Accepted, Mark as Declined, and Mark as Expired. These buttons appear automatically based on the current status so only valid transitions are offered. The navigation badge in the sidebar shows a green count of all Accepted quotes so nothing falls through the cracks.
Quote line items #
Line items are added on the Line Items tab of the quote's detail page. Each line item has:
- Product — optional link to an Product. When a Product is selected, the description can be left blank and the Product name is used instead.
- Description — free-text label for the line, useful for services or custom products that don't exist in the catalog.
- Quantity — how many units. Supports decimal values (e.g.
2.5). - Unit Price — price per unit in dollars. Stored internally in cents — see the API section below.
- Notes — any line-level notes (e.g. color, configuration).
The parent quote's subtotal, tax amount, and total amount refresh automatically each time an item is saved or deleted.
A line item can have either a Product or a description (or both), but at least one must identify what is being quoted. Only items with a linked Product are carried across when converting to a sales order.
Converting a quote #
The Convert to SO action is available on any quote in Draft, Sent, or Accepted status. Click it from the quote list or the quote's detail page. On confirmation:
- A new sales order is created in Draft status, with the same customer, contact, and notes.
- Every line item that has a linked Product is copied across as a sales order item (Product, quantity, and unit price are preserved).
- The quote's sales_order_id is set and its status becomes Converted.
The created sales order number is displayed in a success notification and in the quote list under the Sales Order column.
The quote list #
The quote list (Sales → Quotes) shows each quote's number, customer, contact, status badge, expiry date, total, and linked sales order number. The list defaults to newest first. You can filter by trashed records and sort any column. Custom field columns defined for quotes appear alongside the built-in columns.
Downloading a quote PDF #
From the quote detail page, use the Download PDF action to generate a formatted PDF of the quote — including customer details, all line items, the tax breakdown, expiry date, and notes — suitable for emailing to a customer.
Doing it from the API #
See API: Getting Started for authentication and
general conventions. All quote endpoints live under /api/v1/quotes and
/api/v1/quote-items.
# List all quotes for a customer, filtered to sent status
curl "https://your-domain.com/api/v1/quotes?customer_id=<id>&status=sent" \
-H "Authorization: Bearer $TOKEN"
# Create a quote
curl -X POST "https://your-domain.com/api/v1/quotes" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "<customer-id>",
"customer_contact_id": "<contact-id>",
"status": "draft",
"expires_at": "2026-07-31",
"tax_rate_id": "<tax-rate-id>",
"notes": "Valid for 30 days."
}'
# Add a line item (unit_price is in cents — 15000 = $150.00)
curl -X POST "https://your-domain.com/api/v1/quote-items" \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{
"quote_id": "<quote-id>",
"product_id": "<product-id>",
"quantity": 2,
"unit_price": 15000,
"notes": "Black finish"
}'
Money fields are integers in cents —
unit_priceandtotal_amountare stored and returned as integers (15000= $150.00). The UI shows dollars, the API uses cents.
Filter the quote list with ?customer_id=<id> and/or ?status=<value>. Paginated at
50 per page. Filter quote items with ?quote_id=<id>. Deleting a quote or item is a
soft delete; the parent quote totals recalculate automatically on item changes.