Quotes
Quotes in the BlueSuite REST API
Create drafts, edit pricing, and track quote status. Creating a quote or setting its status does not deliver it to the customer. Use Notifications with type: "quote_to_customer" and the quote ID to send it using the workspace's email/SMS settings.
reminders_enabled controls reminders. waive_credit_card_fee overrides the workspace's online processing fee for this record. Record deposits through Payments. See line items for the shared pricing structure.
List filters status and exclude_statuses accept comma-separated values; tag_ids matches any selected tag.
Example: create a draft
curl 'https://my.bluesuite.app/api/v1/quotes' \
-H "Authorization: Bearer $BLUESUITE_API_KEY" \
-H 'Content-Type: application/json' \
-d '{"contact_id":42,"name":"Window cleaning","status":"draft","line_items":[{"name":"Window cleaning","quantity":1,"unitPrice":150}],"total":150}'GET /api/v1/quotes
GET /api/v1/quotesRequired scopes: quotes:read.
Query parameters
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
page | integer | No | Page number, starting at 1. Default: 1. |
per_page | integer | No | Records per page, from 1 to 100. Default: 25. minimum: 1. maximum: 100. |
search | string | No | Search text. maxLength: 100. |
sort_by | string | No | Sort column. See the supported columns below when listed. |
sort_direction | "asc", "desc" | No | Sort direction. Default: "desc". |
contact_id | string | No | Filter by contact ID. |
exclude_statuses | string | No | Comma-separated statuses to exclude. |
status | string | No | Filter by status. |
tag_ids | string | No | Comma-separated tag IDs. Tags must match this resource type. |
Response
200 with { "success": true, "data": [...], "pagination": { "page": 1, "per_page": 25, "total_pages": 1 } }.
See response conventions and errors.
POST /api/v1/quotes
POST /api/v1/quotesRequired scopes: quotes:write.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
name | string or null | No | |
contact_id | integer or null | No | |
property_id | integer or null | No | |
request_id | integer or null | No | |
salesperson_id | string or null | No | |
template_id | integer or null | No | |
date | string | No | |
expire_on | string or string or null | No | |
message | string or null | No | |
payment_instructions | string or null | No | |
line_items | array of object or object | No | maxItems: 500. |
line_items[]._type | "lineItem" | No | For lineItem rows. Defaults to lineItem when omitted. |
line_items[].name | string | For this variant | For lineItem rows. Item name |
line_items[].description | string or null | No | For lineItem rows. Additional description |
line_items[].quantity | number | No | For lineItem rows. Quantity Default: 1. |
line_items[].unitPrice | number | For this variant | For lineItem rows. Unit price |
line_items[].unitCost | number | No | For lineItem rows. What this costs the business, per unit. Only used when cost tracking is enabled. minimum: 0. |
line_items[].taxable | boolean | No | For lineItem rows. Whether the item is taxable |
line_items[].optional | boolean | No | For lineItem rows. Whether the item is optional |
line_items[]._type | "image" | For this variant | For image rows. |
line_items[].image_path | string | For this variant | For image rows. Storage path returned by /uploads minLength: 1. |
line_items[].image_id | integer or null | No | For image rows. Upload link ID returned by /uploads |
line_items[].description | string or null | No | For image rows. Caption shown beneath the image |
discount | number | No | Default: 0. |
discount_unit | "%", "$" | No | Default: "%". |
deposit | number | No | Default: 0. |
deposit_unit | "%", "$" | No | Default: "%". |
tax_rate | number | No | Default: 0. |
tax_rate_id | integer or null | No | |
total | number | No | Default: 0. |
reminders_enabled | boolean | No | Default: true. |
waive_credit_card_fee | boolean | No | Skip the workspace's online processing fee for this record. Carries over to jobs and invoices created from it. Default: false. |
status | "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | No | Default: "draft". |
custom_fields | JSON value or null | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
201 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
GET /api/v1/quotes/:id
GET /api/v1/quotes/:idRequired scopes: quotes:read.
Path parameters: id. Use positive integer record IDs from this workspace.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
PUT /api/v1/quotes/:id
PUT /api/v1/quotes/:idRequired scopes: quotes:write.
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
name | string or null | No | |
contact_id | integer or null | No | |
property_id | integer or null | No | |
request_id | integer or null | No | |
salesperson_id | string or null | No | |
template_id | integer or null | No | |
date | string | No | |
expire_on | string or string or null | No | |
message | string or null | No | |
payment_instructions | string or null | No | |
line_items | array of object or object | No | maxItems: 500. |
line_items[]._type | "lineItem" | No | For lineItem rows. Defaults to lineItem when omitted. |
line_items[].name | string | For this variant | For lineItem rows. Item name |
line_items[].description | string or null | No | For lineItem rows. Additional description |
line_items[].quantity | number | No | For lineItem rows. Quantity Default: 1. |
line_items[].unitPrice | number | For this variant | For lineItem rows. Unit price |
line_items[].unitCost | number | No | For lineItem rows. What this costs the business, per unit. Only used when cost tracking is enabled. minimum: 0. |
line_items[].taxable | boolean | No | For lineItem rows. Whether the item is taxable |
line_items[].optional | boolean | No | For lineItem rows. Whether the item is optional |
line_items[]._type | "image" | For this variant | For image rows. |
line_items[].image_path | string | For this variant | For image rows. Storage path returned by /uploads minLength: 1. |
line_items[].image_id | integer or null | No | For image rows. Upload link ID returned by /uploads |
line_items[].description | string or null | No | For image rows. Caption shown beneath the image |
discount | number | No | Default: 0. |
discount_unit | "%", "$" | No | Default: "%". |
deposit | number | No | Default: 0. |
deposit_unit | "%", "$" | No | Default: "%". |
tax_rate | number | No | Default: 0. |
tax_rate_id | integer or null | No | |
total | number | No | Default: 0. |
reminders_enabled | boolean | No | Default: true. |
waive_credit_card_fee | boolean | No | Skip the workspace's online processing fee for this record. Carries over to jobs and invoices created from it. Default: false. |
status | "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | No | Default: "draft". |
custom_fields | JSON value or null | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
DELETE /api/v1/quotes/:id
DELETE /api/v1/quotes/:idRequired scopes: quotes:write.
Path parameters: id. Use positive integer record IDs from this workspace.
No request body.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.
See response conventions and errors.
PUT /api/v1/quotes/:id/status
PUT /api/v1/quotes/:id/statusRequired scopes: quotes:write.
Path parameters: id. Use positive integer record IDs from this workspace.
JSON body
| Field | Type / accepted values | Required | Details |
|---|---|---|---|
status | "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | Yes | |
comment | string | No |
Unknown body fields are rejected. Conditional requirements are explained above.
Response
200 with { "success": true, "data": ... }. The data contains the result of the operation.