Quotes
BlueSuite MCP tools for quotes
See connection and authentication and workflow rules before calling these tools.
Related REST API and behavior.
List quotes with optional pagination and search
| Field | Type / accepted values | Required | Details |
|---|
page | integer | No | Page number (default: 1) |
per_page | integer | No | Results per page (default: 25) minimum: 1. maximum: 100. |
search | string | No | Search quotes |
sort_by | "id", "number", "name", "status", "total", "date", "expire_on", "created_at", "modified_at" | No | Field to sort by. Unknown values fall back to the default sort. |
sort_direction | "asc", "desc" | No | Sort direction |
contact_id | integer | No | Filter by contact ID |
exclude_statuses | array of "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | No | Exclude quotes with any of these statuses. |
status | array of "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | No | Filter by one or more statuses. |
tag_ids | array of JSON value | No | Filter to records carrying ANY of these tag IDs (not all). Use list_tags with the matching taggable_type to resolve tag names to IDs first. |
| Field | Type / accepted values | Required | Details |
|---|
data | array of object | Yes | The matching records for this page. |
pagination | object | No | How many more pages of results exist. Absent when the API returned an unpaged result. |
pagination.page | integer | When parent supplied | Current page number, 1-based. |
pagination.per_page | integer | When parent supplied | Number of results per page. |
pagination.total_pages | integer | When parent supplied | Total number of pages available. |
Create a new quote
| Field | Type / accepted values | Required | Details |
|---|
name | string | No | Quote name/title |
contact_id | integer | No | Associated contact ID |
property_id | JSON value | No | Associated property ID |
request_id | JSON value | No | Associated request ID |
salesperson_id | string | No | UUID of salesperson. Use list_users to resolve names. Format: uuid. |
template_id | JSON value | No | Quote template ID |
date | string | No | Quote date (YYYY-MM-DD) |
expire_on | string or string | No | Expiration date (YYYY-MM-DD) |
message | string | No | Message to client |
line_items | array of object or object | No | Array of line item objects. Two shapes are accepted: a regular priced row ({ name, quantity, unit_price }) or an inline image row ({ _type: "image", image_path, image_id, description }). For image rows: first call upload_file with module_type="workspace", category="line_item", is_public=true to upload the image, then pass the returned path as image_path and id as image_id. |
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 | No | For lineItem rows. Plain text description for this line item. Omit when not needed. Default: "". |
line_items[].quantity | number | No | For lineItem rows. Quantity Default: 1. |
line_items[].unit_price | number | For this variant | For lineItem rows. Price per unit |
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 a prior upload_file call. Upload with module_type="workspace", category="line_item", is_public=true to get a usable path. minLength: 1. |
line_items[].image_id | integer | No | For image rows. Upload link ID (id) returned by the same upload_file call. |
line_items[].description | string | No | For image rows. Caption shown beneath the image in the line items list. |
discount | number | No | Discount amount (default: 0) |
discount_unit | "percent", "amount" | No | How the discount is expressed. One of: 'percent' (a percentage of the subtotal) or 'amount' (a fixed currency amount). Default: 'percent'. |
deposit | number | No | Deposit amount (default: 0) |
deposit_unit | JSON value | No | How the deposit is expressed. One of: 'percent' or 'amount'. Default: 'percent'. |
tax_rate | number | No | Tax rate percentage (default: 0) |
tax_rate_id | JSON value | No | Tax rate preset ID |
total | number | No | Quote total |
reminders_enabled | boolean | No | Whether BlueSuite automatically emails the client reminders about this quote. Default: true. |
waive_credit_card_fee | JSON value | No | Skip the workspace's online processing fee for this record. Only meaningful when the workspace passes processing fees on to clients. Carries over to jobs and invoices created from this quote. Default: false. |
status | "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | No | Quote status (default: draft) |
custom_fields | object | No | Custom field values |
| Field | Type / accepted values | Required | Details |
|---|
data | object or null | Yes | The affected record, or the result of the operation. Null when nothing matched. |
Get a single quote by ID with expanded details
| Field | Type / accepted values | Required | Details |
|---|
id | integer | Yes | Quote ID |
| Field | Type / accepted values | Required | Details |
|---|
data | object or null | Yes | The affected record, or the result of the operation. Null when nothing matched. |
Update an existing quote
| Field | Type / accepted values | Required | Details |
|---|
id | integer | Yes | Quote ID |
name | string | No | Quote name/title |
contact_id | JSON value | No | Associated contact ID |
property_id | JSON value | No | Associated property ID |
request_id | JSON value | No | Associated request ID |
salesperson_id | string | No | UUID of salesperson. Use list_users to resolve names. Format: uuid. |
template_id | JSON value | No | Quote template ID |
date | string | No | Quote date (YYYY-MM-DD) |
expire_on | string or string | No | Expiration date (YYYY-MM-DD) |
message | string | No | Message to client |
line_items | array of object or object | No | Array of line item objects. Two shapes are accepted: a regular priced row ({ name, quantity, unit_price }) or an inline image row ({ _type: "image", image_path, image_id, description }). For image rows: first call upload_file with module_type="workspace", category="line_item", is_public=true to upload the image, then pass the returned path as image_path and id as image_id. |
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 | No | For lineItem rows. Plain text description for this line item. Omit when not needed. Default: "". |
line_items[].quantity | number | No | For lineItem rows. Quantity Default: 1. |
line_items[].unit_price | number | For this variant | For lineItem rows. Price per unit |
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 a prior upload_file call. Upload with module_type="workspace", category="line_item", is_public=true to get a usable path. minLength: 1. |
line_items[].image_id | integer | No | For image rows. Upload link ID (id) returned by the same upload_file call. |
line_items[].description | string | No | For image rows. Caption shown beneath the image in the line items list. |
discount | number | No | Discount amount |
discount_unit | "percent", "amount" | No | How the discount is expressed. One of: 'percent' (a percentage of the subtotal) or 'amount' (a fixed currency amount). |
deposit | number | No | Deposit amount |
deposit_unit | JSON value | No | How the deposit is expressed. One of: 'percent' or 'amount'. |
tax_rate | number | No | Tax rate percentage |
tax_rate_id | JSON value | No | Tax rate preset ID |
total | number | No | Quote total |
reminders_enabled | boolean | No | Whether BlueSuite automatically emails the client reminders about this quote. Default: true. |
waive_credit_card_fee | JSON value | No | Skip the workspace's online processing fee for this record. Only meaningful when the workspace passes processing fees on to clients. Carries over to jobs and invoices created from this quote. Default: false. |
status | "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | No | Quote status |
custom_fields | object | No | Custom field values |
| Field | Type / accepted values | Required | Details |
|---|
data | object or null | Yes | The affected record, or the result of the operation. Null when nothing matched. |
Delete a quote by ID
| Field | Type / accepted values | Required | Details |
|---|
id | integer | Yes | Quote ID |
| Field | Type / accepted values | Required | Details |
|---|
data | object or null | Yes | The affected record, or the result of the operation. Null when nothing matched. |
Record a change to a quote's status. This does NOT email anyone. To actually deliver a quote to the client, use send_notification with type="quote_to_customer", which delivers it and moves the quote to awaiting response. Use this tool for bookkeeping: marking a quote accepted, declined or archived after hearing back some other way.
| Field | Type / accepted values | Required | Details |
|---|
id | integer | Yes | Quote ID |
status | "draft", "awaiting_response", "accepted", "declined", "expired", "archived", "awaiting_deposit" | Yes | New status |
comment | string | No | Optional comment for the status change |
| Field | Type / accepted values | Required | Details |
|---|
data | object or null | Yes | The affected record, or the result of the operation. Null when nothing matched. |
The downloadable tool schemas include the full input and output contracts. Tables describe schema-level required fields; cross-field rules still apply.