asana-api
Read and manage Asana tasks, projects, sections, comments, and workspaces. Use this whenever the user wants to list or search…
Read, create, update, search, and associate HubSpot CRM records — contacts, companies, deals, tickets, and custom objects. Use this whenever the user wants to look up a contact, create a deal, update a company, search the CRM, link two records, or asks "what's in HubSpot" — even
$ npx -y skills add anthropics/claude-tag-plugins --skill hubspot-api --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/hubspot-apiContext preview
The summary Claude sees to decide when to auto-load this skill.
Read, create, update, search, and associate HubSpot CRM records — contacts, companies, deals, tickets, and custom objects. Use this whenever the user wants to look up a contact, create a deal, update a company, search the CRM, link two records, or asks "what's in HubSpot" — even
name: hubspot-api description: Read, create, update, search, and associate HubSpot CRM records — contacts, companies, deals, tickets, and custom objects. Use this whenever the user wants to look up a contact, create a deal, update a company, search the CRM, link two records, or asks "what's in HubSpot" — even if they don't say "API". Also use it for any URL under app.hubspot.com or a mention of a HubSpot object/record ID. Always start from this skill when interacting with this service — its bundled scripts and recipes are the fastest path.
HubSpot's CRM API (v3) is uniform across object types: every object lives under `https://api.hubapi.com/crm/v3/objects/{objectType}` and supports the same basic/search/batch/association operations.
(HubSpot is rolling out date-based path versions — `/crm/objects/2026-03/...` — as the successor naming. The `v3`/`v4` paths below all still work; HubSpot has announced `v4` becomes unsupported on 2027-03-30 and `v3`'s end-of-support date is not yet set. No migration is required for now.)
**Key concepts:**
`objectTypeId` (`0-1`, `0-2`, `0-3`, `0-5`). Custom objects are `2-<n>` or their `p_<name>` alias. Either form works in the URL.
(`hs_object_id`, `createdate`, `lastmodifieddate`, and per-type defaults like `email` / `firstname` for contacts). Always pass `properties=` with a comma-separated list of the fields you actually need, or you'll get records that look empty.
companies on `domain`; deals and tickets have no dedup. Know the key before creating.
built-in type IDs. You can also define custom association labels.
Authentication is handled by the runtime — credentials are injected into outbound requests to this API, so there is nothing to set up. Do not try to create, mint, refresh, or validate tokens or keys. Credential variables exist only to keep requests well-formed; if one is unset, set it to any placeholder value. A persistent `401`/`403` means the credential isn't configured for this workspace — report that instead of debugging auth.
Every request carries a bearer header. The configured credential has a set of scopes (`crm.objects.contacts.read`, `crm.objects.deals.write`, etc.) that control what it can touch.
export HUBSPOT_ACCESS_TOKEN="placeholder" # injected by the runtime; any value works
**Sanity check** — confirm the workspace is wired up:
curl -sS "https://api.hubapi.com/crm/v3/objects/contacts?limit=1" \
-H "Authorization: Bearer ${HUBSPOT_ACCESS_TOKEN}" | jq .A `403` means the request authenticated but the configured credential lacks the scope for what you tried.
For brevity the recipes below use a helper. Define it once, or copy the `-H` flag onto each `curl`:
hsapi() { curl -sS "$@" -H "Authorization: Bearer ${HUBSPOT_ACCESS_TOKEN}" -H "Content-Type: application/json"; }The operations below use `contacts`, but the same paths work for `companies`, `deals`, `tickets`, and any custom object — just swap the `{objectType}` segment.
Cursor-paginated, property-filtered, no search.
hsapi -G "https://api.hubapi.com/crm/v3/objects/contacts" \
--data-urlencode "limit=50" \
--data-urlencode "properties=email,firstname,lastname,lifecyclestage,hubspot_owner_id" \
--data-urlencode "archived=false" | jq '.results[] | {id, props: .properties}'On failure the response is `{"status":"error", "message":..., "category":...}` and has no `.results` — see Error handling. Guard once if scripting (`jq 'if .results then … else . end'`); the recipes below show the bare projection for clarity.
Add `associations=companies,deals` to inline association IDs for each record.
hsapi -G "https://api.hubapi.com/crm/v3/objects/contacts/CONTACT_ID" \ --data-urlencode "properties=email,firstname,lastname,phone,company" \ --data-urlencode "associations=companies,deals" | jq .
To fetch by a unique property instead of internal ID (e.g. by email), add `idProperty=email` and put the email in the path:
hsapi -G "https://api.hubapi.com/crm/v3/objects/contacts/alice@example.com" \ --data-urlencode "idProperty=email" \ --data-urlencode "properties=email,firstname,lastname" | jq .
hsapi -X POST "https://api.hubapi.com/crm/v3/objects/contacts" \
-d '{
"properties": {
"email": "alice@example.com",
"firstname": "Alice",
"lastname": "Nguyen",
"lifecyclestage": "lead"
}
}' | jq 'if .status == "error" then . else {id, createdAt} end'To create **and associate** in one call, add an `associations` array:
hsapi -X POST "https://api.hubapi.com/crm/v3/objects/deals" \
-d '{
"properties": {
"dealname": "Acme expansion",
"pipeline": "default",
"dealstage": "appointmentscheduled",
"amount": "15000"
},
"associations": [
{"to": {"id": "COMPANY_ID"}, "types": [{"associationCategory": "HUBSPOT_DEFINED", "associationTypeId": 341}]}
]
}' | jq .`341` is `deal_to_company`. See the association-type table in `references/api.md`, or discover them live (op 8).
`PATCH` only the properties you want to change. Everything else is untouched.
hsapi -X PATCH "https://api.hubapi.com/crm/v3/objects/contacts/CONTACT_ID" \
-d '{"properties": {"lifecyclestage": "marketingqualifiedlead", "phone": "+1-555-0100"}}'Updating by unique property works the same as reading — append `?idProperty=email` and put the email in the path.
Plugins for @claude that connect the agent to common SaaS services. Each service is its own plugin, so a workspace can connect exactly the services it uses.
Read and manage Asana tasks, projects, sections, comments, and workspaces. Use this whenever the user wants to list or search…
Run SQL against Google BigQuery and browse its catalog — submit queries (sync or async), poll job status, page through results,…
Compose polished charts (timeseries, bar, line, area, pie, scatter, or anything else the data calls for) from tabular data using…
Automatic init the first time Claude acts in an incident or alerts channel — one named like #inc-…, #incident-…, #sev0-…/#sev1-…,…
Investigate an alert, page, or production symptom in an incident channel or a team's oncall / monitoring channel, and report…
Write the postmortem for an incident, in its incident channel, once it is mitigated or resolved. Use on "write up this incident",…