Your GTM belongs in gitRegister
Cookbooks
Fundamentals

TAM building

Build your total addressable market (TAM) list and stand it up as a deployed model in Cargo: your ICP, read from your context (or drafted from your website and customer stories), becomes an AI Ark company search setting industries, company size and countries, sized for free before it bills, and lands as one model other pipelines read.

Installation
Set up the tam-building cookbook in this project. 1. If the Cargo CLI is not installed yet, follow every step in https://api.getcargo.io/INSTALL.md 2. From the Cargo project, run: cargo-ai cdk add cookbook/tam-building 3. Then follow .claude/skills/tam-building/SKILL.md. Stop for my approval before any paid call, and stop at "cargo-ai project plan" before deploying anything.
Paste it into Claude Code, Cursor, Codex, Gemini CLI, Devin or Replicas.

Say this to your agent

Source every B2B software company in the US and the UK with 20 to 500 employees from AI Ark, using the ICP in our context repo.

Illustrative output #

Fictional records, to show the shape of what comes back.

CriterionConfirmedFrom
Industriessoftware development, computer and network securityicp.md: “Industry: …”
Company size20 to 500 employeesicp.md: “Headcount: 20 to 500”
CountriesUnited States, United Kingdomthe prompt
ResultValue
Counted pool4,812 companies
Landed in tam_companies500 of 500 (limit)
By countryUnited States 71%, United Kingdom 29%
By size band20-49: 38%, 50-199: 44%, 200-500: 18%
No domain and no LinkedIn6 rows

The report closes on one recommended opening: a CRM coverage analysis, since the workspace already holds HubSpot, to see how many of the 500 are already there.

What you will be asked #

