Tam builder
Build and maintain a scored Total Addressable Market (TAM) using Apollo Company Search.
How to use it
- Hit Copy the whole skill.
- Claude: ⋯ → Download .md, then Customize → Skills → Add → Upload skill.
ChatGPT: make a Project and paste it into Instructions.
Neither? Paste it at the top of a new chat — it works for that chat. - Describe your job in plain words. The AI follows the skill from there.
npx degit gooseworks-ai/goose-skills/skills/lead-generation/capabilities/tam-builder#main ~/.claude/skills/tam-builderFor one project only, change the path to .claude/skills/tam-builder.
Not working?
- Check which app you pasted it into — the steps above name the right one.
- Some skills need the paid tier of Claude or ChatGPT.
Paste into Claude, ChatGPT or Cursor.
Show the full text157 lines
TAM Builder
Build and maintain a scored Total Addressable Market. Uses Apollo Company Search to discover companies, scores ICP fit (0-100), assigns tiers (1/2/3), and auto-builds a persona watchlist for Tier 1-2 companies using Apollo People Search (free).
Three modes:
- build — First-time TAM construction from Apollo search
- refresh — Update existing TAM: re-score, detect tier changes, deprecate stale companies
- status — Read-only report of current TAM state
Prerequisites
Apollo API Key
Add to .env:
APOLLO_API_KEY=your-api-key-here
That's it — one env var.
Config Format
Create a JSON config per client/segment:
{
"client_name": "happy-robot",
"tam_config_name": "voice-ai-midmarket",
"company_filters": {
"organization_num_employees_ranges": ["51,200", "201,500", "501,1000"],
"q_organization_keyword_tags": ["call center", "contact center"],
"organization_locations": ["United States"]
},
"scoring": {
"weights": {
"employee_count_fit": 30,
"industry_fit": 25,
"funding_stage_fit": 20,
"geo_fit": 15,
"keyword_match": 10
},
"tier_thresholds": { "tier_1_min_score": 75, "tier_2_min_score": 50 },
"target_industries": ["Telecommunications", "Customer Service"],
"target_employee_ranges": [[51, 200], [201, 500], [501, 1000]],
"target_funding_stages": ["Series A", "Series B", "Series C"],
"target_geos": ["United States"]
},
"watchlist": {
"enabled": true,
"personas_per_company": 3,
"person_filters": {
"person_titles": ["VP of Operations", "Head of Customer Service"],
"person_seniority": ["vp", "director", "c_suite"]
},
"tiers_to_watch": [1, 2]
},
"mode": "standard",
"max_pages": 50
}
Approval Gate
CRITICAL: Never export results without explicit user approval.
Required flow:
- Search Apollo for a small sample first (~100 companies)
- Score them and present: tier distribution, example Tier 1/2 companies, scoring sanity check
- Get explicit user approval before running the full build
- Only then run the full search + score + export
Pipeline: Build Mode
Step 0: --preview → total count + cost estimate (no DB writes)
Step 1: --sample --test → search 1 page, score in-memory, show results (no DB writes)
Step 2: User reviews sample → approves, adjusts filters, or caps scope
Step 3: Full build → Apollo Company Search → Export to CSV → Score → Tier → Watchlist
Phase details (Step 3 only — after user approval):
Phase 1: Apollo Company Search → Upsert raw companies → Score ICP fit → Assign tiers
Phase 2: (skipped in build mode — no prior data to deprecate)
Phase 3: Persona Watchlist — pull 2-3 personas per Tier 1-2 company (free)
Pipeline: Refresh Mode
Phase 1: Apollo Company Search → Upsert/update companies → Re-score → Detect tier changes
Phase 2: Deprecation — companies missing 2+ consecutive refreshes get deprecated
Phase 3: Persona Watchlist — pull personas for new/promoted Tier 1-2 companies,
disqualify personas at deprecated companies
ICP Scoring (0-100)
Pure function, no API calls. Weighted scoring across 5 dimensions from config:
employee_count_fit— headcount in target ranges?industry_fit— industry matches targets?funding_stage_fit— funding stage in targets?geo_fit— HQ location in target geos?keyword_match— org keywords overlap config keywords?
Score thresholds (configurable): >=75 = Tier 1, >=50 = Tier 2, else Tier 3.
Deprecation Rules (refresh only)
- First miss (not returned by search):
metadata.refresh_miss_count = 1, keep active - Second consecutive miss:
tam_status = 'deprecated' - Employee count drops to 0: immediate deprecation
- Companies with
tam_status = 'converted'are always exempt
Watchlist — Persona Sync
| Scenario | Behavior |
|---|---|
| New Tier 1-2 company | Pull 2-3 personas immediately |
| Company promoted Tier 3→2 | Pull personas during refresh |
| Company deprecated | Disqualify monitoring personas |
| Company demoted Tier 1→3 | Keep existing personas, stop refreshing |
Mode Caps
| Parameter | Test | Standard | Full |
|---|---|---|---|
| Max pages | 1 | 50 | 200 |
| Max companies | 100 | 5,000 | 20,000 |
Apollo API Reference
- Company Search:
POST https://api.apollo.io/api/v1/mixed_companies/search— Returns matching companies in theaccountsarray (notorganizations). Fields:name,primary_domain,estimated_num_employees,industry,keywords,city,state,country. - People Search:
POST https://api.apollo.io/api/v1/mixed_people/search— $0.01 flat per call (cheapest people search). Returns matching people in thepeoplearray. Fields:first_name,title,organization.name. Email/LinkedIn obfuscated on free tier. - People Match (enrich):
POST https://api.apollo.io/api/v1/people/match— ~$0.03 per match. Reveals email, phone, LinkedIn URL, full name. - Auth:
x-api-key: {APOLLO_API_KEY}header on all requests - Pagination:
per_page(max 100),page(1-indexed).pagination.total_entriesgives total count.
Output
Save results as CSV to the current working directory:
tam-companies-{date}.csv— All discovered companies with ICP score and tiertam-personas-{date}.csv— Persona watchlist for Tier 1-2 companies (from People Search)
| 1 | |
| 2 | name tam-builder |
| 3 | description > |
| 4 | Build and maintain a scored Total Addressable Market (TAM) using Apollo Company Search. |
| 5 | Discovers companies matching ICP, scores fit (0-100), assigns tiers (1/2/3), and |
| 6 | auto-builds a persona watchlist for Tier 1-2 companies using Apollo People Search (free). |
| 7 | Outputs to CSV. |
| 8 | tags [lead-generation] |
| 9 | |
| 10 | |
| 11 | # TAM Builder |
| 12 | |
| 13 | Build and maintain a scored Total Addressable Market. Uses Apollo Company Search to discover companies, scores ICP fit (0-100), assigns tiers (1/2/3), and auto-builds a persona watchlist for Tier 1-2 companies using Apollo People Search (free). |
| 14 | |
| 15 | **Three modes:** |
| 16 | **build** — First-time TAM construction from Apollo search |
| 17 | **refresh** — Update existing TAM: re-score, detect tier changes, deprecate stale companies |
| 18 | **status** — Read-only report of current TAM state |
| 19 | |
| 20 | ## Prerequisites |
| 21 | |
| 22 | ### Apollo API Key |
| 23 | Add to `.env`: |
| 24 | |
| 25 | APOLLO_API_KEY=your-api-key-here |
| 26 | |
| 27 | |
| 28 | That's it — one env var. |
| 29 | |
| 30 | ## Config Format |
| 31 | |
| 32 | Create a JSON config per client/segment: |
| 33 | |
| 34 | |
| 35 | { |
| 36 | "client_name": "happy-robot", |
| 37 | "tam_config_name": "voice-ai-midmarket", |
| 38 | |
| 39 | "company_filters": { |
| 40 | "organization_num_employees_ranges": ["51,200", "201,500", "501,1000"], |
| 41 | "q_organization_keyword_tags": ["call center", "contact center"], |
| 42 | "organization_locations": ["United States"] |
| 43 | }, |
| 44 | |
| 45 | "scoring": { |
| 46 | "weights": { |
| 47 | "employee_count_fit": 30, |
| 48 | "industry_fit": 25, |
| 49 | "funding_stage_fit": 20, |
| 50 | "geo_fit": 15, |
| 51 | "keyword_match": 10 |
| 52 | }, |
| 53 | "tier_thresholds": { "tier_1_min_score": 75, "tier_2_min_score": 50 }, |
| 54 | "target_industries": ["Telecommunications", "Customer Service"], |
| 55 | "target_employee_ranges": [[51, 200], [201, 500], [501, 1000]], |
| 56 | "target_funding_stages": ["Series A", "Series B", "Series C"], |
| 57 | "target_geos": ["United States"] |
| 58 | }, |
| 59 | |
| 60 | "watchlist": { |
| 61 | "enabled": true, |
| 62 | "personas_per_company": 3, |
| 63 | "person_filters": { |
| 64 | "person_titles": ["VP of Operations", "Head of Customer Service"], |
| 65 | "person_seniority": ["vp", "director", "c_suite"] |
| 66 | }, |
| 67 | "tiers_to_watch": [1, 2] |
| 68 | }, |
| 69 | |
| 70 | "mode": "standard", |
| 71 | "max_pages": 50 |
| 72 | } |
| 73 | |
| 74 | |
| 75 | ## Approval Gate |
| 76 | |
| 77 | **CRITICAL: Never export results without explicit user approval.** |
| 78 | |
| 79 | **Required flow:** |
| 80 | Search Apollo for a small sample first (~100 companies) |
| 81 | Score them and present: tier distribution, example Tier 1/2 companies, scoring sanity check |
| 82 | **Get explicit user approval** before running the full build |
| 83 | Only then run the full search + score + export |
| 84 | |
| 85 | ## Pipeline: Build Mode |
| 86 | |
| 87 | |
| 88 | Step 0: --preview → total count + cost estimate (no DB writes) |
| 89 | Step 1: --sample --test → search 1 page, score in-memory, show results (no DB writes) |
| 90 | Step 2: User reviews sample → approves, adjusts filters, or caps scope |
| 91 | Step 3: Full build → Apollo Company Search → Export to CSV → Score → Tier → Watchlist |
| 92 | |
| 93 | |
| 94 | Phase details (Step 3 only — after user approval): |
| 95 | |
| 96 | Phase 1: Apollo Company Search → Upsert raw companies → Score ICP fit → Assign tiers |
| 97 | Phase 2: (skipped in build mode — no prior data to deprecate) |
| 98 | Phase 3: Persona Watchlist — pull 2-3 personas per Tier 1-2 company (free) |
| 99 | |
| 100 | |
| 101 | ## Pipeline: Refresh Mode |
| 102 | |
| 103 | |
| 104 | Phase 1: Apollo Company Search → Upsert/update companies → Re-score → Detect tier changes |
| 105 | Phase 2: Deprecation — companies missing 2+ consecutive refreshes get deprecated |
| 106 | Phase 3: Persona Watchlist — pull personas for new/promoted Tier 1-2 companies, |
| 107 | disqualify personas at deprecated companies |
| 108 | |
| 109 | |
| 110 | ## ICP Scoring (0-100) |
| 111 | |
| 112 | Pure function, no API calls. Weighted scoring across 5 dimensions from config: |
| 113 | `employee_count_fit` — headcount in target ranges? |
| 114 | `industry_fit` — industry matches targets? |
| 115 | `funding_stage_fit` — funding stage in targets? |
| 116 | `geo_fit` — HQ location in target geos? |
| 117 | `keyword_match` — org keywords overlap config keywords? |
| 118 | |
| 119 | Score thresholds (configurable): >=75 = Tier 1, >=50 = Tier 2, else Tier 3. |
| 120 | |
| 121 | ## Deprecation Rules (refresh only) |
| 122 | |
| 123 | First miss (not returned by search): `metadata.refresh_miss_count = 1`, keep active |
| 124 | Second consecutive miss: `tam_status = 'deprecated'` |
| 125 | Employee count drops to 0: immediate deprecation |
| 126 | Companies with `tam_status = 'converted'` are always exempt |
| 127 | |
| 128 | ## Watchlist — Persona Sync |
| 129 | |
| 130 | | Scenario | Behavior | |
| 131 | |----------|----------| |
| 132 | | New Tier 1-2 company | Pull 2-3 personas immediately | |
| 133 | | Company promoted Tier 3→2 | Pull personas during refresh | |
| 134 | | Company deprecated | Disqualify monitoring personas | |
| 135 | | Company demoted Tier 1→3 | Keep existing personas, stop refreshing | |
| 136 | |
| 137 | ## Mode Caps |
| 138 | |
| 139 | | Parameter | Test | Standard | Full | |
| 140 | |-----------|------|----------|------| |
| 141 | | Max pages | 1 | 50 | 200 | |
| 142 | | Max companies | 100 | 5,000 | 20,000 | |
| 143 | |
| 144 | ## Apollo API Reference |
| 145 | |
| 146 | **Company Search:** `POST https://api.apollo.io/api/v1/mixed_companies/search` — Returns matching companies in the `accounts` array (not `organizations`). Fields: `name`, `primary_domain`, `estimated_num_employees`, `industry`, `keywords`, `city`, `state`, `country`. |
| 147 | **People Search:** `POST https://api.apollo.io/api/v1/mixed_people/search` — **$0.01 flat per call** (cheapest people search). Returns matching people in the `people` array. Fields: `first_name`, `title`, `organization.name`. Email/LinkedIn obfuscated on free tier. |
| 148 | **People Match (enrich):** `POST https://api.apollo.io/api/v1/people/match` — ~$0.03 per match. Reveals email, phone, LinkedIn URL, full name. |
| 149 | **Auth:** `x-api-key: {APOLLO_API_KEY}` header on all requests |
| 150 | **Pagination:** `per_page` (max 100), `page` (1-indexed). `pagination.total_entries` gives total count. |
| 151 | |
| 152 | ## Output |
| 153 | |
| 154 | Save results as CSV to the current working directory: |
| 155 | `tam-companies-{date}.csv` — All discovered companies with ICP score and tier |
| 156 | `tam-personas-{date}.csv` — Persona watchlist for Tier 1-2 companies (from People Search) |
| 157 |