Systems Lab

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.

activeNeeds a keyInstructions only3,479 words

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-tools in 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.

Is this safe to install?ClaudeChatGPT
Adapt it to my stackClaudeChatGPT
What else do I need for it to workClaudeChatGPT
Rather ask a human? Talk to Cheetah
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.

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 wantsUse
The people who decide at companies in a market, with company and contact counts, tiers, cost and verified emailsicp-list-builder
A send-ready file formatted for one sequencercold-email-list
Local businesses in one city with emailslocal-business-list
Stores filtered by installed apps or techecommerce-by-techstack
Buyers at the accounts this file producesdecision-maker-finder
A one-page brief on the Tier 1 accountsaccount-researcher
Accounts picked by a recent event (funding, hiring, new leader)signal-triggered-outbound
The TAM loaded into a CRMcrm-enricher

Prerequisites

InputWhyDefault if unknown
Market definition in one sentence (who, where, size)Drives every filterAsk; refuse to size "SMBs"
Market type: B2B companies, local businesses, or online storesPicks sourcesInfer from the definition, confirm
GeographyLocation filters, metro splitsAsk
Annual contract value (ACV)Dollar TAMAsk; report accounts only if unknown
Territories or metros the team can serveSAMSame as TAM geography
Closed won and lost deals with domains, rep headcountScoring 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 CRMSpend ceilings per tierLeave ceilings out
PlanDatabases need Growth or Scalecheck_wallet

Authoritative Foundations

SourceContribution
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 estimatorsWith 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 customersTAM 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 ListThe 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.0Acquisition 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.mdCompany 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 typePrimary sourceSecond sourceGap fill
Local or storefront businessesquery_local_business_databasequery_lead_database owners, deduped to companiesscrape_maps, then scrape_yelp or scrape_angi for trades
B2B companies with staffquery_lead_database, one leader title per companyquery_local_business_database for companies with a physical presenceTech Stack Search (scrape_builtwith) for technology-defined markets
Online storesscrape_store_leadsEcommerce Database (REST)Tech Stack Search for a platform or app

3. Count every source before pulling

  • Local Business Database: one call with limit: 1, read pagination.total. That is a business count.
  • Lead Database: pagination.total counts 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: 100 probe 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 with maxCrawledPlacesPerSearch.

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_maps with searchStringsArray set to the category's keyword variants and locationQuery set to each sub-city (metros split into sub-cities; lists in references/coverage-and-dedupe-playbook.md).
  • Before paying, read the local_business_database block 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_status until the run reaches SUCCEEDED, then download_results.

6. Normalize and dedupe

Normalize every row to the business schema (references/list-quality-standard.md section 2b). Then dedupe in three passes:

  1. Registrable domain (blank for social-only websites).
  2. business_name_key plus postal_code, then business_name_key plus street, for rows with no domain.
  3. 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

LayerDefinition used here
TAMEvery deduped account in the market definition times ACV
SAMAccounts the team can serve (territories, languages, size band) times ACV
SOMA 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

StepToolPrice (catalog)
Balance and plancheck_walletFree
Local business count and pullquery_local_business_databaseIncluded on Growth and Scale, 100,000 new businesses a day
B2B count and pullquery_lead_databaseIncluded on Growth and Scale, 100,000 new leads a day
Maps gap fillscrape_maps$0.0099 per business
Yelp gap fillscrape_yelp$0.0099 per result
Home services gap fillscrape_angi$0.0099 per listing
Online storesscrape_store_leads$0.0039 per lead
Technology-defined marketsscrape_builtwith (Tech Stack Search)$4.99 per technology
Runscheck_run_status, download_results, list_runsFree

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

ItemUnitsUnit priceCost
Local Business Database pull9,840 businessesIncluded in Growth$0.00
Lead Database pull6,215 leadsIncluded 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

  1. tam-[market]-[date].csv: one row per account, business schema from the quality standard plus source, source_detail, import_sources, found_in, confidence, completeness_score, metro, in_sam (true or false).
  2. tam-review-[market]-[date].csv: outside-list rows held for review, with a reason.
  3. 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.
  4. When tiers were asked for: fit_score, tier and tier_reason columns 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 source value 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.md prints PASS.

