Write-upA1–A6 · B1–B4 Email copyB3 · all plays
OneGTM case study · Client: VLM Run · Built by Bala · 11 Nov 2026

From one brief to a hundred accounts and the system that keeps finding them

Every phase of Part A (the list) and Part B (the outreach), in the order we did it. Each box is one step. Click a box with an i to see what happened, what it cost and what we changed. Every number comes from our own logs.

~1,000companies pulled in two batches
349survived the free website read
100scored 59+ on evidence only
1,921of 10,000 Blitz credits spent
0people contacted
Phase goal / result Step (click i) Approval gate or batch
00Setup: run it like a client1 credit
One folder, one runbook, one credit logTreated VLM Run like a real client account: documented, gated, reproducible
Read the Blitz docsLearn the cost model before spending
  • 1 credit = 1 record returned. Empty results are free.
  • Sizing trick: max_results: 1 returns the total match count, so a whole segment is sized for 1 credit.
  • Key draws from OneGTM's shared 13.5M pool, so our own 10,000 cap has to be self-enforced.
02-List-Building/Sourcing/blitz.md
Credit guard in code4,000 working cap · 6,000 reserve
  • blitz.py logs every call (endpoint, request, records, balance) to credit_log.csv.
  • Refuses any pull over 500 records without explicit approval.
  • Rule for every phase: test → verify by hand → scale, always with a cap.
Workspace/scripts/blitz.py · 04-Reports/credit-ledger.md
Questions to the clientAsked early, because asking is free
  • Missing Ray Summit / Part 2 file and the "two shared sections".
  • Closed-won list beyond the logo wall.
  • Segments already ruled out, geography, dollar price per credit.
00-Brief/questions-for-garrett.md
The folder, organised like a client accountBrief → onboarding → list building → outreach → reports → deliverables
VLM Run Case Study/
├── INDEX.md                  what's where
├── RUNBOOK.md                plan · gates · log
├── 00-Brief/                 3 brief PDFs, questions
├── 01-Onboarding-GTM/
│   ├── ICP/                  icp, customer anchors
│   ├── Scorecard/            A3–A5, calibration
│   └── Segments-and-Market/  A5 + A6
├── 02-List-Building/
│   ├── Sourcing/             Blitz notes, recipes
│   ├── Enrichment/           A2, pilot, plans
│   └── QA/                   hand-checks
├── 03-Outreach/
│   ├── Signals-People-Copy/  B1–B4, titles
│   └── Side-Quests/          GitHub signal
├── 04-Reports/               credit ledger
├── 05-Deliverables/          this diagram, write-up
└── Workspace/                code + data
    ├── .env                  API key, never shared
    ├── scripts/              blitz · merge · fetch
    │   │                     score · build_top100
    │   └── queries/          every recipe version
    ├── data/                 raw/ web/ web2/ b2/
    │                         *.csv · credit_log.csv
    └── out/top100.csv        the hundred
01ICP + search recipesA1269 credits
Who buys, and how do we find more of them?Start from the 4 real customers, not from guesses
Study the real customersValerie Health · Scan.com · Basata · CivilGrid
  • Looked each up in Blitz (15 credits).
  • Pattern: small vertical software companies (10–200 people) whose product eats messy paperwork. VLM Run sits inside their product.
  • Industry labels are all over the place (4 labels for 4 customers), so description keywords have to do the work.
  • Peak Health: the guessed domain matched the wrong company. Excluded. Lesson: verify domains from the source.
01-Onboarding-GTM/ICP/customer-anchors.md
7 segment hypothesesHealth ops, construction, insurance, lending, logistics, robotics, video AI
  • Ranked by evidence: healthcare ops = 3 of 4 customers (high). Construction = CivilGrid (medium). The rest = tests.
  • Out: doc-AI competitors, integration partners, services shops, >1,000 employees, the hospitals/GCs themselves.
01-Onboarding-GTM/ICP/icp.md
Recipes v1 → v4Size → sample 10–15 → hand-check → fix
  • v1 loose searches matched ~12,000 companies, about 70% junk.
  • Biggest fix: software-only industries. Construction went from 0 good to 6 of 10.
  • Multi-word phrases are AND-of-words ("physical AI" matched a physical-therapy EHR).
  • Competitors look exactly like prospects → blocklist of 29 names.
