Home / Stage 1 of 6
๐Ÿ—‚๏ธ Stage 1

Build the Account List

Before you can reach out to anyone, you need to know who you're trying to reach. This stage turns your niche into a real, working list of target companies.

What is this?

Your prospect list is a spreadsheet (or database) containing every company in your target market โ€” the organizations you might one day work with. Think of it as the foundation your entire marketing system is built on. Everything else โ€” enrichment, contacts, emails, LinkedIn outreach โ€” only works if you start with a solid list.

Why does it matter? Most marketing fails because it's aimed at the wrong people, or at too broad a group. A focused, well-sourced list means every dollar and every hour you spend on outreach goes toward real prospects โ€” not noise.

What does "the list" actually look like?

At its simplest, it's a spreadsheet where each row is one company. At minimum you need: the company name, their city and state, and their website. Everything else gets added later through enrichment. The website is especially important โ€” it becomes the unique identifier that lets you avoid counting the same company twice.

The key insight: Use the website domain (like example.com) as your unique ID โ€” not the company name. Names vary wildly ("The Art Museum" vs "Art Museum, The"). A domain is consistent.

Where does the data come from?

Depending on your market, you might pull from government databases, industry association directories, Wikipedia lists, LinkedIn, or plain old Google searches. For most B2B markets, a combination of Google searches across every US city (run automatically by Claude Code) will surface thousands of companies you'd never find manually.

Real example: For US marketing agencies, we ran 8 different search phrases across nearly 2,000 cities and collected tens of thousands of agencies in a few days โ€” for about $31 in API costs. That same list would cost thousands from a data vendor and be months out of date.
10k+
agencies discovered per niche via Google
~$31
total API cost for all 1,946 cities
8
search phrase clusters per city
days
to build a list a vendor charges thousands for
Before you start You need a clear answer to: "What type of company am I targeting, and in what geography?" The more specific, the better. "Small marketing agencies in the US" works. "Businesses" does not.
1

Identify your sources

Decide where your companies will come from. Common sources:

  • Google searches โ€” city by city, using search terms that describe your audience. ("marketing agency Denver CO", "web design firm Nashville TN", etc.)
  • Government databases โ€” for museums, we used the IMLS federal database. Many industries have equivalent registries.
  • Industry directories โ€” trade associations often publish member lists (AAM for museums, etc.)
  • LinkedIn โ€” company searches by industry + location. Sales Navigator exports can be a starting point.
  • Wikipedia lists โ€” for well-catalogued categories (museums by state, universities, etc.)
2

Design your search strategy

For Google-based discovery, you need a set of search phrases that describes your target. Think about all the ways someone might describe your ideal client:

  • What does the company call itself? ("marketing agency" vs "advertising firm" vs "creative studio")
  • What services do they advertise? ("branding", "web design", "social media")
  • Are there industry-specific terms? ("boutique agency", "full-service firm")

Group these into 5โ€“10 clusters and Claude Code will run each one across every city in your geography automatically.

3

Run the collection (automated overnight)

You describe your search strategy to Claude Code, and it builds a script that runs every search, collects the results, and saves them to a database. This runs unattended โ€” you set it going and check the results in the morning. For 2,000 cities ร— 8 search types, expect 2โ€“3 days of background processing.

4

Remove the noise

Google returns everything โ€” including job boards, directories, Yelp listings, and giant national brands that aren't your audience. You'll need an exclusion list:

  • Directory sites โ€” Clutch, UpCity, GoodFirms, Yelp, etc.
  • Companies too large โ€” WPP, Publicis, Ogilvy, and any holding company brands
  • Irrelevant domains โ€” job boards, news sites, social networks

Claude Code maintains this exclusion list and gets smarter as you review results. Every time you spot a new type of noise, you add it once and it's filtered forever.

5

Deduplicate

The same company often appears in multiple searches. "Acme Creative" shows up when you search "creative agency Denver" and again when you search "branding firm Denver." Deduplication uses the website domain as the unique key โ€” one domain = one company.

  • Exact domain matches are removed automatically
  • Companies sharing a parent domain need judgment calls (a university museum vs. the university itself)
  • Fuzzy name matching catches cases where the domain isn't obvious