Common Pitfalls

MistakeWhy it failsFix
Quoting pagination.total from the Lead Database as a company countIt counts people; a 40-person firm can appear 40 timesOne leader title per company, sample the domain ratio, dedupe by domain.
Deduping only by name"ABC Heating" and "ABC Heating & Air LLC" survive as twoDomain first, then name key plus ZIP, then phone.
Deduping only by domainFranchise locations sharing one domain collapse into one rowFor local markets keep one row per location; use phone as the location key.
One Maps search across a metroMaps searches return a limited set per query; outer suburbs vanishSplit into sub-cities and keyword variants.
Paying for Maps rows the database already hasDouble spendPull the database first; read the local_business_database block in the Maps response.
Treating capture-recapture as exactBoth sources favor businesses with an online presence, so the population estimate is a floor and the coverage share is a ceilingSay so in the report; cross-check with CBP and a registry file.
A TAM in dollars with no ACV sourceBoard decks repeat itState ACV and where it came from.
Adding every outside-list row to the TAMLicense files hold individuals and lapsed licenses; exhibitor lists hold vendorsNew rows join only with fit plus a domain or phone; the rest go to review.
Quoting the TAM without its Low shareA file heavy with single-source accounts can overstate the marketReport found-in-N next to every TAM count.
Scoring on a column filled for half the rowsData-rich accounts float to Tier 1 whatever their fitReport fill rates; score only columns at or above the user's minimum fill.
Cutting Tier 1 by score alone600 Tier 1 accounts for two reps get Tier 3 treatmentSize tiers from capacity, then read the cutoff.
Scoring intent and engagement into the fit scoreA pricing-page visit at a misfit account outranks a perfect-fit account; the score decays weeklyFit sets the tier; triggers, engagement and warm paths move it up one tier for the next send cycle.
Never reading the tiers after launchA Tier 1 that books no more meetings than Tier 2 costs AE time for nothingQuarter-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 countA public register lists every memberPull the register first and report coverage against it.
Using a score nobody testedThe ranking reflects opinions about fitBacktest on current customers; at or below 1.0x concentration, re-weight.
Buying a source again because it was in last month's runPaid rows that only duplicate the databasesRead Source Yield; drop a paid source whose unique accounts cost more than the tier ceiling.

Execution Artifacts

FileOpen it when
references/framework-notes.mdYou need the reasoning or source behind a rule, or the routing table.
references/market-definition-recipes.mdWriting 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.mdGap-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.mdStep 9: hard exclusions, scorable columns, lift points, capacity-based tiers, spend ceilings, the customer backtest.
references/list-quality-standard.mdSchema, normalization, dedupe precedence, source vocabulary (shared).
references/scrapercity-catalog.mdPrices and parameters (shared).
references/scrapercity-platform.mdDatabase rules and daily allowances (shared).
templates/output-template.mdWriting the report.
examples/worked-example.mdA finished TAM for HVAC contractors in Texas.
scripts/check-output.pyFinal gate on the report.

Related Skills

  • icp-list-builder for a contact list from one slice of this TAM.
  • local-business-list for one city with validated emails.
  • ecommerce-by-techstack for online store markets by app or technology.
  • decision-maker-finder to add buyers to the accounts, starting with Tier 1.
  • account-researcher for a brief on each Tier 1 account.
  • signal-triggered-outbound to find the triggers that lift an account one tier.
  • crm-enricher to load the account universe into HubSpot or Pipedrive.
  • scrapercity-local-business-database and scrapercity-lead-database for 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.

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.

Build my GTM engine

Tell us what you want to improve. Fedor reviews the workflow and replies by email when there is a useful fit.

Fedor reviews every request personally. If there is a useful fit, he will reply by email.