I built my sales pipeline the way I build engineering: agents draft, a person decides.

Four scheduled jobs, one spreadsheet, and one rule I refused to bend: nothing leaves my inbox until I've ticked a box next to it. How I find founders who need a CTO, what it cost to build, and why the approve column is the whole design.

Puneet Gupta · 29 September 2026 · 8 minute read

When I decided to sell "your engineering is my problem" to founders, I had a sales problem I'd never had before. The founders I'm looking for are not googling "fractional CTO". Most of them don't know that's a category. They know they raised a seed round and the two engineers they have are stretched, or that their CTO left last quarter, or that the agency they hired ships slowly and owns everything. Those facts are public. They're just scattered across funding news, job boards and Hacker News threads, and nobody is reading all of it.

So I treated it as an engineering problem. Two days, four scheduled jobs, one spreadsheet, and one rule I refused to bend: nothing leaves my inbox until I've ticked a box next to it. This post is how it works and what it cost, in case the same shape is useful to you.

Who I'm looking for, precisely

Everything downstream depends on this being narrow. Four kinds of company, each with a reason to want engineering taken off their hands:

  • Startups in the US, UK, EU or UAE, pre-seed to Series A, roughly $1M to $15M raised, with no CTO or one who left recently. Contact: the CEO.
  • Venture studios that launch several companies a year and need engineering for each new bet.
  • Small software businesses, $2M to $20M revenue, recently bought by a search fund or holding company, where the new owner inherited a codebase and no technical leader.
  • Anyone publicly hiring a fractional, interim or part-time CTO. These people have already asked for what I sell.

Just as important is who to exclude: Series B and later, over 200 people, hardware, biotech, defense, crypto, agencies, and any company that already runs an India team. Half the value of the pipeline is what it throws away.

The shape of it

One Google Sheet is the database. Three tabs: Leads (one row per company, with a status that moves from New to Qualified to In sequence), Config (every limit and API key as a key-value row, so I can change behaviour without touching a workflow), and Runs (one row per run: what was found, added, qualified, pushed, and what went wrong). No database, no dashboard, no admin UI. A spreadsheet is something I'll open every morning.

Four n8n workflows run against it on a schedule:

JobWhenWhat it does
FindMon, Wed, Fri 07:45Searches the week's funding news, CTO departures, studio launches, acquisitions and job posts; extracts companies
Find (Hacker News)2nd of the monthReads the monthly "Who is hiring?" thread and pulls out founder-led teams hiring their first engineers
QualifyDaily 08:45Researches each new company, scores it out of 10, finds the contact, drafts the opening line, verifies the email
SendDaily 09:45Pushes approved leads into the right email sequence and records the result

The stack is deliberately boring: n8n Cloud for scheduling, Tavily for search, Claude for reading and judging, a free email verifier, and Instantly for sending. Everything except the model calls is on a free tier.

Finding: let the model read, not decide

The Find job runs about fourteen searches: "startup raises seed round" restricted to sites that publish small rounds, "startup CTO steps down", "venture studio launches new startup", "search fund acquires software company", plus job-board searches for founding engineer and head of engineering roles. Each search returns ten snippets. They're pooled, de-duplicated by URL, and handed to a fast model in batches of twenty with a prompt that says, in effect: list every company in these snippets that fits one of the four segments, return JSON, use only facts in the snippets, never invent a website.

Two things matter here. The model's job is extraction, not judgement, so the cheap fast model does it. And a funding roundup mentions eight companies in one paragraph, which a keyword filter would score as one lead; the model reads it as eight. What comes back is de-duplicated against every company already in the sheet, capped at 25 new rows per run, and saved with status New.

The Hacker News job is the same idea against a different source. The September thread had 255 posts. A regular expression keeps the ones that mention founding engineers, a head of engineering, a CTO, or a founder writing the post, and drops anything that says Series C or "500 employees". Thirty-eight posts survived. Those went to the model; the rest never cost a token.

Qualifying: a rubric, not a vibe

This is where the expensive model earns its keep, and where most of the two days went. For each New company, the job runs two searches, one about the company and one about its people on LinkedIn, and gives the stronger model the lead plus both result sets with a rubric:

  • No CTO, 0 to 3. Three if no CTO or VP Engineering appears in any source, or the CTO left in the last six months. Zero if a senior technical leader is clearly in place.
  • Signal, 0 to 3. Three for something in the last twelve months: a raise plus engineering hiring, an open engineering leadership role, a departure, an acquisition.
  • Budget, 0 to 2. Two if at least $2M raised or $2M revenue.
  • Stack, 0 to 1. Web, mobile, cloud or AI application software.
  • Warm, 0 to 1. Always zero. Only I can fill this in.

