sales-execution
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.
By hubspot · 1,307 installs
npx skills add hubspot/agent-cli-skills --skill sales-execution
Source repository · Upstream listing
Resources
File When to use
resources/activity properties reference.md Property names and enum values for calls/notes/meetings/tasks. Keep open while writing objects create — for live enum values run hubspot properties options list type calls <property , and for call outcomes hubspot activities calls dispositions list ; the reference is the shortcut.
Read bulk operations/SKILL.md first — this skill assumes its batching, pipe, and dry run patterns.
The two non obvious rules
1. Activities are invisible until associated. hubspot objects create type calls ... alone produces a record nobody can see in the CRM UI. Always follow with hubspot associations create from calls:<id to contacts:<id (and the deal, if relevant) before stopping.
2. Timestamps differ between write and read.
Path Field Format
objects create property hs timestamp=... hs timestamp Unix ms (13 digits)
objects get type calls <id returns properties.hs timestamp Unix ms (string)
activities list contact <id returns timestamp (flat, top level) ISO 8601 (e.g. 2024 01 15T10:00:00Z )
Current Unix ms: $(date +%s)000 (macOS) or $(date +%s%3N) (Linux). activities list rows are {"id","type","timestamp","lastModified","title","body","status","owner id"} — the cross type timeline read shape, no raw property names.
Create + associate, by type
Open tasks for a contact — two CLI calls, no xargs
associations list emits {"id": …} per row (plus label/associationType fields); objects get reads from stdin in one batch call (see bulk operations/SKILL.md "Read in batch").
Open tasks portal wide — exclude statuses server side with @!=
@!= is NOT IN: one condition for the whole excluded list. Do not spend one filter flag per excluded status — the search API caps a request at 5 filter groups, 6 conditions per group, and 18 conditions total.
@!= matches only records that have the property, so replicating a real HubSpot task view's "status is none of … or is empty" needs two groups (OR'd), with the shared conditions repeated in each:
Inverse (only these statuses) is @= (IN): filter "hs task status@=NOT STARTED,IN PROGRESS,WAITING" .
Bulk: follow up task per deal in a stage
The deal ID and the task ID must travel together. Persist the deal payload to a file, create tasks (output order matches input order — see bulk operations), then zip the two ID lists line by line and stream association pairs in one call.
These are objects create calls (Additive) — creates are never digest gated, so dry run is a plain preview and you execute by dropping it (no digest/confirm). The digest flow only applies to the irreversible writes ( update / upsert / delete / merge ) in bulk operations/SKILL.md .
Known constraints
Activities must be associated immediately or they're invisible in the CRM UI. For enum option values on activity properties, run hubspot properties options list type calls <property (and for call outcomes, hubspot activities calls dispositions list ); the reference is the shortcut. Sales Hub sequences are read only in the CLI ( hubspot sequences list / get / enrollments , automation.sequences.read scope) — the CLI cannot enroll a contact in a sequence, so drive outreach via tasks/activities above. This surface grows; recheck hubspot help / CHANGELOG.md before assuming an API is missing.