audience-targeting
This skill filters HubSpot contacts by lifecycle stage, engagement, job title, geography, and company attributes, then exports the matching segment as JSONL…
Community author
- Agents
- Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode
- License
- Apache-2.0 (permissive)
- Pin
- a8eea08pinned Oct 9, 2026
- Context cost
- about 1,900 tokenswhen the skill loads
- GitHub stars
- 27on hubspot/agent-cli-skills
- Scripts
- None found
What it does
“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.”
Generated summary from the skill's own text
This skill filters HubSpot contacts by lifecycle stage, engagement, job title, geography, and company attributes, then exports the matching segment as JSONL for campaigns or downstream systems. It handles cross-object queries to find contacts at target companies and supports pagination for large result sets.
When to use it
- Build lists of leads, decision-makers, or engaged contacts for outreach campaigns
- Target prospects by geography, job title, or company size and industry
- Create reusable contact segments for email campaigns or sales workflows
- Find contacts at specific companies meeting firmographic criteria
When not to
- When you need to apply complex regex patterns or substring matching on contact fields
- When targeting behavior data that requires buyer intent or analytics analysis instead of CRM attributes
Install
These commands install from the publisher's repository and need no account.
skills CLI
npx skills add hubspot/agent-cli-skills --skill audience-targetingInstalls from the repository's default branch, which may have changed since the commit we checked.
GitHub CLI 2.90 or later
gh skill install hubspot/agent-cli-skills audience-targeting@a8eea0880838f8eb5fc79ed2cc3e5bc30edad904Installs the commit we checked (a8eea08).
Copy by hand
Download the folder at a8eea08 and put it in .claude/skills/audience-targeting for Claude Code and in .agents/skills/audience-targeting for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode.
Copy for your agent
A prompt for any coding agent. It installs this skill from GitHub at the pinned commit, copies the files as they are, and runs nothing unless you ask.
Prompt
Install the agent skill "audience-targeting" by HubSpot. Source, pinned to commit a8eea0880838f8eb5fc79ed2cc3e5bc30edad904: https://github.com/hubspot/agent-cli-skills/tree/a8eea0880838f8eb5fc79ed2cc3e5bc30edad904/audience-targeting 1. Download that folder at exactly this commit. Do not use the default branch. 2. Copy every file unchanged, keeping the folder structure, into .claude/skills/audience-targeting/ for Claude Code and .agents/skills/audience-targeting/ for Codex, Cursor, Gemini CLI, GitHub Copilot and OpenCode. Create the folders if they do not exist. 3. Do not edit the files, and do not run any script in the folder unless I ask you to. 4. When you are done, list the files you copied and where you put them. Listing and checks: https://www.agentnative.dev/skills/hubspot/audience-targeting
SKILL.md at the pin
---
name: audience-targeting
description: 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.
triggers:
- "segment contacts"
- "target audience"
- "find prospects"
- "build audience"
- "contact segmentation"
- "contacts in industry"
- "decision makers"
- "engaged contacts"
---
## Foundation
Read `bulk-operations/SKILL.md` first — pagination, JSONL piping, destructive-op safety. Reshape recipes in `bulk-operations/resources/json-patterns.md`. Resource: `resources/contact-segmentation-filters.md` is the filter-expression cookbook (lifecycle, lead status, email engagement, activity, deals, owner).
## Filter syntax cheat sheet
Source of truth: `hubspot objects search --help`.
- One `--filter` flag = one AND group: `--filter "lifecyclestage=lead AND !hubspot_owner_id"`.
- Multiple `--filter` flags are OR'd. Use for enum-OR-enum.
- Operators: `=`, `!=`, `>`, `>=`, `<`, `<=`, `~` (CONTAINS_TOKEN — whole-word, NOT substring), `@=` (IN), `@!=` (NOT_IN).
- HAS_PROPERTY: bare `name` or `name?`. NOT_HAS_PROPERTY: `!name`. Dates: `YYYY-MM-DD`.
- **Limits (CRM search API):** max 5 `--filter` flags, max 6 conditions per flag, max 18 conditions total. Prefer `@=` / `@!=` for enum lists — `lifecyclestage@=lead,customer` is **one** condition, `--filter "lifecyclestage=lead" --filter "lifecyclestage=customer"` is two groups.
- **"None of these, or empty" needs two groups** — `@!=` skips records where the property is unset, so OR in a `!name` group and repeat the shared conditions in both:
`--filter "hubspot_owner_id=123 AND lifecyclestage@!=customer,evangelist" --filter "hubspot_owner_id=123 AND !lifecyclestage"`
`~` gotcha: `jobtitle~director` matches the token "director", not arbitrary substrings. No regex operator — search broadly, post-filter with `jq`.
## Properties this skill turns on
Full live list: `hubspot properties list --type contacts`. Enum options: `hubspot properties options-list --type contacts <name> | jq -r '.value'`. As a fallback (e.g. to see which values are actually in use), read live records: `hubspot objects list --type contacts --properties <name> --limit 100 --format json | jq -r '.data[].properties.<name> // empty' | sort -u`.
Core fields used here: `lifecyclestage`, `hubspot_owner_id` (bare/`!` for owned/unowned; `hubspot owners list` for IDs), `hs_email_optout` (`!=true` excludes opted-out), `hs_email_last_open_date` / `notes_last_contacted` (recency), `jobtitle` / `country` / `city` (string `=` or `~`), `num_associated_deals` (0 net-new, `>=1` has-pipeline).
Firmographics (`industry`, `numberofemployees`, `annualrevenue`) live on **companies** — see cross-object section.
## Common segments
```bash
# Recent leads (this quarter, not yet owned)
hubspot objects search --type contacts \
--filter "lifecyclestage=lead AND createdate>2026-01-01 AND !hubspot_owner_id" \
--properties email,firstname,lastname,createdate
# Decision-makers by jobtitle (OR across tokens)
hubspot objects search --type contacts \
--filter "jobtitle~director" --filter "jobtitle~vp" --filter "jobtitle~chief" \
--properties email,jobtitle,company
# Engaged but not yet MQL (opened recently, still lead, opted in)
hubspot objects search --type contacts \
--filter "lifecyclestage=lead AND hs_email_last_open_date>2026-04-01 AND hs_email_optout!=true" \
--properties email,firstname,hs_email_last_open_date
# Geographic — US contacts opted in
hubspot objects search --type contacts \
--filter "country=United States AND hs_email_optout!=true" \
--properties email,state,city
```
More patterns (lead status, deals, owners, combined AND/OR) in `resources/contact-segmentation-filters.md`.
## Cross-object: companies-in-industry → their contacts
`industry`/`numberofemployees`/`annualrevenue` live on the company. Build the company set, then traverse — never `xargs -I{} hubspot objects get` per company. `associations list` emits `{"id":"...","labels":[...],"associationTypes":[...]}` — `{id}` feeds directly into a single batched `objects get`.
```bash
# Step 1: target companies. Industry options are portal-specific — discover with:
# hubspot objects list --type companies --properties industry --limit 100 --format json \
# | jq -r '.data[].properties.industry // empty' | sort -u
hubspot objects search --type companies \
--filter "industry=SOFTWARE AND numberofemployees>=100" \
--properties name,industry,numberofemployees \
> target_companies.jsonl
# Step 2: gather association IDs (associations list has no batch --from), then ONE batched
# objects get for all contacts. Page each company with --limit/--after — a company with >100
# associated contacts truncates silently on a single call.
while read -r cid; do
after=""
while :; do
page=$(hubspot associations list --from "companies:$cid" --to contacts --limit 100 ${after:+--after "$after"} --format json)
echo "$page" | jq -c '.data[]?'
after=$(echo "$page" | jq -r '.meta.next // empty')
[ -z "$after" ] && break
done
done \
< <(jq -r '.id' target_companies.jsonl) \
| jq -c '{id}' | sort -u \
| hubspot objects get --type contacts --properties email,firstname,jobtitle,hs_email_optout \
> target_contacts.jsonl
# Optional: drop opted-out
jq -c 'select(.properties.hs_email_optout != "true")' target_contacts.jsonl > campaign_audience.jsonl
```
## Saving and reusing a segment
A segment is a JSONL file. Re-use for updates, exports, or re-fetches:
```bash
# Save
hubspot objects search --type contacts \
--filter "lifecyclestage=lead AND hs_email_optout!=true" \
--properties email,firstname,lastname,jobtitle \
> segments/opted_in_leads.jsonl
# Assign owner (dry-run first per bulk-operations/SKILL.md)
jq -c '{id, properties:{hubspot_owner_id:"12345"}}' segments/opted_in_leads.jsonl \
| hubspot objects update --type contacts --dry-run
# Re-fetch with different properties later
jq -c '{id}' segments/opted_in_leads.jsonl \
| hubspot objects get --type contacts --properties email,lifecyclestage,hs_lead_status
```
Destructive ops on a saved segment follow the dry-run → digest → confirm flow in `bulk-operations/SKILL.md`.
## Save as a HubSpot list or view
A JSONL segment is portable, but you can also persist an audience in HubSpot:
- **List** — `hubspot segments create` saves a list; `segments get` / `list` inspect it; `segments members-list` reads members; `segments members-add` / `members-remove` manage membership. Use `segments update-filters` to set a dynamic list's filter criteria.
- **View** — `hubspot views create --type <t> --name "..." --columns a,b [--filters-file filters.json] [--sort prop:asc]` saves a filter set as a reusable object view; `views list` / `get` / `update` / `replace-field` / `delete` manage it.
- **Size it first** — `hubspot objects count --type contacts --filter "..."` returns `{"object_type":"contacts","total":N}` without paging, so you can size an audience before saving or exporting it.
## Related read-only signals (context for targeting)
- `hubspot buyer-intent` — visiting-company intent signals (read-only). **Requires OAuth login (`hubspot auth login`); service keys are NOT supported.**
- `hubspot analytics traffic sources` — where sessions/contacts came from, for source-based segmentation.
- `hubspot marketing forms list` — form definitions, to segment by which form a contact converted on.
Run each command's `--help` for the full surface.
## Known limits
- `~` is token-match, not substring. No regex operator.
- Enum options: `hubspot properties options-list --type contacts <name>` (fallback: read live records via `objects list` + `jq`).
- `associations list` has no batch `--from`, and returns one page (default 100) per call. Loop to gather IDs and page each call with `--limit`/`--after` until `.meta.next` is null, then batch the downstream `objects get` — otherwise a company with >100 associated contacts truncates silently.
- For >100 results, use the pagination loop in `bulk-operations/SKILL.md`.
From hubspot/agent-cli-skills at a8eea08, shown as plain text under its license: Apache-2.0 (permissive). The license text is in LICENSE.
View SKILL.md on GitHub at a8eea08Files
- SKILL.md8.1 KB · 12c6659889f6
- resources/
- contact-segmentation-filters.md4.4 KB · 975445cd3a75
2 files, 13 KB in total. Each file has a sha256 in the pin's manifest; the first 12 characters are shown.
Skill folder on GitHub at a8eea08Related in Marketing, sales and product
business-pulse
Generates a one-page business snapshot by pulling live data in parallel from connected accounting (QuickBooks, Xero, Zoho Books), payment (PayPal, Square…
by AnthropicOfficial publisher
Claude Code, Codex, Cursor +4 · about 2.8K tokens · pinned 6 days ago
canva-creator
This skill executes a complete marketing campaign from an approved content brief: builds a posting calendar, generates Canva designs for social posts, drafts…
by AnthropicOfficial publisher
Claude Code, Codex, Cursor +4 · about 4.7K tokens · pinned 6 days ago
crm-autopilot
This skill automatically maintains a CRM from emails, calendar events, and call transcripts without the owner opening it.
by AnthropicOfficial publisher
Claude Code, Codex, Cursor +4 · about 3.5K tokens · pinned 6 days ago
lead-triage
Scores inbound HubSpot leads using engagement, company fit, urgency, and recency signals to produce a ranked call list with talking points and proposed…
by AnthropicOfficial publisher
Claude Code, Codex, Cursor +3 · about 1.8K tokens · pinned 6 days ago
monday-brief
Compiles a weekly Monday briefing by pulling cash position, sales trends, and pipeline updates from connected business systems, combining them with scheduled…
by AnthropicOfficial publisher
Claude Code, Codex, Cursor +4 · about 2K tokens · pinned 6 days ago
marketing-ops
Sets up and operates marketing operations workflows in Airtable, including request intake, campaign orchestration, creative production, content calendars…
by AirtableOfficial publisher
Claude Code, Codex, Cursor +4 · about 7.4K tokens · pinned 6 days ago