Home / Stage 2 of 6
๐Ÿ” Stage 2

Enrich the Accounts

You have a list of company domains. Now find out what each company actually does, how big they are, and whether they're worth contacting.

What is this?

Enrichment means visiting each company's website and pulling out useful information automatically: company description, employee count, what they specialize in, whether they're still active. A raw list of domains tells you almost nothing. Enriched data tells you whether to bother.

What does enriched data look like?

Before enrichment
pixelcraft.com
โ†’
After enrichment
PixelCraft Studio
Brand identity & web design
Austin, TX ยท 3 employees
Founded: owner Sarah Chen

Why automate this?

With potentially tens of thousands of companies on your list, manually visiting each website would take months. A script can process hundreds per hour overnight, reading each site and asking an AI to extract the key details.

~$15
AI cost to enrich tens of thousands of companies
3โ€“5
key fields per company
400+
sites processed per hour
~70%
success rate (some sites block scrapers)
Before you run this overnight: is your machine configured to stay awake? Enrichment takes 8โ€“12 hours. If Windows sleeps mid-run, your script stops โ€” and may not resume cleanly. See Prerequisite โ†’ Step 6 for the one-time fix.
Enrichment runs in batches overnight. You don't sit and watch it โ€” you run the script before bed and check the results in the morning.
1

Decide what you want to know

Before you ask Claude Code to build anything, decide on the 5โ€“8 fields that would help you determine whether a company is worth contacting. For a web agency targeting small businesses: company name, description, employee count, city, state, whether they serve a specific industry, and whether the owner is findable. Write them down first โ€” Claude Code builds exactly what you describe, so the clearer you are here, the better the result.

2

Fetch the website content

The script visits each company's homepage and extracts the text. Most websites block simple scrapers โ€” use a reader service like Jina Reader, which returns clean text content from any URL. The text is then passed to an AI to extract the information you want.

3

Ask the AI to extract key fields

Send the page text to a cheap AI model (Claude Haiku costs fractions of a cent per call) with a structured prompt: "Given this text, extract: company name, description, employee count, location." The AI returns structured data that gets saved to your database.

4

Handle failures gracefully

About 30% of websites will fail โ€” the site is down, it blocks scrapers, or it's just a blank page. The script tracks these failures so you can skip them in future runs. Capture why each one failed โ€” this is how you improve over time.

5

Score and filter

After enrichment, add a simple quality score to each record. Size match (1โ€“10 employees = high priority), description match (mentions design/branding = relevant), location match (US only = in scope). Anything below a score threshold gets deprioritized so you work the best prospects first.

Run incrementally. If enrichment takes 8 hours overnight, don't restart from scratch if it fails halfway. Store progress in your database and pick up where you left off. This is why SQLite beats a CSV file for this work.
Jina Reader API Claude Haiku SQLite Python asyncio aiohttp

Accounts & costs

Service What it does Cost
Jina Reader Converts any URL to clean readable text Free for basic use / ~$0.02 per 1k calls
Anthropic API (Haiku) AI extraction โ€” reads page, returns structured data ~$0.25 per million input tokens
Claude Code Prompt โ€” Build the enrichment script
I have a SQLite database with a table called "agencies" that has a "domain" column. I want to enrich each record by visiting the company website. For each domain: 1. Fetch the page using Jina Reader (https://r.jina.ai/{domain}) to get clean text 2. Send the text to Claude Haiku with a structured prompt to extract: - company_name - description (1-2 sentences) - employee_count_estimate (numeric) - city - state - services_keywords (comma-separated list) - confidence (high/medium/low) 3. Store results back in the agencies table 4. Track failures in an enrichment_log table with the error reason 5. Use asyncio to run 10 concurrent requests 6. Skip domains already enriched (check if company_name is already populated) Use the Anthropic Python SDK. My API key is in a .env file as ANTHROPIC_API_KEY.
Claude Code Prompt โ€” Add quality scoring
After enrichment, I want to add a quality score to each agency. Add a column called "quality_score" (integer 0-100) and a column called "tier" (A/B/C). Score based on: - Employee count 1-10: +40 points (ideal), 11-50: +25 points, 51+: +5 points - Description mentions design/branding/marketing: +20 points - US state is populated: +10 points - Confidence is "high": +15 points, "medium": +10 points - City is populated: +5 points - Domain is a .com: +5 points - Missing company_name: -50 points Tier A = 70+, Tier B = 40-69, Tier C = below 40 Write a SQL update statement or Python script that runs after enrichment completes.

Design decisions

Why Jina Reader instead of raw requests? Jina handles JavaScript-rendered sites, removes ads and nav clutter, and bypasses basic bot detection. Raw HTTP requests fail on ~40% of modern websites. Jina costs almost nothing and dramatically increases your success rate.
Why Claude Haiku, not GPT or a cheaper model? Haiku is fast, cheap, and excellent at structured extraction from messy text. At $0.25 per million input tokens, enriching tens of thousands of sites costs roughly $15โ€“20 total. The structured output (JSON) is reliable enough to insert directly into your database without manual review.
Why 10 concurrent requests? More than ~15 concurrent requests starts to trigger rate limiting on Jina and on the Anthropic API. 10 is the sweet spot between speed and stability. You can tune this up or down based on what you observe.

Outreach Machine Playbook ยท Built with Claude Code ยท Back to overview