Loading...
Loading...
Build the product catalog, assemble quotes (line items + associations to deals), and track invoices and subscriptions through to revenue.
npx skill4agent add hubspot/agent-cli-skills quote-to-cash| File | When to use |
|---|---|
| Six-field cheat sheet, association directions, portal caveats for invoices/subscriptions/orders/carts. |
bulk-operations/SKILL.mdbulk-operations/resources/json-patterns.mdhubspot <command> --helpproductsline_itemsquotesinvoicessubscriptionshubspot properties list --type <type>hubspot properties get --type <type> --name <property>options[].valueinvoicessubscriptionsorderscartsobjectTypeIdhubspot objects typesobjects searchlistinvoices-readsubscriptions-readDRAFThubspot objects create --type products \
--property name="Enterprise License" \
--property price=12000 \
--property hs_sku=ENT-001recurringbillingfrequencyhubspot properties get --type products --name recurringbillingfrequency --format json | jq -r '.options[].value'{"properties":{...}}hubspot objects create --type products --dry-runobjects createDEAL_ID=12345
# 1. Create the line items. items.jsonl holds {"name":..,"qty":..,"price":..,"product_id":..} per line.
jq -c '{properties:{
name:.name, quantity:(.qty|tostring), price:(.price|tostring),
hs_product_id:.product_id, hs_line_item_currency_code:"USD"
}}' items.jsonl \
| hubspot objects create --type line_items > /tmp/lineitems.jsonl
# 2. Create the quote.
QUOTE_ID=$(hubspot objects create --type quotes \
--property hs_title="Acme Corp - 2026" \
--property hs_expiration_date=2026-06-30 \
--property hs_currency=USD \
--format json | jq -r '.data.id // .id')
# 3. Associate every new line item to the quote in one pipe.
jq -r '.id' /tmp/lineitems.jsonl \
| jq -cR --arg q "$QUOTE_ID" '{from:("quotes:" + $q), to:("line_items:" + .)}' \
| hubspot associations create
# 4. Link the quote to the deal.
hubspot associations create --from "deals:$DEAL_ID" --to "quotes:$QUOTE_ID"discount10hs_total_discounthubspot properties get --type line_items --name hs_total_discountmodificationMetadata.readOnlyValue:trueDRAFThubspot objects update --type quotes <quote_id> --property hs_status=APPROVAL_NOT_NEEDEDhs_statushubspot properties get --type quotes --name hs_status --format json | jq -r '.options[].value'hs_invoice_status# All outstanding invoices
hubspot objects search --type invoices \
--filter "hs_invoice_status=OUTSTANDING" \
--properties hs_number,hs_amount_billed,hs_balance,hs_due_date
# Past-due (overdue) invoices, dynamic date
hubspot objects search --type invoices \
--filter "hs_due_date<$(date +%Y-%m-%d) AND hs_invoice_status!=PAID" \
--properties hs_number,hs_due_date,hs_balance
# Invoices billed in the last 30 days
hubspot objects search --type invoices \
--filter "hs_invoice_date>=$(date -v-30d +%Y-%m-%d 2>/dev/null || date -d '30 days ago' +%Y-%m-%d)" \
--properties hs_number,hs_amount_billed,hs_invoice_datehubspot properties get --type invoices --name hs_invoice_status --format json | jq -r '.options[].value'hs_subscription_statusACTIVECANCELLEDPAST_DUEhubspot properties get --type subscriptions --name hs_subscription_status --format json \
| jq -r '.options[].value'
# Then filter (case matters)
hubspot objects search --type subscriptions \
--filter "hs_subscription_status=<value-from-above>" \
--properties hs_mrr,hs_arr,hs_subscription_status
# Sum MRR across active subs
hubspot objects search --type subscriptions \
--filter "hs_subscription_status=<active-value>" --format json \
| jq '[.data[].properties.hs_mrr | select(. != null) | tonumber] | add'invoicessubscriptionsorderscartsobjects deleteexport HUBSPOT_ACCESS_TOKEN=<token>bulk-operations/SKILL.mdhs_total_discountdiscount