InputWhy
icpLooked upIt is the one thing that cannot be computed. Everything else here is arithmetic on top of it
market_minimumLooked upThese three are the floor of any TAM. Missing one sources a market with no edge in that dimension: every industry, every size, or the whole world, billed per record
sourcing_filterLooked upA flat map is ignored silently and a guessed enum member matches nothing. Either way you source a market nobody described
pool_sizeLooked upIt is the only number that turns “is this filter right” into a question with an answer, and it costs nothing to ask
limitLooked upfetchCompaniesbills per returned record, so this is the invoice. Below the counted pool,limit` also decides which slice you get

Done when #

  • the ICP came from the context repo, or was researched and approved, and is written to context/icp.md
  • industries, company size and countries were proposed from icp.md (or suggested and marked), confirmed by the operator, and all three are in the deployed filter
  • countCompanies was run for the filter actually deployed, and its number is recorded before any sourcing run
  • the sync landed rows, and the row count is at or under limit
  • the report splits the landed rows by industry, size band and country, and states actual credits against the estimate
  • the report ended on the openings, with one recommended
  • node --import tsx evals/contract.mjs passes against the adapted resources

What it costs #

Read this before pointing the skill at a market-sized filter.

Counting is free, and it is the cheapest insurance in this skill: aiArk.countCompanies takes the same filter groups as the search and returns the pool size without billing. Run it for every candidate filter, every time you widen one.

Research bills per call, and only runs when no ICP is written down. Reading the website and customer stories is one extraction per batch of pages, and each customer’s LinkedIn page is one enrichment. Fetch the live prices with cargo-ai connection integration get <slug> for each integration you use, and keep the customer list to the ones named on the site.

Sourcing is the spend, and it is per returned record, not per call. Immediately before every preview, run cargo-ai connection integration get aiArk and read the current fetchCompanies entry under credits.costs. Record the CLI version, the lookup time, and the unit price. The estimate is limit * unit price, which is why limit is the only control that matters: to spend less, source less.

The sourced model deliberately carries no schedule. See refresh-cadence above for what a recurring source really costs.

To build a total addressable market (TAM) list the rest of your go-to-market stack can use, turn your ICP into an AI Ark company search and land the result as one model in Cargo. This cookbook settles industries, company size and countries first, sizes the search for free before it bills, and keeps the companies as tam_companies. Atomic by design: one connector, one model, one folder.

shellscript
cargo-ai cdk add cookbook/tam-building

What it does #

  • Starts from the ICP you already wrote, or drafts one from evidence. It reads the workspace context first. When nothing is there, it offers to read your website and customer stories and enrich your customers’ LinkedIn pages, and drafts context/icp.md from what they share.
  • Settles the minimum before any filter. Industries, company size and countries, each guessed from icp.md with the line quoted, or suggested and labelled, then confirmed by the operator.
  • Counts before it sources. aiArk.countCompanies takes the same filter groups as the search, returns {"count": N}, and is free. The search bills per returned record, so this is the difference between a market you chose and one you discovered after paying for it.
  • Puts the ICP in the filter, not in a post-filter. Every returned record is paid for. Narrowing happens where it costs nothing.
  • Needs nothing else. No CRM, no LLM, no play, no key, no seat. AI Ark runs on the connection the workspace already holds, bound with default: true.
  • Ends on openings, not on more infrastructure. A CRM coverage analysis, enrichment, deduplication or scoring: each is a separate job the report offers, with its own dependencies.

How it works #

flowchart TD
    icp["context/icp.md<br/>read, or drafted from website, customer stories, LinkedIn"]
    minimum["industries · company size · countries<br/>confirmed by the operator"]
    count["aiArk.countCompanies<br/>free, same filters, run at design time"]
    tam["tam_companies<br/>aiArk.fetchCompanies · the ICP filter · limit · no schedule"]
    report["Report: companies found, split by industry, size, country"]
    next["Openings: CRM coverage · enrichment · dedup · scoring"]

    icp --> minimum --> count
    count -.->|"shapes"| tam
    tam --> report --> next
  1. Write the ICP down in the project’s context/icp.md, or confirm the one that is there. This skill’s context/icp.md is the shape.

  2. Confirm industries, company size and countries. They are the floor of the filter.

  3. Translate the ICP into filter groups in infra/models/tam-companies.ts. They are nested groups, not a flat map, and enum-backed values come from the integration’s autocompletes.

  4. Count each candidate filter with aiArk.countCompanies:

    shellscript
    cargo-ai orchestration action execute --wait-until-finished \
      --action '{"kind":"connector","integrationSlug":"aiArk","actionSlug":"countCompanies","config":{}}' \
      --data '{"industry":{"industry_or":["software development"]},"employeeSize":{"min_employee_count":20,"max_employee_count":500},"companyLocation":{"location_or":["United States"]}}'
    
  5. Set limit to what you are willing to spend on the first run.

  6. Deploy and sync once, then read the report and pick an opening.

FileResourceRole
infra/connectors/ai-ark.tsdefineConnectorAI Ark, bound: no key, no seat, no cookie
infra/folders/index.tsdefineFolderthe model folder named after the skill
infra/models/tam-companies.tsdefineModelthe universe: the ICP filter and the budget
this skill’s context/icp.md(not a resource)example ICP to copy into the project’s context/
references/sources.md(not a resource)the other company sources, with pros and cons

Why it is atomic #

An agent installing a cookbook sets up every dependency the infra declares. If the TAM model shipped with a CRM extract, a unified model or a tiering agent, every install would wire a CRM connection or an LLM before it could source a single company, including for a company that has neither. Building the TAM needs AI Ark and a written ICP. Everything that acts on the TAM afterwards is a next step with its own cookbook.

Placeholders (edit before deploy) #

  1. The ICP: copy this skill’s context/icp.md into the project’s context/, or keep the one already there. The example is a technical B2B software ICP; nothing in it is yours.
  2. The filter groups in infra/models/tam-companies.ts config, always including industry, employeeSize and companyLocation. Nested groups, _or to include and _not to exclude, enum values from listIndustries / listSeniorities / listDepartmentsAndFunctions / listFundingTypes, numeric ranges as numbers.
  3. config.limit in the same file: the per-sync record budget, and the only real cost control.

Cost #

Counting is free. Research, when there is no ICP, bills per page read and per customer enriched. Sourcing bills per returned record, so the estimate is limit times the current per-record price: fetch it with cargo-ai connection integration get aiArk immediately before any preview rather than trusting a number written here.

The sourced model carries no schedule on purpose. A cron re-runs the same search and re-bills every returned record, including the rows already in the model: a monthly refresh buys the handful of new companies at the price of the whole pool. Sourcing is a deliberate spend.

Alternatives #

AI Ark is the default because it is the only source that counts for free with the filters it bills on. references/sources.md compares it with the other sources the contract accepts as a swap:

SourcePick it whenWatch out for
AI ArkYou want the pool size before you commitEnum-backed filters; per-record billing; 10,000 per sync
FullEnrichBudget matters, or you want a free refreshNo count; no persona, funding or lookalike filter
ApolloThe market is defined by hiring or fundingNo industry taxonomy (keyword tags only); no free count
Sales NavigatorThe market is defined by LinkedIn facetsNeeds a seat; highest per-record price; no domain; 5,000 per search

People Data Labs, TheirStack, Ocean.io and CompanyEnrich are covered there too, with the reason each one is not a default TAM source.

Verification #

shellscript
node --import tsx evals/contract.mjs   # the graph boundaries, from the compiled registry
cargo-ai cdk types && cargo-ai cdk check && cargo-ai cdk plan

evals/acceptance.md is the line-by-line acceptance test.

Composes into #

A CRM coverage analysis (how much of the TAM the CRM already holds), crm-enrichment, crm-deduplication, and account-scoring, which tiers tam_companies in place. references/run.md lists them as the report’s openings.

Give your agents a runtime

Bring the agents you have.Start free, deploy in one command.