6

Review and curate

Run a sample of results past your own eye. You'll catch patterns the automation missed โ€” a whole category of irrelevant companies, or a useful source you hadn't thought of. Update the exclusion list and re-run. Each pass tightens the quality.

The list is never "done" New companies start every day. Think of the list as a living thing you refresh periodically, not a one-time project. The automation you build here can be re-run any time to pick up new entries.

Tools you'll use

Serper API Python / Claude Code SQLite tldextract pandas (optional)
Accounts & costs

Starting prompt for Claude Code

Paste this into Claude Code to get started
I want to build a prospect list of [TYPE OF COMPANY] across the United States. My target: [DESCRIBE YOUR IDEAL COMPANY IN 1โ€“2 SENTENCES] Geography: All US cities (I have a CSV of 1,946 cities with population tiers) Source: Serper API (I have an API key: [YOUR KEY]) Build me a Python script that: 1. Reads the cities CSV 2. For each city, runs these search queries through Serper: - "[term1] [city] [state]" - "[term2] [city] [state]" (I'll provide the full list of search terms) 3. Saves results to a SQLite database with these columns: domain, name, city, state, snippet, first_seen, source_query 4. Uses the apex domain (via tldextract) as the unique key โ€” skip duplicates 5. Tracks progress per city so it can resume if interrupted 6. Excludes these domains: [yelp.com, clutch.co, linkedin.com, facebook.com, ...] Make it resumable โ€” if it crashes or I stop it, I should be able to re-run and it picks up where it left off.

Designing your search clusters

For US marketing/design/ad agencies, we used 8 clusters of synonyms, each covering a different facet of the industry. Adapt this for your market:

Example: marketing agency clusters
Cluster 1 (core): "marketing agency" OR "marketing firm" OR "marketing company" Cluster 2 (advertising): "advertising agency" OR "ad agency" OR "advertising firm" Cluster 3 (creative/brand): "creative agency" OR "branding agency" OR "brand studio" Cluster 4 (design): "design agency" OR "design studio" OR "graphic design firm" Cluster 5 (web design): "web design company" OR "web design agency" OR "website design" Cluster 6 (web dev): "web development company" OR "web development agency" Cluster 7 (digital): "digital marketing agency" OR "digital agency" OR "online marketing" Cluster 8 (PR/social): "PR agency" OR "public relations firm" OR "social media agency"

Key design decisions we made (and why)

Use SQLite, not CSV, for the collection phase A long collection run across 2,000 cities takes days. If you store results in CSV and the script crashes, you lose everything or create duplicates. SQLite gives you transactional writes (each city commits atomically) and lets you resume exactly where you stopped. Export to CSV later for editing and analysis.
Source weighting matters when merging multiple sources If you use both a government database and Google searches, the same company appears in both โ€” often with conflicting information (different name spellings, different addresses). Establish a priority order upfront: which source wins for each field? We learned this the hard way when IMLS directory names overwrote better names we'd scraped from actual websites.
Build your exclusion list incrementally Don't try to anticipate every bad result upfront. Start with the obvious ones (social networks, major job boards), then add to the list as you review results. Claude Code makes it trivial to re-filter your existing database after adding new exclusions โ€” no need to re-run the expensive API calls.

Prompt to add your exclusion list

Run this after reviewing your first batch of results
Look at my agencies.db. I've reviewed the first 500 results and found these patterns that aren't my target companies: Directory/aggregator sites: clutch.co, upcity.com, goodfirms.co, sortlist.com, [add yours] Large holding companies: wpp.com, publicis.com, interpublic.com, [add yours] Irrelevant categories: jobboards, news sites, SaaS tools that call themselves "agencies" 1. Add these to an EXCLUDED_DOMAINS frozenset in a new file called exclusions.py 2. Write a one-time script that flags existing DB records matching these domains as excluded 3. Update collect.py to import exclusions.py and call is_excluded() before inserting any new record Show me the count of newly-excluded records so I know how many were filtered.