Hubspot contacts
Use when the user wants to search, read, create, update, delete, or otherwise manage HubSpot CRM contacts (people records, emails, leads, subscribers) via the `hubspot` command-line tool.From its SKILL.md
npx -y skills add dipankar/hubspot-cli --skill hubspot-contactsAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
4 things to look at
- skips confirmationTells the agent to proceed without asking first, 1 time: "hubspot crm contacts delete 12345 --yes".
- reads credentialsReads from 2 credential sources: `HUBSPOT_ACCESS_TOKEN` and 1 more.
- 1 stars1 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
- runs commandsInstructs the agent to run 8 commands, including `hubspot crm contacts list --limit 10` and 7 more.
SKILL.md
3.7 KB, 957 tokens by cl100k_base, as published. Nobody here has run it
HubSpot Contacts (via hubspot CLI)
Drive HubSpot contact operations through the hubspot CLI. Every command emits a JSON envelope ({"success": true, "data": ...}) suitable for parsing.
Prerequisite: authentication
The CLI reads HUBSPOT_ACCESS_TOKEN (a HubSpot private-app token) from the environment. If a command returns exit code 3 with AUTH_ERROR, tell the user:
export HUBSPOT_ACCESS_TOKEN=<private-app-token>
Multi-account users can pass --profile <name> (reads [profiles.<name>] from ~/.config/hubspot-cli/config.toml).
Canonical commands
| Intent | Command |
|---|---|
| List recent contacts | hubspot crm contacts list --limit 10 |
| Paginate | hubspot crm contacts list --limit 50 --after <next_cursor> |
| Request extra properties | hubspot crm contacts list --properties phone,company,lifecyclestage |
| Get by ID | hubspot crm contacts get 12345 |
| Create from flags | hubspot crm contacts create --email [email protected] --firstname Jane --lastname Doe |
| Create from JSON | hubspot crm contacts create --properties '{"email":"[email protected]","lifecyclestage":"lead"}' |
| Update | hubspot crm contacts update 12345 --firstname Janet |
| Delete (archive) | hubspot crm contacts delete 12345 --yes |
| Simple search | hubspot crm contacts search --query "email:*@acme.com" --limit 25 |
| Filtered search | hubspot crm contacts search --filter-groups '[{"filters":[{"propertyName":"lifecyclestage","operator":"EQ","value":"customer"}]}]' |
| Batch create | hubspot crm contacts batch-create --inputs '[{"properties":{"email":"[email protected]"}},{"properties":{"email":"[email protected]"}}]' |
| Discover properties | hubspot discover properties contacts |
Filter-group operators
Common operator values for --filter-groups: EQ, NEQ, GT, GTE, LT, LTE, BETWEEN, IN, NOT_IN, HAS_PROPERTY, NOT_HAS_PROPERTY, CONTAINS_TOKEN, NOT_CONTAINS_TOKEN. Filter groups are OR'd; filters within a group are AND'd.
Default vs custom properties
Only email, firstname, lastname come back by default. For anything else (phone, company, lifecyclestage, hs_lead_status, hubspot_owner_id, custom properties) pass --properties prop1,prop2,.... Use hubspot discover properties contacts to list every valid property name.
Output envelope
{
"success": true,
"data": { "id": "12345", "properties": { "email": "...", "firstname": "..." } },
"paging": { "next_cursor": "abc", "has_more": true }
}
List endpoints put an array in data. Pagination: when paging.has_more is true, call again with --after <paging.next_cursor>.
Error codes (JSON error.code, exit code)
| Code | Exit | Action |
|---|---|---|
AUTH_ERROR | 3 | Tell the user to set HUBSPOT_ACCESS_TOKEN |
VALIDATION_ERROR / DUPLICATE_EMAIL | 5 | Show error.message; fix input |
NOT_FOUND | 6 | Contact ID doesn't exist or was archived |
RATE_LIMIT | 7 | Back off using error.retry_after_seconds |
SERVER_ERROR | 8 | Transient; retry once |
Required scopes
- Read:
crm.objects.contacts.read - Write:
crm.objects.contacts.write - Search:
crm.objects.contacts.read
Tips for the agent
- Prefer
searchoverlistwhen the user describes a filter ("contacts in lifecycle stage customer").listhas no filtering. - Always pass
--limitwhen the user says "a few" / "some" to keep responses small. - Use
--output json-prettyonly when showing the raw JSON to the user; use the defaultjsonwhen piping intojqor parsing. - Never echo the access token back to the user.
What ships with it
Read from the repository
Just SKILL.md. No reference files, no scripts.