Anything under 4 is disqualified with a reason written into the row. Hard disqualifiers override the score: a tenured CTO, Series B, an agency, an existing India team, a company that has shut down. The model also names the contact, but under strict rules: only names, titles and LinkedIn URLs that literally appear in the sources, and an email only if the full address appears in a source. It is not allowed to guess an email. That's the single most important line in the prompt, because a confidently invented address is worse than none.

Email guessing happens in code instead, where it can be checked. If the sources didn't contain an address, the job tries first@, first.last@ and flast@ against the company domain and runs each through a verifier before anything is marked Qualified. Verified means Qualified. Catch-all domain means best guess, labelled as such. Nothing verified means the row stays at Needs email, and spare verification budget each morning works through the older Needs email rows, highest score first.

The opening line

The model also drafts the first sentence of the email, and the rules for that sentence are stricter than the rules for the score. At most 25 words. One specific, checkable fact from the last twelve months and what it usually means. No "Saw", no "Noticed", no "Congrats". Never comment on what the company lacks, never guess how the founder feels, never mention AI or this research. If there's no real fact to use, leave it blank, and a blank first line means the lead can't be sent. I would rather send nothing than send "I noticed you don't seem to have a CTO".

The gate

The Send job only looks at rows where three things are true: the status is Qualified, there's a verified email, and I have typed a Y in the approve column. It reads which campaign belongs to the lead's segment from the Config tab, adds the lead to that sequence with the first line as the personalisation variable, and asks the sending tool to skip anyone already in the workspace. The row moves to In sequence with a timestamp, or to Push failed with the reason. Twenty a day, at most.

That approve column is the whole design. Every morning I open the sheet, read the Qualified rows with their score, the evidence for the score, the contact, and the drafted first line, and I tick the ones I'd be happy to have my name on. It takes about ten minutes. Everything the machine did is visible in the row, so when a first line is wrong I can see which fact it misread, and when a score is wrong I can see which of the five numbers moved it.

The rules that made it work

None of these are clever. All of them were added after something went wrong on the first run.

Only facts from the sources. Every prompt says it, and the parsing code enforces what it can: a LinkedIn URL that isn't a linkedin.com/in/ link is dropped, an email that didn't come from a source is dropped, a website that isn't a domain is dropped.

Every limit lives in the Config tab. New leads per run, leads to qualify, emails to verify, leads to push, the minimum score, the model names, the campaign IDs. Changing any of them is editing a cell, and a bad day of results can be throttled before the next run without opening n8n.

Every run writes a row. Found, added, qualified, needs email, disqualified, pushed, errors, and a notes field that names the lead IDs that need my attention. If a search fails or the model returns something that isn't JSON, the run finishes, logs the problem and moves on. Nothing retries forever and nothing fails silently.

Cheap model for reading, expensive model for judging. Extraction from snippets is a fast-model job. Scoring a company against a rubric with two sets of search results is not. Splitting them keeps the qualification prompt long and careful without making the search step expensive.

The same code in two places is the same code. The parsing step is identical in the news job and the Hacker News job, down to detecting which workflow it's running in. When I fix a bug in one, I paste it into the other.

What it costs

Two days to build, including the false starts. About ten minutes a morning to run. The model spend is cents per lead at the current caps, and the search, verification and scheduling tools are all on free tiers. The only real monthly cost is the sending tool. The sending inbox is on its own domain with SPF, DKIM and DMARC set up, and it is warming up slowly: a handful of emails a day, rising to a cap of seventeen. The first campaign starts in mid October. Until then, the top leads go out by hand, one at a time.

Results

Updated as replies come in. The first emails went out by hand on 28 and 29 September. Automated sequences start mid October once the inbox has warmed up. I'll put reply and booking rates here when there are enough to mean something, including the ones that embarrass me.

Why I'm telling founders this

Because it's the same pattern I run in engineering, and it's the pattern I'll run on your codebase. Agents do the reading, the searching and the first draft. Code enforces the rules that can be enforced. A person decides. The approve column in this sheet is the same thing as the pull request review in the workflow my teams use: the step where a human with context looks at what the machine produced and says yes, no, or not like that. Remove that step and you get speed and embarrassment in equal measure. Keep it, and you get a system one person can run in ten minutes a day.

If you'd rather I ran that system for you on the engineering side, the button is below.

I take over engineering for founders who don't have a CTO: infrastructure, delivery, hiring and the team, for less than a third of US cost. The pipeline above is how I sell it; the workflow behind it is how my teams build. If your engineering needs an owner, book a call.