Gx Hubspot Expert
criptogus/agent-evolve-network
Configure HubSpot CRM, workflows, lifecycle stages, lead scoring, and reporting.
Agent skill
by jeremylongshore in jeremylongshore/tons-of-skills-marketplace
Manage HubSpot lifecycle stages and list segmentation in production without silently destroying CRM trust.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a claude-codeProject install by default; add -g for ~/.claude/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-lifecycle-and-lists --agent claude-codeProject scope by default; add --scope user for a personal install. Needs GitHub CLI 2.90.0 or later (public preview).
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .claude/skills && cp -r skills-src/skills/.curated/hubspot-lifecycle-and-lists .claude/skills/hubspot-lifecycle-and-lists && rm -rf skills-srcUse ~/.claude/skills/ instead of .claude/skills for a personal install. The folder must contain SKILL.md.
Claude Code skills documentation · loads skills from .claude/skills/
Install the "hubspot-lifecycle-and-lists" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-lists into .claude/skills/hubspot-lifecycle-and-lists/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hubspot-lifecycle-and-lists", then confirm the skill loads.Claude Code copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$skill-installer install https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-listsType this inside Codex. $skill-installer <name> installs a curated skill from openai/skills. The installer writes to $CODEX_HOME/skills (default ~/.codex/skills). Restart Codex if the skill does not show up.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a codexProject install goes to .agents/skills/; add -g for ~/.codex/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-lifecycle-and-lists --agent codexProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .agents/skills && cp -r skills-src/skills/.curated/hubspot-lifecycle-and-lists .agents/skills/hubspot-lifecycle-and-lists && rm -rf skills-srcUse ~/.agents/skills/ instead of .agents/skills for a personal install.
Codex skills documentation · loads skills from .agents/skills/
Install the "hubspot-lifecycle-and-lists" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-lists into .agents/skills/hubspot-lifecycle-and-lists/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hubspot-lifecycle-and-lists", then confirm the skill loads.Codex copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a cursorProject install goes to .agents/skills/; add -g for ~/.cursor/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-lifecycle-and-lists --agent cursorProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .cursor/skills && cp -r skills-src/skills/.curated/hubspot-lifecycle-and-lists .cursor/skills/hubspot-lifecycle-and-lists && rm -rf skills-srcUse ~/.cursor/skills/ instead of .cursor/skills for a personal install.
Cursor skills documentation · loads skills from .cursor/skills/, .agents/skills/, .claude/skills/, .codex/skills/
Install the "hubspot-lifecycle-and-lists" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-lists into .cursor/skills/hubspot-lifecycle-and-lists/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hubspot-lifecycle-and-lists", then confirm the skill loads.Cursor copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gemini skills install https://github.com/jeremylongshore/tons-of-skills-marketplace.git --path skills/.curated/hubspot-lifecycle-and-lists--scope user (default) or --scope workspace; --path is the subfolder of the repo that holds the skill; --consent skips the security confirmation prompt.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a gemini-cliProject install goes to .agents/skills/; add -g for ~/.gemini/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-lifecycle-and-lists --agent gemini-cliProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .gemini/skills && cp -r skills-src/skills/.curated/hubspot-lifecycle-and-lists .gemini/skills/hubspot-lifecycle-and-lists && rm -rf skills-srcUse ~/.gemini/skills/ instead of .gemini/skills for a personal install, then run /skills reload.
Gemini CLI skills documentation · loads skills from .gemini/skills/, .agents/skills/
Install the "hubspot-lifecycle-and-lists" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-lists into .gemini/skills/hubspot-lifecycle-and-lists/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hubspot-lifecycle-and-lists", then confirm the skill loads.Gemini CLI copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-lifecycle-and-listsInstalls for Copilot at project scope by default; add --scope user for a personal install. Preview a skill first with gh skill preview. Needs GitHub CLI 2.90.0 or later (public preview).
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a github-copilotProject install goes to .agents/skills/; add -g for ~/.copilot/skills/.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .github/skills && cp -r skills-src/skills/.curated/hubspot-lifecycle-and-lists .github/skills/hubspot-lifecycle-and-lists && rm -rf skills-srcUse ~/.copilot/skills/ instead of .github/skills for a personal install. Commit .github/skills so cloud agent and code review can use it.
GitHub Copilot skills documentation · loads skills from .github/skills/, .claude/skills/, .agents/skills/
Install the "hubspot-lifecycle-and-lists" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-lists into .github/skills/hubspot-lifecycle-and-lists/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hubspot-lifecycle-and-lists", then confirm the skill loads.GitHub Copilot copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
$ npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a opencodeOpenCode documents no install command of its own. Project install goes to .agents/skills/; add -g for ~/.config/opencode/skills/.
$ gh skill install jeremylongshore/tons-of-skills-marketplace hubspot-lifecycle-and-lists --agent opencodeProject scope by default (.agents/skills/); add --scope user for a personal install.
$ git clone --depth 1 https://github.com/jeremylongshore/tons-of-skills-marketplace.git skills-src && mkdir -p .opencode/skills && cp -r skills-src/skills/.curated/hubspot-lifecycle-and-lists .opencode/skills/hubspot-lifecycle-and-lists && rm -rf skills-srcUse ~/.config/opencode/skills/ instead of .opencode/skills for a personal install.
OpenCode skills documentation · loads skills from .opencode/skills/, .claude/skills/, .agents/skills/
Install the "hubspot-lifecycle-and-lists" agent skill from https://github.com/jeremylongshore/tons-of-skills-marketplace/tree/main/skills/.curated/hubspot-lifecycle-and-lists into .opencode/skills/hubspot-lifecycle-and-lists/ in this project. Copy the whole folder (SKILL.md and every file beside it), keep the folder name "hubspot-lifecycle-and-lists", then confirm the skill loads.OpenCode copies the folder itself, the same result as the manual copy. Check what it changed before you commit it.
hubspot-lifecycle-and-listsManage HubSpot lifecycle stages and list segmentation in production without silently destroying CRM trust.
Hubspot Lifecycle And Lists is an agent skill from jeremylongshore/tons-of-skills-marketplace. Manage HubSpot lifecycle stages and list segmentation in production without silently destroying CRM trust. Covers lifecycle stage progression guards that prevent regression, dynamic list criteria drift, static list orphan detection, lead-scoring source-of-truth conflicts, webhook-missed-event recovery, and cross-portal list sync. Use when moving contacts through the funnel, building segment-based nurture flows, auditing list membership integrity, reconciling external lead scores with HubSpot native scoring, or…
Its SKILL.md is about 5.4k tokens, which your agent loads only when the skill is triggered. The skill folder holds 3 other files, including reference files (for example `references/API_REFERENCE.md` and `references/implementation-guide.md`). Compatibility notes: Designed for Claude Code
It sits in Sales & Support, covering CRM management, Lead generation and Webhooks. It works with HubSpot. The repository describes itself as: Model-agnostic agent-skills platform with a harness-free canonical layer, verified adapters, and the ccpi package manager. Explore at tonsofskills.com. The licence is MIT.
6 steps, taken from the step headings in SKILL.md.
Read from SKILL.md and the folder at commit cfae287. It shows what the files ask for, not the result of running them.
Pre-approves these tools, so the agent can use them without asking each time:
ReadWriteEditBash(curl:*)Bash(jq:*)Bash(python3:*)GrepFrom allowed-tools in the SKILL.md frontmatter.
Shell commands in SKILL.md call:
curljqpython3From the folder's file list and the shell code blocks in SKILL.md.
Hosts in commands or code, which the agent is likely to contact:
api.hubapi.comAlso links to:
developers.hubspot.comknowledge.hubspot.comFrom URLs in SKILL.md, links to its own repository left out.
Names these keys or tokens, usually read from environment variables:
HUBSPOT_ACCESS_TOKENFrom names ending in _API_KEY, _TOKEN, _SECRET, _KEY or _PASSWORD in SKILL.md.
Designed for Claude Code
From compatibility in the SKILL.md frontmatter.
Hubspot Lifecycle And Lists loads about 5.4k tokens when it runs, and up to ~19k if it reads all its reference files. Until then it costs about 211 tokens; SKILL.md has 1,624 words of instructions outside code blocks.
Estimates: characters ÷ 4, the usual rule of thumb; real counts depend on the model's tokenizer. Scripts and assets cost tokens only if the agent reads them.
The automated check noted patterns worth knowing about, such as sudo or a known installer.
1-*` values in source code or committed `.env` files.Automated static check — not a guarantee. Review scripts before installing. It scans the text of SKILL.md for risky patterns (piping downloads into a shell, reading credential files, hidden Unicode, destructive commands); files beside SKILL.md are not scanned.
The full file from jeremylongshore/tons-of-skills-marketplace at commit cfae287, republished under its MIT licence (© jeremylongshore). 1,624 words, ~5,395 tokens.
.claude/skills/hubspot-lifecycle-and-lists/SKILL.md (or your agent's skills folder). This skill also uses 2 other files; get the full folder from GitHub.Move contacts through the HubSpot funnel and maintain list integrity in a production system. This is not a setup walkthrough — it is the code your marketing-ops integration runs when a lifecycle stage update would silently regress a Customer back to Subscriber, when a dynamic list's criteria change orphans members who qualified last week, when a static list import references contacts that were deleted from the portal, when an external lead-scoring model creates a second source of truth that fights HubSpot's native scoring, when a list-membership webhook fires but your consumer returns 5xx and HubSpot never retries, and when an agency needs to mirror list membership across two portals that have no native sync API.
The six production failures this skill prevents:
PATCH /crm/v3/objects/contacts/{id} will set lifecyclestage to any valid value regardless of direction. Setting a Customer back to Subscriber silently destroys funnel attribution, invalidates reporting, and corrupts revenue forecasting. The API returns 200 OK. There is no built-in guard.POST /contacts/v1/lists/{listId}/add remain list members even after the underlying contact record is hard-deleted from the CRM. These orphan IDs return errors on any subsequent contact-level API call and pollute downstream sync pipelines.contact.propertyChange events for lifecyclestage updates and list-membership changes via HTTP POST with no retry on 5xx responses. A single downstream outage during a bulk-import window can drop hundreds of membership events permanently with no dead-letter queue or re-delivery mechanism.crm.objects.contacts.readcrm.objects.contacts.writecrm.lists.readcrm.lists.writecrm.schemas.contacts.read (for lifecycle stage enumeration)jq on PATH for shell-level inspectioncurl for API verification stepshubspot-auth skill)Store all tokens in a secret manager. Never put pat-na1-* values in source code or committed .env files.
Build in this order. Each section neutralizes one production failure mode.
The lifecycle stage enum has a defined forward direction. Any update that moves a contact backward is almost certainly a data pipeline bug, not an intentional business action.
Canonical stage order (HubSpot internal values, not display labels):
subscriber → lead → marketingqualifiedlead → salesqualifiedlead → opportunity → customer → evangelist → otherother is a lateral bucket, not a terminal stage — it sits outside the linear progression and should only be set explicitly.
Never read the stage order from display labels. Display labels are portal-configurable. Always use the internal enum values.
Progression guard pattern (Python):
STAGE_ORDER = [
"subscriber",
"lead",
"marketingqualifiedlead",
"salesqualifiedlead",
"opportunity",
"customer",
"evangelist",
]
# 'other' is not in the linear sequence — treat as a lateral assignment
def stage_index(stage: str) -> int:
try:
return STAGE_ORDER.index(stage.lower())
except ValueError:
return -1 # 'other' or unknown — always allow
def safe_set_lifecycle(contact_id: str, new_stage: str, token: str) -> dict:
current = get_contact_lifecycle(contact_id, token)
current_idx = stage_index(current)
new_idx = stage_index(new_stage)
# Allow lateral 'other' assignments and forward progressions
if current_idx != -1 and new_idx != -1 and new_idx < current_idx:
raise ValueError(
f"Lifecycle regression blocked: {current} → {new_stage} "
f"for contact {contact_id}. "
f"Current index={current_idx}, requested index={new_idx}."
)
return patch_contact_lifecycle(contact_id, new_stage, token)
def get_contact_lifecycle(contact_id: str, token: str) -> str:
import urllib.request, json
url = f"https://api.hubapi.com/crm/v3/objects/contacts/{contact_id}?properties=lifecyclestage"
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"})
with urllib.request.urlopen(req) as resp:
data = json.loads(resp.read())
return data["properties"].get("lifecyclestage", "subscriber")
def patch_contact_lifecycle(contact_id: str, stage: str, token: str) -> dict:
import urllib.request, json
url = f"https://api.hubapi.com/crm/v3/objects/contacts/{contact_id}"
payload = json.dumps({"properties": {"lifecyclestage": stage}}).encode()
req = urllib.request.Request(
url,
data=payload,
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
method="PATCH",
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())Verify a contact's current stage before running a bulk update:
curl -s \
"https://api.hubapi.com/crm/v3/objects/contacts/{contact-id}?properties=lifecyclestage" \
-H "Authorization: Bearer {your-token}" \
| jq '.properties.lifecyclestage'When you edit a dynamic list's filter criteria, HubSpot queues a background re-evaluation job. Existing members who no longer satisfy the new criteria remain in the list until that job completes — up to 24 hours. Any automation triggered on list membership during that window operates on stale data.
Production pattern: snapshot membership before and after a criteria change, then audit the delta.
import urllib.request, json, time
def snapshot_list_members(list_id: int, token: str) -> set[str]:
"""Return the full set of vid (legacy contact ID) strings for a list."""
vids = set()
offset = None
while True:
url = f"https://api.hubapi.com/contacts/v1/lists/{list_id}/contacts/all?count=100"
if offset:
url += f"&vidOffset={offset}"
req = urllib.request.Request(url, headers={"Authorization": f"Bearer {token}"})
with urllib.request.urlopen(req) as resp:
data = json.loads(resp.read())
for contact in data.get("contacts", []):
vids.add(str(contact["vid"]))
if not data.get("has-more", False):
break
offset = data["vid-offset"]
return vids
def audit_criteria_drift(list_id: int, token: str, poll_interval_s: int = 3600):
"""
Take a pre-criteria-change snapshot, wait for the nightly refresh window,
take a post snapshot, and report contacts that should have been removed.
Call this before editing criteria and again after the refresh window.
"""
before = snapshot_list_members(list_id, token)
print(f"Pre-change member count: {len(before)}")
print(f"Snapshot saved. Re-run after {poll_interval_s}s (or after nightly refresh).")
return beforeShell verification of list metadata:
curl -s \
"https://api.hubapi.com/contacts/v1/lists/{list-id}" \
-H "Authorization: Bearer {your-token}" \
| jq '{listId, name, listType, updatedAt, metaData}'Flag the list as DYNAMIC in your internal registry and mark it "refresh-pending" whenever criteria change. Suppress automation triggers until a post-refresh snapshot confirms membership is stable.
A static list retains member IDs after the underlying contact record is hard-deleted. Batch-processing that list later will hit 404 on every orphaned ID, burning API quota and producing false error telemetry.
Orphan sweep pattern (key logic):
def find_orphaned_members(list_id: int, token: str, batch_size: int = 100) -> list[str]:
"""Return vids in the list whose contact records no longer exist."""
all_vids = list(snapshot_list_members(list_id, token))
orphans = []
for i in range(0, len(all_vids), batch_size):
batch = all_vids[i : i + batch_size]
payload = json.dumps({
"inputs": [{"id": vid} for vid in batch],
"properties": ["lifecyclestage"],
}).encode()
# POST /crm/v3/objects/contacts/batch/read
# Any VIDs absent from results[] are orphaned
result = batch_read_contacts(payload, token)
found_ids = {str(r["id"]) for r in result.get("results", [])}
orphans.extend(v for v in batch if v not in found_ids)
return orphansFull batch_read_contacts + remove_orphans_from_static_list implementations: implementation-guide.md § Static List Batch Membership Manager.
Schedule this sweep weekly and before any bulk send that reads the static list.
If HubSpot's native Lead Scoring tool is active on a portal, it writes to the system-managed hs_lead_status and hubspotscore properties. Writing an external score to hubspotscore directly is blocked — HubSpot rejects the PATCH with a 400. Writing to a custom property (e.g., external_lead_score) creates a second source of truth that sales and marketing will each discover separately and use inconsistently.
Resolution pattern — pick one authority and route everything through it:
Option A (HubSpot is authority): disable or remove the HubSpot native scoring ruleset, write the external score to hubspotscore via the API, and document the source in the portal's settings notes.
Option B (external model is authority): disable native HubSpot scoring, write the external score to a single custom property (external_lead_score), and update every automation and workflow filter to reference that property instead of hubspotscore. Write a clear comment in every HubSpot workflow that hubspotscore is not used.
Option C (both must coexist): keep both, but surface the discrepancy to the rep via a third computed field:
def write_external_score(contact_id: str, score: int, token: str):
"""
Write external score to a custom property. Never write to hubspotscore
if HubSpot native scoring is active — the PATCH will be rejected.
"""
payload = json.dumps({"properties": {"external_lead_score": str(score)}}).encode()
req = urllib.request.Request(
f"https://api.hubapi.com/crm/v3/objects/contacts/{contact_id}",
data=payload,
headers={
"Authorization": f"Bearer {token}",
"Content-Type": "application/json",
},
method="PATCH",
)
with urllib.request.urlopen(req) as resp:
return json.loads(resp.read())Document the scoring authority in a pinned internal wiki page. Ambiguity here compounds over time.
HubSpot delivers contact.propertyChange events (for lifecyclestage) and list-membership events via HTTP POST to your registered endpoint. If your consumer returns a 5xx, HubSpot does not retry. There is no dead-letter queue, no re-delivery, no backfill API. The event is permanently lost.
Three-layer defense:
Layer 1 — Fast consumer with async processing. Accept the POST, validate the signature, write the raw payload to a durable queue (Redis, SQS, Postgres events table), return 200 immediately. Never do downstream processing inside the HTTP handler — any exception there causes a 5xx and the event is lost.
Layer 2 — Idempotent event processor. Use the HubSpot eventId as an idempotency key before processing:
PROCESSED_EVENT_IDS = set() # replace with Redis SET or DB unique constraint
def process_event(event: dict):
event_id = event.get("eventId")
if event_id in PROCESSED_EVENT_IDS:
return # duplicate delivery — skip
PROCESSED_EVENT_IDS.add(event_id)
# downstream logic here — never inside the HTTP handlerLayer 3 — Reconciliation sweep. Every 6 hours, compare local cached lifecycle stages to the HubSpot REST API. Divergence = missed webhook.
Full HTTP handler with SQLite durable store, v3 signature validation, processor thread, and reconciliation loop: implementation-guide.md § List-Membership Webhook Handler with Idempotency.
There is no HubSpot API endpoint for "sync list A in portal X to list B in portal Y." The workaround is a two-leg pull-and-push:
GET /contacts/v1/lists/{sourceListId}/contacts/all?property=email from the source portal to collect all member emails.GET /contacts/v1/contact/email/{email}/profile. Contacts with no matching email in the destination are unresolvable — log and skip, do not fail the sync.POST /contacts/v1/lists/{destListId}/add in batches of 100.Key constraint: the destination list must be STATIC — dynamic lists reject direct membership writes.
Full implementation with dry-run mode, unresolvable reporting, and rate-limit delays: implementation-guide.md § Cross-Portal List Sync.
Schedule this sync as a nightly job. For suppression lists, run it before every campaign send, not on a calendar cadence.
| HTTP Status | Error | Root Cause | Action |
|---|---|---|---|
400 BAD_REQUEST | PROPERTY_VALUE_NOT_FOUND | Invalid lifecycle stage enum value sent in PATCH | Validate against canonical enum before calling — see API_REFERENCE.md lifecycle stage table |
400 BAD_REQUEST | Cannot modify system-managed property | Attempt to write to hubspotscore while native scoring is active | Disable native scoring or write to a custom property instead |
404 NOT_FOUND | Contact not found | Orphaned VID in a static list, or contact was hard-deleted | Run orphan sweep, remove VID from list |
404 NOT_FOUND | List not found | List was deleted; IDs are not reused | Remove the list reference from all automation configs |
409 CONFLICT | CONTACT_ALREADY_EXISTS_IN_LIST | Duplicate add to a static list | Idempotent — treat as success, not error |
429 TOO_MANY_REQUESTS | RATE_LIMIT | API quota exhausted (100 calls/10s per private app) | Back off with Retry-After header; use batch endpoints to reduce call count |
500 INTERNAL_SERVER_ERROR | HubSpot internal error | Transient HubSpot infrastructure issue | Retry with exponential backoff (max 4 attempts); log for rate-limit awareness |
0 (no response) | Webhook delivery failed | Your consumer returned 5xx or timed out | HubSpot will not retry — rely on reconciliation sweep to detect and correct |
curl -s -X PATCH \
"https://api.hubapi.com/crm/v3/objects/contacts/{contact-id}" \
-H "Authorization: Bearer {your-token}" \
-H "Content-Type: application/json" \
-d '{"properties": {"lifecyclestage": "salesqualifiedlead"}}' \
| jq '{id, properties: {lifecyclestage: .properties.lifecyclestage}}'curl -s -X POST \
"https://api.hubapi.com/crm/v3/objects/contacts/search" \
-H "Authorization: Bearer {your-token}" \
-H "Content-Type: application/json" \
-d '{
"filterGroups": [{"filters": [{"propertyName": "lifecyclestage", "operator": "EQ", "value": "customer"}]}],
"properties": ["email", "lifecyclestage", "hs_lead_status"],
"limit": 100
}' \
| jq '{total, results: [.results[] | {id, email: .properties.email, stage: .properties.lifecyclestage}]}'curl -s -X POST \
"https://api.hubapi.com/contacts/v1/lists" \
-H "Authorization: Bearer {your-token}" \
-H "Content-Type: application/json" \
-d '{"name": "2026-Q2 Campaign — Suppression", "dynamic": false}' \
| jq '{listId, name, listType}'curl -s -X POST \
"https://api.hubapi.com/contacts/v1/lists/{list-id}/add" \
-H "Authorization: Bearer {your-token}" \
-H "Content-Type: application/json" \
-d '{"vids": [12345, 67890, 11223]}' \
| jq '{updated, discarded}'curl -s \
"https://api.hubapi.com/contacts/v1/lists/all/lists/static?count=250" \
-H "Authorization: Bearer {your-token}" \
| jq '[.lists[] | {listId, name, updatedAt, metaData: {size: .metaData.size}}]'python3 - <<'EOF'
import os, json
# Load the progression-guard code from implementation-guide.md
# Then run a dry-run report before committing changes
contacts = [
{"id": "12345", "target_stage": "marketingqualifiedlead"},
{"id": "67890", "target_stage": "customer"},
]
token = os.environ["HUBSPOT_ACCESS_TOKEN"]
for c in contacts:
try:
result = safe_set_lifecycle(c["id"], c["target_stage"], token)
print(f"Updated {c['id']} → {c['target_stage']}")
except ValueError as e:
print(f"BLOCKED: {e}")
EOF© jeremylongshore, MIT. Rendered from Markdown: HTML in the file is shown as text, images as links, and headings moved down two levels. Raw file
SKILL.md and 2 other files (references) in skills/.curated/hubspot-lifecycle-and-lists of jeremylongshore/tons-of-skills-marketplace.
Open the folder on GitHubat commit cfae287
Hubspot Lifecycle And Lists next to the 5 skills that share the most tags, products or categories with it. Stars are the repository's; “used in” counts other GitHub owners with a copy.
| Skill | Stars | Used in | Tokens | Auto-check | Licence | Repo updated |
|---|---|---|---|---|---|---|
| Hubspot Lifecycle And Lists this skilljeremylongshore/tons-of-skills-marketplace | 2.8k | — | ~5.4k | Automated safety check: Notes | MIT | |
| Gx Hubspot Expertcriptogus/agent-evolve-network | 288 | — | ~745 | Automated safety check: Pass | MIT | |
| Lead Gen Tool Builderexplorium-ai/gtm-skills | 185 | — | ~1.8k | Automated safety check: Notes | MIT | |
| Lead ScoringLeoYeAI/openclaw-master-skills | 2.2k | — | ~4.6k | Automated safety check: Pass | MIT | |
| Hubspot Integrationdavila7/claude-code-templates | 33k | 4 repos | ~265 | Automated safety check: Pass | MIT | |
| Hubspot Integrationaiskillstore/marketplace | 433 | 3 repos | ~5k | Automated safety check: Pass | None |
criptogus/agent-evolve-network
Configure HubSpot CRM, workflows, lifecycle stages, lead scoring, and reporting.
explorium-ai/gtm-skills
Lead generation tool builder skill for Claude Code and Codex: scaffolds a complete, self-hostable, ZoomInfo-style B2B lead-generation web app — company & contact search UI, firmographic and…
LeoYeAI/openclaw-master-skills
Set up and automate lead scoring for HubSpot and other CRMs.
davila7/claude-code-templates
Expert patterns for HubSpot CRM integration including OAuth authentication, CRM objects, associations, batch operations, webhooks, and custom objects.
aiskillstore/marketplace
Expert patterns for HubSpot CRM integration including OAuth authentication, CRM objects, associations, batch operations, webhooks, and custom objects.
manojbajaj95/claude-gtm-plugin
A skill your agent uses when setting up marketing automation in HubSpot, Marketo, email sequences, lead scoring, and workflows.
jeremylongshore/tons-of-skills-marketplace
Execute this skill enables AI assistant to conduct a security-focused code review using the security-agent plugin.
jeremylongshore/tons-of-skills-marketplace
Build this skill automates the adaptation of pre-trained machine learning models using transfer learning techniques.
jeremylongshore/tons-of-skills-marketplace
Execute proactive auto-loading: automatically detects and loads agents.md files.
jeremylongshore/tons-of-skills-marketplace
Aggregate and centralize performance metrics from applications, systems, databases, caches, and services.
jeremylongshore/tons-of-skills-marketplace
Execute this skill enables AI assistant to analyze capacity requirements and plan for future growth.
jeremylongshore/tons-of-skills-marketplace
Process use when you need to work with database indexing. An agent skill from jeremylongshore/tons-of-skills-marketplace.
Works with
Categories
Manage HubSpot lifecycle stages and list segmentation in production without silently destroying CRM trust. Hubspot Lifecycle And Lists is an agent skill from jeremylongshore/tons-of-skills-marketplace. Manage HubSpot lifecycle stages and list segmentation in production without silently destroying CRM trust.
Hubspot Lifecycle And Lists fits situations like: moving contacts through the funnel; building segment-based nurture flows; auditing list membership integrity; reconciling external lead scores with HubSpot native scoring.
Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a claude-code`. Or copy the skill folder (skills/.curated/hubspot-lifecycle-and-lists in jeremylongshore/tons-of-skills-marketplace) into .claude/skills/hubspot-lifecycle-and-lists in your project. Claude Code loads it when a task matches its description.
Run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a codex`. Or copy the skill folder (skills/.curated/hubspot-lifecycle-and-lists in jeremylongshore/tons-of-skills-marketplace) into .agents/skills/hubspot-lifecycle-and-lists in your project. Codex loads it when a task matches its description.
Cursor, Gemini CLI, GitHub Copilot and OpenCode also load SKILL.md folders. With the skills CLI, run `npx skills add jeremylongshore/tons-of-skills-marketplace --skill hubspot-lifecycle-and-lists -a cursor` (or -a gemini-cli, github-copilot or opencode for the others). To copy it by hand, put the folder in .cursor/skills/hubspot-lifecycle-and-lists, .gemini/skills/hubspot-lifecycle-and-lists, .github/skills/hubspot-lifecycle-and-lists and .opencode/skills/hubspot-lifecycle-and-lists in your project.
Going by SKILL.md and its folder, Hubspot Lifecycle And Lists needs the command-line tools its instructions call (curl, jq and python3) and credentials named HUBSPOT_ACCESS_TOKEN. Our summary lists: Python 3; Node.js. Its frontmatter pre-approves these tools: Read, Write, Edit, Bash(curl:*), Bash(jq:*), Bash(python3:*), Grep. Compatibility (from SKILL.md): Designed for Claude Code.
SKILL.md names 3 domains. In commands or code: api.hubapi.com; the agent is likely to contact it when it follows the instructions. As links in the text: developers.hubspot.com and knowledge.hubspot.com. This is read from the text; nothing was executed.
Our automated static check of SKILL.md found notes only (mentions a .env file), nothing it rates as a warning. It is not a guarantee. Review the folder before installing.
Hubspot Lifecycle And Lists is published under the MIT licence (declared in SKILL.md). It allows redistribution, so the full SKILL.md is shown on this page.
About 5.4k tokens (SKILL.md is roughly 22k characters). Agents keep only the skill's name and description in context until a task matches; then they load SKILL.md in full. Its references folder adds about 14k tokens, read only when the agent opens those files.
Skills that share tags, products or a category with Hubspot Lifecycle And Lists: Gx Hubspot Expert (criptogus/agent-evolve-network, 288 stars), Lead Gen Tool Builder (explorium-ai/gtm-skills, 185 stars), Lead Scoring (LeoYeAI/openclaw-master-skills, 2.2k stars) and Hubspot Integration (davila7/claude-code-templates, 33k stars). The comparison table on this page puts their stars, adoption, token cost, safety result and licence side by side.
jeremylongshore (a GitHub user) maintains it in jeremylongshore/tons-of-skills-marketplace, which has 2,827 GitHub stars. The repository holds 3,342 skills in this directory. The repository was last updated on October 10, 2026.
Source: jeremylongshore/tons-of-skills-marketplace on GitHub. Facts on this page come from the repository at the commit we read; the author's words are quoted as theirs.