deal-management
Run the full deal lifecycle from CLI — discover pipelines/stages, qualify MQLs into deals with associations, advance/reassign in bulk, hunt stalled deals, and close.
crm-lookup
Find a specific CRM record by ID, email, domain, or name fragment, and traverse associations for the full account picture.
Full skill instructions
hubspot <command> --help is authoritative. Read bulk-operations/SKILL.md first — it owns JSONL piping, pagination, batch-get-via-stdin, and the safety flow for any write that comes after a lookup. This skill is read-only.
Schemas drift. Run hubspot properties list --type <type> for the live set. First-pass --properties for a brief:
| Object | --properties |
|---|---|
| contacts | email,firstname,lastname,company,phone,lifecyclestage,hubspot_owner_id |
| companies | name,domain,industry,annualrevenue,numberofemployees,hubspot_owner_id |
| deals | dealname,amount,dealstage,closedate,hubspot_owner_id,hs_is_closed_won |
| tickets | subject,hs_pipeline_stage,hs_ticket_priority,hubspot_owner_id |
Contact ad/campaign attribution lives on hs_analytics_* (e.g. hs_analytics_source, hs_analytics_source_data_1/_2, hs_analytics_first_touch_converting_campaign, hs_analytics_last_touch_converting_campaign). Full list: hubspot properties list --type contacts | grep hs_analytics_.
Up to ~100 IDs in a single batch call:
hubspot objects get --type contacts 12345 67890 23456 --properties email,firstname,lastname,company,phone,lifecyclestage
email/domain are exact-match — normalize to lowercase. Multiple --filter flags are OR'd.
hubspot objects search --type contacts --filter "[email protected]" \
--properties email,firstname,lastname,company,lifecyclestage,hubspot_owner_id
hubspot objects search --type companies --filter "domain=acme.com" \
--properties name,domain,industry,annualrevenue,hubspot_owner_id
# OR — multiple emails in one call
hubspot objects search --type contacts \
--filter "[email protected]" --filter "[email protected]" --properties email,firstname
~ is CONTAINS_TOKEN — matches whole space-separated words. dealname~acme finds "Acme Renewal" but not "AcmeCorp". For substring, pipe to jq. There's no full-text search across all fields — pick the property.
hubspot objects search --type deals --filter "dealname~acme" --properties dealname,amount,dealstage \
| jq -c 'select(.properties.dealname | ascii_downcase | contains("acme corp"))'
Pattern: associations list → jq -c '{id}' → objects get batch. Never xargs -I{} hubspot objects get … — that spawns one process per record. Use plural in --from (contacts:12345), exactly as --help shows.
# All contacts at a company
hubspot associations list --from companies:67890 --to contacts \
| jq -c '{id}' \
| hubspot objects get --type contacts --properties email,firstname,lastname,jobtitle
# Open deals for a contact (filter client-side; "open" varies by pipeline)
hubspot associations list --from contacts:12345 --to deals | jq -c '{id}' \
| hubspot objects get --type deals --properties dealname,amount,dealstage,hs_is_closed \
| jq -c 'select(.properties.hs_is_closed != "true")'
contact_id=12345
hubspot objects get --type contacts $contact_id --properties email,firstname,lastname,company,lifecyclestage
# Associated company (usually one)
hubspot associations list --from contacts:$contact_id --to companies | jq -c '{id}' | head -1 \
| hubspot objects get --type companies --properties name,domain,industry,annualrevenue
# Associated deals
hubspot associations list --from contacts:$contact_id --to deals | jq -c '{id}' \
| hubspot objects get --type deals --properties dealname,amount,dealstage,closedate
bulk-operations/SKILL.md.~ is token-based; substring filtering happens in jq after the search.--dry-run → digest → --confirm flow in bulk-operations/SKILL.md.Run the full deal lifecycle from CLI — discover pipelines/stages, qualify MQLs into deals with associations, advance/reassign in bulk, hunt stalled deals, and close.
Daily briefings, pipeline snapshots, and win/loss analysis from the terminal — closing-this-week, open pipeline by stage/owner, and closed-won vs closed-lost over a period.
Discover, create, update, and delete custom CRM object schemas. Use when defining a new object type, inspecting existing schemas, or removing one. Record CRUD on custom objects is identical to standard objects — see `bulk-operations`.
Match external CSV/JSONL records to CRM contacts (by email) or companies (by domain) and write enriched data back in one pass using `hubspot objects upsert`.
Retrieve activity history (calls, emails, notes, meetings, tasks) for a CRM record and assemble pre-call briefs.
Log sales activities — calls, notes, meetings, tasks — against contacts and deals, with the mandatory create-then-associate step that makes them visible in the CRM.
Assign and reassign CRM record ownership, audit who-owns-what across object types, and handle rep transitions. Built on `bulk-operations`.
Identify inactive/at-risk customers via CRM filters and create follow-up tasks at scale. Builds on `bulk-operations`; defers activity-creation specifics to `sales-execution`.
Build a targeted contact segment by filtering on lifecycle, engagement, jobtitle, geography, or firmographics — then export it as JSONL for a campaign or downstream tool.
Build the product catalog, assemble quotes (line items + associations to deals), and track invoices and subscriptions through to revenue.
Generate, edit, and beat-sync AI video with leading models in one workspace.
The world's fastest calendar for remote work
Transform Your Design with AI Designer by ImgCreator.ai
Revolutionizing Video Production with AI-Powered Creativity
Extend an image past the frame and let AI fill the new aspect ratio.
Discover your celebrity doppelgänger with StarByFace!
ChainClarity explains 700+ crypto whitepapers in plain English, with layered summaries, comparisons, research tools, alerts, and a $4.99 Pro plan.
Opus.ai: Revolutionize Your Web Experience