Agent skill
tam-builder
Builds a company-level market file: every account in a defined market, counted, pulled, deduped across sources and outside lists, with a coverage estimate, TAM/SAM/SOM in accounts and dollars, and on request a fit score and Tier 1 to 3 cut to team capacity.
Filed under Positioning and messaging.
From scrapercity/gtm-skills · 31 skill entries · 0 · pushed 2026-11-02
What it does when it runs
Builds a company-level market file: every account in a defined market, counted, pulled, deduped across sources and outside lists, with a coverage estimate, TAM/SAM/SOM in accounts and dollars, and on request a fit score and Tier 1 to 3 cut to team capacity. Use when the user asks "how big is my market", "build our TAM", "every X in Y", "account universe", "which accounts should we target first", or "tier our accounts", and wants companies rather than people. Counts the Lead Database and Local Business Database, fills gaps with Google Maps or Store Leads, imports state license files, associations, exhibitor lists and similar registers with a found-in-N confidence tier. When the user wants the decision-makers at those companies with counts, tiers, cost and verified emails, use icp-list-builder; for buyers at a named account list, decision-maker-finder.
Automated analysis of the skill and the 10 files bundled beside it. A skill’s own description is written to be selected by an agent, so it describes the job and not the dependencies.
- Keys and connectors you must supply
- SCRAPERCITY_API_KEY
- Hosts it reaches
- alexberman.com
- api.fdic.gov
- app.scrapercity.com
- blog.google
- data.census.gov
- datatracker.ietf.org
- docs.github.com
- download.cms.gov
- emt.gartnerweb.com
- help.instantly.ai
- helpcenter.smartlead.ai
- leanb2bbook.com
- nces.ed.gov
- ncua.gov
- open.gsa.gov
- pe.usps.com
- publicsuffix.org
- scrapercity.com
- senders.yahooinc.com
- support.google.com
- techcommunity.microsoft.com
- www.acca.org
- www.ahrexpo.com
- www.aprildunford.com
- www.bls.gov
- www.bmj.com
- www.census.gov
- www.crexi.com
- www.crunchbase.com
- www.forentrepreneurs.com
- www.g2.com
- www.inc.com
- www.irs.gov
- www.linkedin.com
- www.montana.edu
- www.sec.gov
- www.tdlr.texas.gov
- www.thomasnet.com
- www.twilio.com
- www.zerobounce.net
- Tool permissions it declares
- No
allowed-toolsin the frontmatter. It only issues instructions, so there is nothing to bound. - Actions present in the files
- None. Instructions only.
Ask about tam-builder
Opens your assistant with this page's recorded context. Check the linked sources before relying on it.
Install it
View source on GitHub ↗git clone --depth 1 --filter=blob:none --sparse https://github.com/scrapercity/gtm-skills.git /tmp/gtm-skills git -C /tmp/gtm-skills sparse-checkout set "skills/list-building/tam-builder" mkdir -p ~/.claude/skills/tam-builder cp -R "/tmp/gtm-skills/skills/list-building/tam-builder/." ~/.claude/skills/tam-builder/
Picked up without a restart. A project skill of the same name is shadowed by your personal one. For one repository only, swap ~/.claude/skills for .claude/skills. Claude Code docs ↗
Or take the whole library
This repo ships a .claude-plugin manifest, so Claude Code can install all 31 skills at once. Plugin skills are invoked as /<plugin>:<skill>, so they never collide with your own.
/plugin marketplace add scrapercity/gtm-skills /plugin
The folder is the same in every client that implements the format — 46 of them — so if yours is not above, only the destination changes.
Before you install: this skill will not complete its job on a bare agent. It needs SCRAPERCITY_API_KEY, which you have to obtain separately.
The skill
Source on GitHub ↗Reproduced in full from scrapercity/gtm-skills/blob/46d446143690c8048b17817aecf36990ea6880e5/skills/list-building/tam-builder/SKILL.md, which is licensed MIT (skill frontmatter). 3,479 words, 25 headings.
TAM Builder
Overview
This skill produces an account universe: one row per distinct company in a defined market, pulled from every ScraperCity source that covers it, deduped, with a source column showing where each row came from. It adds a coverage estimate (the share of the market the file holds), a TAM, SAM and SOM in accounts and dollars, and, when the user wants to know where to start, a fit score and Tier 1 to 3 cut to the team's capacity.
It prevents three failures. The first is quoting a market size from one database count, which double counts people as companies and misses businesses the source does not hold. The second is merging three sources without a dedupe key, which inflates the market and sends the same business three emails. The third is a Tier 1 list built from a score nobody tested and sized beyond what the reps can work.
When to Use
- "How many HVAC contractors are there in Texas, and can I get all of them?"
- "Build our TAM for the board deck."
- "Every Shopify store selling pet supplies in the US."
- "Account universe for territory planning."
- "Which metros have the most targets per rep?"
- "Which 100 accounts should our AEs work first?" or "Tier our account list."
Use a different skill when:
| The user wants | Use |
|---|---|
| The people who decide at companies in a market, with company and contact counts, tiers, cost and verified emails | icp-list-builder |
| A send-ready file formatted for one sequencer | cold-email-list |
| Local businesses in one city with emails | local-business-list |
| Stores filtered by installed apps or tech | ecommerce-by-techstack |
| Buyers at the accounts this file produces | decision-maker-finder |
| A one-page brief on the Tier 1 accounts | account-researcher |
| Accounts picked by a recent event (funding, hiring, new leader) | signal-triggered-outbound |
| The TAM loaded into a CRM | crm-enricher |
Prerequisites
| Input | Why | Default if unknown |
|---|---|---|
| Market definition in one sentence (who, where, size) | Drives every filter | Ask; refuse to size "SMBs" |
| Market type: B2B companies, local businesses, or online stores | Picks sources | Infer from the definition, confirm |
| Geography | Location filters, metro splits | Ask |
| Annual contract value (ACV) | Dollar TAM | Ask; report accounts only if unknown |
| Territories or metros the team can serve | SAM | Same as TAM geography |
| Closed won and lost deals with domains, rep headcount | Scoring weights, tier sizes (only when tiers are asked for) | Assumed weights labeled as such; one Capacity line asks for headcount |
| ACV, gross margin and win rates per tier from the CRM | Spend ceilings per tier | Leave ceilings out |
| Plan | Databases need Growth or Scale | check_wallet |
Authoritative Foundations
| Source | Contribution |
|---|---|
| US Census Bureau, County Business Patterns (CBP) and Nonemployer Statistics (NES) | CBP counts establishments with paid employees by NAICS code and county (latest data year 2023, released June 2025); NES counts businesses with no paid employees (latest data year 2024). CBP is the benchmark for a market of firms with staff; CBP plus NES bounds a market that includes owner-only shops. Far below CBP means low coverage; far above means the definition is too loose. |
| Lincoln-Petersen and Chapman capture-recapture estimators | With two independent samples of one population, total size is about n1 times n2 divided by the overlap. Applied to two sources in one metro it estimates how many businesses neither source has. |
| April Dunford, best-fit customers | TAM is only useful when sized for the segment that values the product most. Define the market from the best-fit customer traits, then size it. |
| Public Suffix List | The registrable domain is the most stable company key across sources; shop.acme.co.uk and acme.co.uk are one company. |
| David Skok, SaaS Metrics 2.0 | Acquisition cost recovered within 12 months. Applied: first-year gross profit times the expected win rate per worked account caps what each tier may spend per account. |
references/list-quality-standard.md | Company schema, business name key, dedupe precedence, completeness score, source vocabulary. |
Detail in references/framework-notes.md.
Workflow
1. Write the market definition
One sentence with all four parts: business type, geography, size band, exclusions. Example: "Residential and light commercial HVAC contractors in Texas, any size, excluding supply houses and manufacturers." Map it to a NAICS code for the CBP benchmark (238220 Plumbing, Heating, and Air-Conditioning Contractors in this example). Recipes for common markets are in references/market-definition-recipes.md.
2. Pick sources by market type
| Market type | Primary source | Second source | Gap fill |
|---|---|---|---|
| Local or storefront businesses | query_local_business_database | query_lead_database owners, deduped to companies | scrape_maps, then scrape_yelp or scrape_angi for trades |
| B2B companies with staff | query_lead_database, one leader title per company | query_local_business_database for companies with a physical presence | Tech Stack Search (scrape_builtwith) for technology-defined markets |
| Online stores | scrape_store_leads | Ecommerce Database (REST) | Tech Stack Search for a platform or app |
3. Count every source before pulling
- Local Business Database: one call with
limit: 1, readpagination.total. That is a business count. - Lead Database:
pagination.totalcounts people, not companies. Use a one-per-company title set (Owner, Founder, CEO, President, General Manager), pull a sample (the worked example uses 500 rows), compute unique domains divided by rows, and multiply the total by that ratio for an estimated company count. - Store Leads: there is no free count. Run a
totalLeads: 100probe with the filters ($0.0039 per lead, $0.39) and read the rows to confirm the filters fit before a large job. - Maps: there is no count call. Estimate from metro size (see
references/coverage-and-dedupe-playbook.md) and cap withmaxCrawledPlacesPerSearch.
Put the counts in one table with the projected cost and show it to the user. Stop for a go-ahead if paid steps exceed $5.
4. Pull the databases with cursors
check_wallet, then page each database with after: "0" and limit: 100, passing pagination.next_after until null. Pulls above 100,000 new records per database per day split across days (by state or metro). Save each page to disk with source and source_detail.
5. Fill gaps
Decide where to scrape by comparing database counts per metro against population or against CBP per county. Metros with the lowest database count per 100k residents against the state average are gap candidates; the user picks the cutoff. For each:
scrape_mapswithsearchStringsArrayset to the category's keyword variants andlocationQueryset to each sub-city (metros split into sub-cities; lists inreferences/coverage-and-dedupe-playbook.md).- Before paying, read the
local_business_databaseblock a Maps run can return: it reports matches already in the database that the account does not have yet. Pull those from the database first. - Poll
check_run_statusuntil the run reaches SUCCEEDED, thendownload_results.
6. Normalize and dedupe
Normalize every row to the business schema (references/list-quality-standard.md section 2b). Then dedupe in three passes:
- Registrable
domain(blank for social-only websites). business_name_keypluspostal_code, thenbusiness_name_keyplusstreet, for rows with no domain.- Phone in E.164 as a final catch for rows that share neither.
When rows match, keep the most complete record by completeness score, fill empty fields from the other rows, and join every contributing source into source (for example local_db|maps).
6b. Import outside lists and tier confidence
When the market has a public register (banks, credit unions, nonprofits, federal contractors, public companies, schools), pull the register first: its count is the TAM denominator and the ScraperCity pulls supply people and emails (references/market-definition-recipes.md, Public registries). Add the outside lists that fit the market (the vertical table in the same file names one per market): state license files and association directories for trades, the CMS NPPES provider file for healthcare, exhibitor and sponsor lists for vendor markets, Inc. 5000 for growth segments, G2 categories and GitHub organizations for software, Crunchbase for funded companies, job boards for companies hiring a role. None is a ScraperCity source: tag rows source = user_upload with the list name in import_sources. Dedupe each list against itself, then against the file (domain, then phone, then name key + ZIP). Matched rows add to import_sources; new rows join only when they fit and carry a domain or phone; the rest go to a review file. Count found_in per account and label it: found in 3 or more sources High, 2 Medium, 1 Low. The labels name the count; a hand check of Low and High accounts on the user's file shows what each level means. Then write Source Yield: per source, accounts contributed, accounts no other source found, cost, and cost per unique account; a paid source whose unique accounts cost more than the Tier 3 spend ceiling (when the user's deal inputs set one) is dropped from the next refresh. Procedure, source table, overlap and yield reports: references/coverage-and-dedupe-playbook.md sections 9 to 12.
7. Estimate coverage
Pick 1-3 metros covered by two sources. Run Chapman's estimator on the overlap (formula and caveats in references/coverage-and-dedupe-playbook.md). Report observed accounts, estimated true count, and coverage percentage. Compare the statewide deduped count against the CBP establishment count for the NAICS code (data.census.gov, County Business Patterns filtered to the NAICS code and state; the Census API needs a free key), and add the NES count when the market includes owner-only businesses.
8. Size TAM, SAM, SOM
| Layer | Definition used here |
|---|---|
| TAM | Every deduped account in the market definition times ACV |
| SAM | Accounts the team can serve (territories, languages, size band) times ACV |
| SOM | A 12-month share of SAM the user commits to, stated as an assumption |
9. Score and tier (when asked)
Follow references/account-scoring-and-tiers.md: hard exclusions first, score only columns filled on at least the share of SAM rows the user sets (report every column's fill rate), points from win-rate lift (10 x log2 of lift, capped at plus or minus 10) when closed deals join the file, tier sizes from rep capacity, a spend ceiling per account only when the user supplies ACV, gross margin and win rates per tier (written on a "Deal inputs (from you):" line; otherwise the column is left out), and a backtest on current customers (Tier 1 and 2 must hold a larger share of customers than of SAM, a concentration above 1.0x, or the higher bar the user sets). Fit sets the tier; three things move an account up one tier for the next send cycle (Alex Berman spaces cycles 30 to 60 days apart, alexberman.com, October 2026): a dated trigger, first-party engagement from the user's CRM or marketing tool (pricing page visit, webinar, a past reply), and a warm path (a former customer champion now works there, a TeamLink connection). Write the Account Tiers section with its Capacity and Backtest lines, and book the quarter-end read: meetings per 100 accounts worked, by tier.
10. Deliver
Deliver the CSV and the report in templates/output-template.md, including Source Overlap and Source Yield. Run scripts/check-output.py.
ScraperCity Implementation
| Step | Tool | Price (catalog) |
|---|---|---|
| Balance and plan | check_wallet | Free |
| Local business count and pull | query_local_business_database | Included on Growth and Scale, 100,000 new businesses a day |
| B2B count and pull | query_lead_database | Included on Growth and Scale, 100,000 new leads a day |
| Maps gap fill | scrape_maps | $0.0099 per business |
| Yelp gap fill | scrape_yelp | $0.0099 per result |
| Home services gap fill | scrape_angi | $0.0099 per listing |
| Online stores | scrape_store_leads | $0.0039 per lead |
| Technology-defined markets | scrape_builtwith (Tech Stack Search) | $4.99 per technology |
| Runs | check_run_status, download_results, list_runs | Free |
Calls for the HVAC example
Local Business Database count:
{"keyword": ["hvac contractor", "air conditioning contractor", "heating contractor"],
"location": ["Texas"], "notCategory": ["Appliance store", "HVAC supply store"], "limit": 1}
Pull: same body with "limit": 100, "after": "0", then each pagination.next_after. Read searched_as in the first response to confirm Texas was read as the state.
Lead Database company proxy:
{"title": "Owner, President, CEO, Founder, General Manager",
"notTitle": "assistant, former, sales, technician",
"keywords": ["hvac"], "companyState": ["Texas"], "limit": 100, "after": "0"}
Maps gap fill for one metro:
{"searchStringsArray": ["hvac contractor", "air conditioning repair", "heating contractor"],
"locationQuery": "Pasadena, TX", "maxCrawledPlacesPerSearch": 50}
maxCrawledPlacesPerSearch applies per search term, so this call can return up to 150 businesses (3 terms x 50) and cost up to $1.49. Each sub-city is a separate run; keep a list of run ids. Store Leads for an ecommerce TAM: {"platform": "shopify", "countryCode": "US", "category": "pet supplies", "totalLeads": 1000, "offset": 0}, then raise offset by totalLeads each call or send back nextOffset.
Worked cost estimate
| Item | Units | Unit price | Cost |
|---|---|---|---|
| Local Business Database pull | 9,840 businesses | Included in Growth | $0.00 |
| Lead Database pull | 6,215 leads | Included in Growth | $0.00 |
| Google Maps gap fill, 30 sub-cities x 3 terms x 50 cap (4,500 max, $44.55 ceiling) | 3,600 businesses returned | $0.0099 | $35.64 |
| Total paid usage | $35.64 |
The two database pulls use 9.8% and 6.2% of their daily allowances. $35.64 exceeds $5, so show the table and wait for approval before the Maps runs.
Output Format
tam-[market]-[date].csv: one row per account, business schema from the quality standard plussource,source_detail,import_sources,found_in,confidence,completeness_score,metro,in_sam(true or false).tam-review-[market]-[date].csv: outside-list rows held for review, with a reason.- A report from
templates/output-template.md: market definition, source counts, pull and dedupe funnel, source mix, source overlap, source yield (unique accounts and cost per unique account per source, with a keep or drop call for the next refresh), coverage estimate, TAM/SAM/SOM, metro breakdown, account tiers when asked, cost, output schema, next steps. - When tiers were asked for:
fit_score,tierandtier_reasoncolumns in the CSV.
What the reader receives is the deliverable only: no internal file paths, reference section numbers, tool ids or skill names (name the product, such as Lead Database or Email Validator, and describe the next action instead of naming a skill); each figure stated once; every outside number with its source and date on first mention; no spend ceiling without the user's deal inputs; no invented team size (one Capacity line asks for headcount); no table of checks that were not run (one "Not checked:" line instead); no legal commentary. Next Steps is a table with Step, Owner, Date and Done when.
Quality Check
- Market definition names business type, geography, size band and exclusions.
- Every source was counted before pulling; counts and cost shown before paid runs.
- Lead Database totals converted from people to companies with a sampled ratio.
- Funnel adds up from raw rows to final accounts with a reason on each drop.
- Source mix rows sum to the final account count.
- Every row has a
sourcevalue from the controlled vocabulary. - Source Overlap: found-in-N rows sum to the final count, confidence matches N, and each outside list reconciles (rows = matched + new + held).
- Coverage estimate shows observed, estimated and percentage, with its caveat.
- TAM, SAM and SOM each show accounts, ACV and dollars, and SOM states its assumption.
- Source Yield shows unique accounts per source, never more than the source contributed, with a keep or drop decision.
- If tiers are included: hard exclusions listed, tier counts sum to SAM, Tier 1 fits the stated capacity, and the Backtest line shows a concentration above 1.0x.
-
scripts/check-output.py report.mdprints PASS.
Common Pitfalls
| Mistake | Why it fails | Fix |
|---|---|---|
Quoting pagination.total from the Lead Database as a company count | It counts people; a 40-person firm can appear 40 times | One leader title per company, sample the domain ratio, dedupe by domain. |
| Deduping only by name | "ABC Heating" and "ABC Heating & Air LLC" survive as two | Domain first, then name key plus ZIP, then phone. |
| Deduping only by domain | Franchise locations sharing one domain collapse into one row | For local markets keep one row per location; use phone as the location key. |
| One Maps search across a metro | Maps searches return a limited set per query; outer suburbs vanish | Split into sub-cities and keyword variants. |
| Paying for Maps rows the database already has | Double spend | Pull the database first; read the local_business_database block in the Maps response. |
| Treating capture-recapture as exact | Both sources favor businesses with an online presence, so the population estimate is a floor and the coverage share is a ceiling | Say so in the report; cross-check with CBP and a registry file. |
| A TAM in dollars with no ACV source | Board decks repeat it | State ACV and where it came from. |
| Adding every outside-list row to the TAM | License files hold individuals and lapsed licenses; exhibitor lists hold vendors | New rows join only with fit plus a domain or phone; the rest go to review. |
| Quoting the TAM without its Low share | A file heavy with single-source accounts can overstate the market | Report found-in-N next to every TAM count. |
| Scoring on a column filled for half the rows | Data-rich accounts float to Tier 1 whatever their fit | Report fill rates; score only columns at or above the user's minimum fill. |
| Cutting Tier 1 by score alone | 600 Tier 1 accounts for two reps get Tier 3 treatment | Size tiers from capacity, then read the cutoff. |
| Scoring intent and engagement into the fit score | A pricing-page visit at a misfit account outranks a perfect-fit account; the score decays weekly | Fit sets the tier; triggers, engagement and warm paths move it up one tier for the next send cycle. |
| Never reading the tiers after launch | A Tier 1 that books no more meetings than Tier 2 costs AE time for nothing | Quarter-end: meetings per 100 accounts worked by tier; Tier 1 at or below Tier 2 means re-weight. |
| Sizing a bank, nonprofit or contractor market from a database count | A public register lists every member | Pull the register first and report coverage against it. |
| Using a score nobody tested | The ranking reflects opinions about fit | Backtest on current customers; at or below 1.0x concentration, re-weight. |
| Buying a source again because it was in last month's run | Paid rows that only duplicate the databases | Read Source Yield; drop a paid source whose unique accounts cost more than the tier ceiling. |
Execution Artifacts
| File | Open it when |
|---|---|
references/framework-notes.md | You need the reasoning or source behind a rule, or the routing table. |
references/market-definition-recipes.md | Writing the market definition and the per-source filters (27 markets), and the public registers (FDIC, NCUA, IRS, SAM.gov, EDGAR, NCES) that count regulated and registered markets. |
references/coverage-and-dedupe-playbook.md | Gap-fill decisions, metro sub-city splits, capture-recapture, dedupe passes, merge rules, outside-list imports, found-in-N confidence, the source-overlap and source-yield reports. |
references/account-scoring-and-tiers.md | Step 9: hard exclusions, scorable columns, lift points, capacity-based tiers, spend ceilings, the customer backtest. |
references/list-quality-standard.md | Schema, normalization, dedupe precedence, source vocabulary (shared). |
references/scrapercity-catalog.md | Prices and parameters (shared). |
references/scrapercity-platform.md | Database rules and daily allowances (shared). |
templates/output-template.md | Writing the report. |
examples/worked-example.md | A finished TAM for HVAC contractors in Texas. |
scripts/check-output.py | Final gate on the report. |
Related Skills
icp-list-builderfor a contact list from one slice of this TAM.local-business-listfor one city with validated emails.ecommerce-by-techstackfor online store markets by app or technology.decision-maker-finderto add buyers to the accounts, starting with Tier 1.account-researcherfor a brief on each Tier 1 account.signal-triggered-outboundto find the triggers that lift an account one tier.crm-enricherto load the account universe into HubSpot or Pipedrive.scrapercity-local-business-databaseandscrapercity-lead-databasefor every parameter.
Files bundled with it
These load only when the skill asks for them, so they cost nothing until it runs.
Other skills for the same job
Different authors, same problem. Matched on the words in the skill name, across every library in the catalogue except this one.
- build-tam by getaero-io · 72
- tam-scoring by Cold-IQ · 3
- tam-calculator by ekatasingh1107 · 2
- tam-sizing by noahatcheckpoint · 1
- tam-builder by edupegoretti · 0
- tam-map by richapiai · 0
- tam-data-cost-estimate by jurjen-gtm-engineer · 0
Need help setting it up?
This page tells you what tam-builder does and what it needs. Cheetah builds the agent setup it runs inside: data, CRM, sequencing and the guardrails.
Book a call →The directory stays free. There is nothing gated behind this.