02-List-Building/Sourcing/sourcing-recipes.md · 02-List-Building/QA/phase1-handcheck.md
Kept 6 recipesS1–S6, each sized for 1 credit
RecipeMatchesHit rate in test
S1 Health ops7624 / 10
S2 Construction3426 / 10
S3 Insurance2054 / 10
S4 Lending3034 / 10
S5 Logistics1596 / 10
S6 Robotics962test segment
Workspace/scripts/queries/*.json
Dropped 2 recipesVideo AI · CV-engineer hiring
  • S7 Video AI: 3 of 15 "maybe", mostly generative video and ad tech.
  • J2 CV hiring: teams hiring core CV engineers are building their own (build, not buy). Kept as a signal idea instead.
  • J1 document-AI hiring: low volume, highest intent → saved for signals.
Gate: Bala cuts the pullProposed 1,660 → approved 600

100 per segment × 6. Pull small, learn, then decide whether the rest is worth paying for.

02Pull companies · batch 1A1656 credits
Pull 50 → read every row → decide → pull 50Optimise the search while it runs, per segment
Resume the same queryInsurance · lending · logistics · healthcare
  • Changing a filter restarts results at page 1, so you pay again for rows you already have.
  • Junk here was cheap to remove locally, so we resumed instead of re-filtering.
  • Finds: Avallon AI, Heron Data, Two Dots, KlearNow, Alvys, Humata.
Re-filter mid-pullConstruction v6 · robotics v6
  • Construction: "reality capture" pulled motion-capture companies. Re-filtered.
  • Robotics: half were integrators or hardware. Tilted to robot learning, autonomy and teleop.
  • Re-filter only when it saves more junk than it re-buys (~15 dupes in robotics).
One mistake: "as-built"−50 credits, rule added

The hyphen split it into "as" + "built", which matched 1,754 random companies. 50 junk rows are kept as evidence in data/raw/discarded/.

New rule: size after every filter change, before pulling.

609 unique → 44 excluded → 565 candidatesFree local merge, every exclusion keeps its reason
  • 21 horizontal doc-AI competitors, 15 acquired/shell pages, 5 bad domains, 3 manual (Tennr built its own VLM).
  • Judgment call: vertical doc-AI apps use the same words as competitors but are the ICP (same shape as Valerie Health). Kept and flagged "build or buy?".
  • Moved to the Google Sheet: README, Candidates, Excluded, Credit Ledger.
Workspace/scripts/merge.py · 02-List-Building/Sourcing/phase2-pull-log.md
03Enrich: free data and signals first, paid lastA2169 credits
Is messy visual input core to their product?Cut with free data first. Pay only for the companies that survive.
Calibrate the rubric on known answers4 of 4 real customers survive · 4 of 4 known junk cut · 12 credits

Before trusting the rubric on 565 companies, we ran it on VLM Run's real customers and on obvious junk. It sorted all 8 correctly, so we used it unchanged.

01-Onboarding-GTM/Scorecard/phase3-calibration.md
565 companies sourced from BlitzWith the data Blitz already gave us: about text, industry, size, HQ
Pass 1 · read each company's Blitz "about" text against the rubricFree (data already paid for) · 333 disqualified, each with its reason
Why it was cutCompanies
Core product isn't messy visual input226
Services shop, not a software product51
Operator (the hospital, carrier or contractor itself)25
Builds its own vision models (build, not buy)12
Acquired or defunct10
Media / publisher9
Workspace/data/pass1.csv · rubric Workspace/scripts/enrich_prompt.md
232 companies left
Pass 2 · read their own websiteFree · product, security, integrations, developer and careers pages · 38 disqualified
  • Each page answers one question: what enters the product, regulated data, which OCR tool they use today, whether they're developer-led.
  • Saved for every company: visual core (yes / partly), modalities, a word-for-word evidence quote + URL, and flags (OCR, REG, DEP, VID, OWN).
  • Cut: 37 whose product turned out not to be visual once the site was read, 1 that built its own VLM (PackageX).
  • 26 sites couldn't be read (JavaScript walls), so we fell back to the Blitz text and flagged them.
Workspace/scripts/fetch_web.py · fetch_deep.py · Workspace/data/web2/
194 companies qualifyOnly these get paid data
Hiring signalFree job boards first, then Blitz jobs · 28 credits
  • 35 companies checked on their public job boards (Greenhouse, Lever, Ashby, Workable). Free.
  • 104 checked with Blitz jobs data. Empty results are free, so it cost 28 credits.
  • Result: 29 companies hiring ML/AI engineers right now.
Workspace/scripts/jobs.py · Workspace/data/jobs.csv
Engineering team shareBlitz department data · 1 credit per company
  • How many engineers each company has, and what share of staff that is. Tells us whether they can integrate an API.
  • 129 credits for the strongest 130 in this phase, then the other 64 at the start of Phase 4, so all 194 are covered.
  • Blitz's docs say this data is free. It actually costs 1 credit per company. We caught that on the first few calls.
Workspace/scripts/dept.py · Workspace/data/dept.csv
194 enriched companies → scoring169 credits in total: 12 calibration + 129 engineering + 28 hiring
04Score on evidence onlyA364 credits
100-point scorecard, every point with a source70 points for the need · 30 for the buyer · penalties for build-own
The need · 70Visual core 30 · messy 10 · modality 15 · extracting today 15
  • Visual core: yes 30, partly 12.
  • Messy input: fax, handwriting, scans, phone photos.
  • Modality: docs 5 · images 10 · video 15 (VLM Run's edge).
  • Extracting today: OCR, IDP or GPT/Claude stack = existing budget.
The buyer · 30Sensitive data 10 · timing 10 · buyable 10
  • Sensitive: HIPAA/PII 6 + VPC/on-prem/ZDR 4. SOC 2 alone doesn't count.
  • Timing: ML/AI hiring 7 + "launching soon" 3.
  • Buyable: 10–300 people 6 + ≥5 engineers 4.
PenaltiesOwn vision −15 · services −10 · acquired −8

A perfect buyer with no visual workload can't score above ~42.

Workspace/scripts/score.py
CalibrationReal customers land #8, #10, #12, #71

No weight tuning needed. Scored with the same rules as everyone else.

StabilityEach weight ±20%: worst case 93 of 100 unchanged

34 runs, average 99.3 of 100 unchanged. The ranking doesn't hinge on one weight.

10 rows by hand4 fake points found → 4 rule fixes
  • Trust-center text, a marketing "watch video", a dated blog headline, weak quotes.
  • Evidence now only counts from product/home/integrations/developer pages.
  • Then every top-100 quote checked word for word: 100/100 verbatim.
02-List-Building/QA/handcheck_10.md
05Batch 2 → the hundred + segmentsA4A5762 credits
Raise the bar: learn from the top scorers, pull lookalikesBatch 1's #100 scored only 42
Batch 2 · reran phases 2–4
Commonalities of top scorersSoftware dev · founded 2010+ · 15–470 staff · intake / automation words

The first 609 companies were held out so nothing was bought twice.

6 lookalike + 6 geo recipes + video v2US/GB/CA, then AU, NZ, IE, IL, SG, NL
StepCredits
Lookalike sourcing (6 segments)470
Geo recipes (0 dupes, small pools)45
Video-first re-cut76
Eng headcount, 155 survivors153
Hiring check, 148 companies18
Workspace/scripts/queries/batch2/
432 new → 155 kept → 349 combined poolSame free website read, same scorecard, rescored together
The hundred: #1 Avallon AI 85 · #100 TrialView 59#100 rose 42 → 59 · 97 at 60+ · 49 from batch 2
  • Combined calibration: Basata #14, CivilGrid #17, Valerie Health #26. Scan.com fell to #135 as the bar rose (it was always the "partly" customer).
  • Robotics dropped out: best is Mind Robotics at #127. None showed video extraction today.
  • Every row: per-criterion scores, segment, title to contact, verbatim quote + URL.
Workspace/out/top100.csv · Sheet tabs Top 100, Scored, Enriched
A · Regulated doc intake59 accounts · health, insurance, lending, legal

Faxes, referrals, ACORD forms, pay stubs. Lead with accuracy on messy docs + ZDR, BAA, VPC. Proof: Valerie Health, Scan.com.

B · Field & freight28 accounts · construction, logistics

Drivers photograph BOLs and PODs; jobsite photos and plans. Lead with docs + photos in one API. Proof: CivilGrid.

C · Video-first13 accounts · dash cams, video inspection

Footage at scale that needs searching. Buyer is the ML/data team. No customer proof yet.

Leave outCompetitors · built their own VLM

Tennr, PackageX, Owl.co and horizontal doc-AI vendors. Reference cases, not prospects.

Inside every play one split changes the message: already extracting → "replace your OCR + LLM stack"; not yet → "build it right the first time".

06Scale it to the whole marketA60 credits
From 100 to every company that fitsAnswered from saved search sizes, no new spend
Market size~2,300 tight matches · ~1,000 pulled
  • Funnel: 1,000 → 349 (35%) → 100 (10%).
  • Inference: the other ~1,300 hold another 100–130 top-grade accounts.
  • Loose universe ~12,000 at ~30% fit → low thousands of real fits.
01-Onboarding-GTM/Segments-and-Market/a5-a6.md
Unit cost~19 credits per top-100 account
  • Batch 2 alone: ~16 per top-100 account.
  • Next ~1,300 matches ≈ 2,600 credits: above our remaining working cap, so not run.
  • Full loose universe ≈ 20,000+ credits (inference). Needs OneGTM's budget and $ per credit.
9 things that breakAll of them happened to us
  • Keyword splitting · filter changes restart pages · docs wrong on cost · shared pool
  • Fake evidence · search labels ≠ what they do · unreadable sites / LLM drift
  • Stale signals · best segments run dry → grow by geography and hiring
Side quest: GitHubWeak for this ICP, one real find
  • Stargazer lists are closed (404). Forks, issues and code search still work, free.
  • 127 people around VLM Run's repos → 0 matches to our 349 (students, solo devs, platforms).
  • Zeitro (#91): public code sends borrower PDFs and photos to OpenAI vision. The exact stack VLM Run replaces.
  • Competitor repos: recent stars recovered from the public events feed (353 stars, 329 people, 60 list a company). Not yet matched.
03-Outreach/Side-Quests/github-signal.md
07Turn the list into outreachB1B2B3B40 credits
Right moment · right people · emails an engineer answersDesigned, not sent. Nobody contacted.
B1 · Signals9 company · 5 people signals
  • Company: ML/doc-AI hiring, job post naming Textract/Tesseract, new intake product page, compliance page, funding, marketplace listing, public LLM-vision code, repo activity, VLM Run signup.
  • People: new CTO/Head of AI (90 days), customer champion moved, OCR-pain post, event speaker, engaged with VLM Run posts.
  • Strong signal on a top-100 account → signal email within 48h. One signal email per account per 30 days.
B2 · People30 DM · 40 influencer · 40 champion titles
  • Blitz people search → Blitz waterfall ranks decision maker > influencer > champion.
  • Email-finder waterfall → MillionVerifier: valid → sendable.csv.
  • Catch-alls → BounceBan → deliverable joins the same file. Rest → LinkedIn only.
03-Outreach/Signals-People-Copy/b2-titles.md
B3 · Copy3 emails + signal version per play
  • 25–55 words, one fact each, CTA offers to run their samples and send the JSON.
  • All 12 emails pass the house spam scan.
  • LinkedIn: lowest-scored accounts first. Founder + growth account connect the same day, then 30–60 days of silence while weekly posts warm them up. Only the employee account messages.
B4 · Personalization5 real examples, sources shown
  • Inflooens: Claude Sonnet 4 for PDFs, GPT-4o-mini for images.
  • Coral: e-fax extraction + hiring ML engineers.
  • Zeitro: borrower phone photos → 1003.
  • Alvys: drivers snap BOL/POD photos.
  • Blitzz: OCR during live video sessions.
  • At 1,000: the same website read writes the line from a verbatim quote. No quote → segment fallback.
03-Outreach/Signals-People-Copy/b1-b4.md
08The system: what runs whenB5
The same pipeline, running on its ownEach layer feeds the next; signals decide timing, not targeting
Layer
What happens
Runs when
Sources
Blitz company search (tight + lookalike recipes), new geographies, marketplaces, hiring search
Quarterly · after each recipe change: size first
Enrichment
Free website read + public ATS → visual core, modalities, flags, verbatim quote. Paid headcount on survivors only
On every new company · monthly refresh, top 300
Scoring
score.py: 100 points, evidence only. Canary: the 4 real customers must stay near the top
After every enrichment run
Segments
Play A regulated docs · B field & freight · C video-first · leave-out group
Set by score run
Signals
Hiring + named-tool job posts, site diffs, new leaders, funding, VLM Run signups
Daily signups · weekly jobs · monthly sites & people
People
Title lists → Blitz search → waterfall → email finders → MillionVerifier → BounceBan → sendable.csv
When an account enters a play · monthly re-check
Copy
Play sequence, or the signal version when one fired · line written from the site quote
Per contact, at enrolment
Sending
Email: 3 steps, days 0 · 3 · 9. LinkedIn: two accounts connect, message after 30–60 days
Signal emails within 48h · approval gate before any send

Loop: replies and bounces feed back into scoring; accounts with no contact found go to next month's re-check.

ΣWhere the credits went
100 setup
26901 recipes
65602 pull
16903 enrich
6404 score
76205 batch 2
1,921of 10,000 · 6,000 reserve untouched

Phases 6–8 used no credits. Lost to mistakes: 50 ("as-built") + 2 (wrong Peak Health domain).