Skip to content
Development
Skill

/quotes

The ConnectWise CPQ quote lifecycle over the real tool surface: searching quotes, the GUID-vs-quoteNumber dual addressing, versions, creating quotes by copying a template (the API's only create path), patching quote fields, the per-quote customer records and payment/financing

From plugin
msp-claude-plugins
46200 skills146 agents200 commands4 MCP
Install
$ npx -y skills add wyre-technology/msp-claude-plugins --skill quotes --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/quotes

Context preview

The summary Claude sees to decide when to auto-load this skill.

The ConnectWise CPQ quote lifecycle over the real tool surface: searching quotes, the GUID-vs-quoteNumber dual addressing, versions, creating quotes by copying a template (the API's only create path), patching quote fields, the per-quote customer records and payment/financing

SKILL.md

quotes.SKILL.md
name: "ConnectWise CPQ Quotes"
description: >
  The ConnectWise CPQ quote lifecycle over the real tool surface: searching
  quotes, the GUID-vs-quoteNumber dual addressing, versions, creating quotes by
  copying a template (the API's only create path), patching quote fields, the
  per-quote customer records and payment/financing terms, tabs as the section
  structure, and the deletes that cascade.
when_to_use: >-
  When finding, building, updating, versioning, or deleting a ConnectWise CPQ quote,
  or working with the customers and payment terms attached to one. Use when: cpq quote,
  connectwise cpq quote, create quote from template, cpq quote version, cpq quote status,
  cpq quote customer, cpq quote terms, cpq quote tabs, quosal quote, or connectwise sell quote.

ConnectWise CPQ Quotes

Overview

A CPQ quote is the proposal an MSP sends a client: a header (account, status, dates, totals), one or more **tabs** that section the proposal, **line items** on those tabs, **customer records** synced from the attached CRM/PSA, and optional **payment/financing terms**. Quotes are versioned — a revision creates a new version under the same quote number rather than mutating the old one.

Everything an MSP does after the quote is built — publishing to Order Porter, e-signature, porting a won quote into the PSA as a sales order — happens in the CPQ web app. The API covers building and reading quotes, not delivering them.

Anti-triggers

CPQ owns one stage of the quote funnel: **composing and pricing the quote document**. It does not source the SKUs that go into it, it cannot deliver it, and it is not the only tool in the stack that holds something called a quote.

  • **The priced SKU master list rather than this deal's document** — catalog items,

costs, categories and manufacturers live in ConnectWise PSA; use `connectwise-psa-product-catalog`.

  • **"Send the customer the quote", e-signature, or signed-document status** — CPQ's API

has no publish, send or e-sign verb. `isSent` and the `orderPorter*` fields are state you can read (and patch), not actions you can trigger. Delivery and signature tracking are `pandadoc-documents`.

  • **A quote that was built in a different quoting product** — Kaseya Quote Manager and

SalesBuildr each keep their own quotes, numbering and APIs; use `kaseya-quote-manager-quotes` or `salesbuildr-quotes`. Route on the product the quote lives in, not on the word "quote".

  • **Adding, repricing or removing a line** — the quote header and its line items are

separate tool sets; use `connectwise-cpq-quote-items`.

Key Concepts

Two ways to address a quote

| Addressing | Used by | Notes | |---|---|---| | GUID `id` (string) | `cpq_get_quote`, `cpq_update_quote`, `cpq_delete_quote`, `cpq_create_quote_from_template` | Unique to one *version* of one quote | | `quoteNumber` (int) + `quoteVersion` (int) | `cpq_get_quote_versions`, `cpq_delete_quote_version` | The human-facing number; identifies the quote across its versions |

Searches return both, so pull the `id` out of a search result before doing anything that needs a GUID. A quote number alone is not enough to patch or delete a quote.

Versions

`cpq_get_quote_versions` takes a `quoteNumber` and behaves three ways:

  • omit `version` → list every version
  • `version: "latest"` → the current version
  • `version: 3` → that specific version

Searches return **latest versions only** unless you pass `showAllVersions: true`. If a search seems to be missing a quote a colleague is looking at, they are probably on a superseded version.

Quote status and flags

Status lives across several fields rather than one enum. The ones that decide what a quote means:

| Field | Meaning | |---|---| | `quoteStatus` | Tenant-configurable status text (values vary per install — read them from live data, do not assume) | | `isSent` | Delivered to the customer | | `isAccepted` | Customer accepted | | `isLost` | Marked lost | | `isArchive` | Archived; excluded from most working views | | `requiresApproval` / `approvalStatus` / `approvedByUser` | Internal approval workflow | | `expirationDate` / `expectedCloseDate` | Proposal validity and forecast date | | `orderPorter*` | Order Porter publishing state (passcode, template, signed date, upload state) |

See [references/fields.md](references/fields.md) for the fuller QuoteView field reference.

Sub-resources

| Sub-resource | Tools | Notes | |---|---|---| | Tabs | `cpq_search_quote_tabs` | Read-only over the API. Sections of the proposal; every line item belongs to one. | | Line items | see the [quote-items skill](../quote-items/SKILL.md) | Full CRUD | | Customers | `cpq_list_quote_customers`, `cpq_update_quote_customer`, `cpq_delete_quote_customer` | Exist **only** in the context of a quote — there is no global customer directory to search | | Terms | `cpq_list_quote_terms`, `cpq_create_quote_term`, `cpq_update_quote_term`, `cpq_delete_quote_term` | Payment/financing options: `periods`, `interestRate`, `downPayment`, `periodPaymentAmount`, `isSelected`, leasing fields |

Common Workflows

Find a quote

1. `cpq_search_quotes` with `conditions` and a tight `includeFields`, e.g. `conditions: accountName contains "Acme" AND isArchive = False`, `includeFields: id,name,quoteNumber,quoteVersion,quoteStatus,quoteTotal,createDate` 2. Page with `page`/`pageSize` until a page returns fewer rows than `pageSize`. 3. `cpq_get_quote` with the GUID for the full record.

Called with no `conditions` the search asks for a created-since date, falling back to the last 90 days and noting that in the result. Give it a condition when you know one — a 90-day window silently hides older quotes.

Create a quote

There is no create-from-scratch endpoint. Every new quote is a **copy** of a template or of an existing quote, then patched into shape.

1. `cpq_list_templates` to see what is available (templates are themselves quotes). 2. `cpq_create_quote_from_template` with `te

Read more
Ships withmsp-claude-plugins

One command to supercharge Claude Code for MSP workflows. Then restart Claude Code. That's it. Documentation: mcp.wyre.ai

Get the whole plugin

Other skills on msp-claude-plugins.