Yes, ChatGPT's free plan can hand you several hundred usable leads this month. The condition is that you do the checking yourself, because the model only types the table.
Ask for 1,000 dental practices in Ohio tonight and you will get them, with names and websites that were never once opened.
On this build, ChatGPT types for under 40 minutes of a roughly 38-hour job. Out of 1,250 raw rows, about 480 survive a phone call. The typing was never the work.
Every prompt in this build is written out in full, and so are the emails. The line is drawn where the chat window stops and your 90 seconds per row begins.
You will finish knowing whether Free is enough or whether Go at $8 a month earns its place. Tonight, paste the niche paragraph and pull the first 25 rows.
| Tool | Price (US) | Job in this build | Day-one need |
|---|---|---|---|
| ChatGPT Free | $0/month | Drafts seed rows, batches, dedupe, scoring and email angles | Yes — the whole build runs here |
| ChatGPT Go | $8/month | More messages, uploads and longer memory than Free | No — buy only if two weeks stall |
| ChatGPT Plus | $20/month, no annual option | Deeper research, projects, custom GPTs | No — custom GPTs and the AI Lead Scout plugin need a paid plan |
| HubSpot free CRM | $0 | Stores and dedupes verified contacts by website domain | Yes — on day one, before you import |
| Apify Niche B2B Lead Finder | From $5.00 per 1,000 B2B leads | Buys raw rows when drafting is the bottleneck | No — an outside spend, not part of Free |
| Clay Launch | $167/month billed yearly | Workflow builder for teams; free plan covers 6,000 AI actions a year | No — only once a team is involved |
The One-Paragraph Niche Brief

Start with the brief, because it is the only real input in the whole build. Every later prompt opens by pasting this same paragraph back in, so a sloppy one gets copied into 24 replies.
A tighter version of the prompt formula makes that paragraph do more work per paste.
Ask for "dentists in the US" and the table comes back full of chains, hospital groups and addresses with no city you can check.
Narrow it to Ohio, one location, one to three dentists, and each row arrives with a city, a site and a person to open in a browser.
Only four pieces change when the niche changes: who they are, where they are, how big they are, and what you sell at what price. Everything else in the paragraph stays put.
Quick check: Free holds about 27,000 tokens. A token is a chunk of text, roughly three quarters of a word, so the chat forgets the start of the conversation once that fills.
That ceiling leaves room for about 12 pages, seeds and answer together. A vague brief starts drifting off-niche around batch three, and the columns stop matching the niche.
Prompt to copy
Act as a B2B lead researcher. My niche is single-location dental practices in Ohio with 1 to 3 dentists and a live website. I sell website redesigns at $3,500. For each lead give practice name, city, website, decision-maker name and role, and the URL where you saw it. If you cannot find a field, write unknown – never guess. Return 25 rows at a time as a table.
Paste that into ChatGPT unchanged and read the first reply before going further. If a row has no city or no site, the brief is still too loose for the volume ahead.
The Search-String Generator Prompt

The chat cannot walk a directory for you, so it writes the searches instead. On Free it can browse the live web, but it will not page through Google Maps or the Ohio state dental board the way a person does.
So this prompt hands back strings to run yourself. Twelve of them come back in about 20 seconds, and running all twelve in a browser takes about 20 minutes.
Prompt to copy
Using this brief – [paste the niche paragraph] – write 12 search strings I can paste into Google Maps and the Ohio state dental board directory. Mix city plus service, "independently owned", "family dental" and "new practice" angles. Put each string on its own line and say which site to run it on.
Check the split before running anything. If all twelve lean on city names and none covers ownership or new practices, the net is too even and you will miss the small offices.
What you get back is material for the seed rows, pulled from pages you loaded and looked at yourself, not from the model's memory of what Ohio dentists exist.
The 40-Row Seed List

One request for the whole list is the mistake this build exists to prevent.
Asked for 1,000 rows in a single pass, ChatGPT would rather fill a cell than write "unknown", so it hands back 1,000 tidy lines and some of those practices were never there.
A seed row is smaller and honest: practice name, city, website, and the directory page it came from. Forty of them come out of those twelve searches, about 45 minutes of copying and 5 minutes of tidying before you paste.
Paste all 40 into one fresh chat, then ask the chat to describe the pattern in them and keep that conversation open as the template. Every later batch is then asked to match those 40, not the open internet.
The difference shows in the second batch. The lookalikes arrive with cities you can place, sites that load and a person named in roughly the same style, because the model has your forty examples in front of it instead of a vague national category.
The Lookalike Expansion Prompt

Forty rows copied with their source pages give the model a pattern to copy back, and the next ask turns that pattern into hundreds more. Debt starts with one cut.
The first delete happens before the 90-second check: any row with a blank Source URL, a dead link, or a Google results page in that column goes without reading further. Saves 90 seconds.
Prompt to copy
Here are 5 seed practices from my list: [paste 5]. Find 25 more Ohio single-location dental practices with 1-3 dentists that are like these but not on this already-found list: [paste names]. Same table, same rules: Practice | City | Website | Contact | Role | Source URL. One source URL per row, \"unknown\" where you cannot verify. Number the rows 41 to 65 and then stop.
Run it 24 times and the sheet reaches 600 raw rows, about 18 minutes of machine time across the whole run. What comes back is not proof.
Live web search can land on a practice's own site and hand over the page address. It cannot tell you whether the practice is still independently owned. It cannot confirm the named person still works there.
That gap is the reason every row carries a source column the reader can open, and the reason the 90-second check comes after this prompt rather than instead of it.
The 25-Row Batch Rule

Holding each reply to 25 rows is what keeps 600 rows arriving in one shape. The free plan's context is 27,000 tokens, roughly 12 pages, and it holds the pasted seeds and the answer together.
Ask for 200 rows in one go and the seeds get pushed out first. By batch three the six columns no longer line up.
The fix is one message pasted into a fresh chat before any rows are asked for. It returns the brief, five of the 40 seeds and the format, so the model starts each batch from the same starting point.
Building that reset message once and reusing it is a job for a reusable prompt chain.
Prompt to copy
Brief: [niche paragraph]. Seed examples: [paste 5 of the 40]. Rules: 25 rows maximum per reply, table columns Practice | City | Website | Contact | Role | Source URL, \"unknown\" instead of a guess, and stop after 25 rows and wait for me.
Twenty-four batches at about 45 seconds of drafting each puts the machine side at 18 minutes in total. The payoff is 24 replies carrying identical columns, which is the one thing that lets the next step merge them without guessing.
Five terms this build keeps using
The Dedupe Prompt

Twenty-four clean batches still overlap heavily, so merge them before a single row is checked. The same practice arrives under two names and three cities: 'Akron Family Dental' and 'Family Dental of Akron' are one practice in one office.
Names and cities both move, so the website domain is the only dependable key. Two rows sharing a domain are one row. Two rows with the same phone number usually are too.
Paste two batches into one chat and run the merge prompt.
Prompt to copy
Here are two batches. Merge them into one table, drop any row whose website domain or phone number already appears, keep the row with the fuller contact, and tell me how many you removed and why.
The model only sees what you paste, so it cannot flag a practice sitting in a list from last month. That duplicate surfaces at the CRM import, where the domain key catches it again.
Two clean batches take about 5 minutes of review, and the removal count is worth keeping. It tracks how many duplicates the model is generating across the build.
💡 PRO TIP
Count the duplicates out loud
Write the number of removed rows at the top of every merged batch. If the count jumps suddenly, your last five seeds were too alike, and the next batch will repeat the pattern.
The Fit-Score Table

Six hundred rows all look the same size until they carry a score.
Five criteria, each rated 1 to 5: a single location, one to three dentists, a copyright year on the site older than 2022, a named decision-maker, and a spot within 30 miles of Columbus.
Paste the merged table into a fresh chat with this.
Prompt to copy
Score each row 1-5 on: single location, 1-3 dentists, site copyright year before 2022 if shown, named contact found, within 30 miles of Columbus. Add a Score column and a Reason column quoting the site. Sort highest first. Do not change any other field.
The answer comes back in about a minute for a batch of 100. The catch sits in the third criterion.
A stale site is a guess unless the footer actually shows a year, so that box stays at 3 when the year is missing, never at 5.
What comes out is a call order: the top 50 earn a phone call, and everything below earns the template email. Check the Reason column against the site before trusting any score.
The 90-Second Verification Pass

A score ranks a row and proves nothing about it. Three checks per row, in a browser, about 90 seconds each: the site loads, the practice is one location and not a chain, and the named person appears on the team page.
Nothing about that loop can happen inside the chat window.
In this example 4 rows in 5 survive it. Six hundred raw rows leave about 480 real contacts, and the checking runs about 15 hours, spread over the day in short sittings.
Skip it and the table lies to you. Every assistant states false facts with confidence and invents sources and links, so an unopened row is a guess wearing a table. The 480 that survive are the ones somebody typed into a browser and watched load.
Each row that passes gets a Verified column with today's date next to it. That date is the only column the outreach stage is allowed to read, which keeps the guesses where they belong.
⏱️ One batch, start to finish
Reanchor the chat
Paste the brief and five seeds into a fresh chat before adding the rules.
Draft 25 rows
The model returns a six-column table in about 45 seconds.
Delete bad sources
Remove any row whose Source URL is blank, broken or a search page.
Run the 90-second check
Open the site, confirm single location, find the person. About 37 minutes 30 seconds for 25 rows.
Dedupe and import
Merge against the last batch and load it into HubSpot. About 7 minutes.
Score and queue
Sort by fit score and send the top rows to calls, the rest to the template email.
The Role-and-Angle Map

The dentist count decides who reads the email. In a one or two dentist practice the owner opens it and decides alone.
In a practice with three or more, an office manager screens the inbox and forwards what matters. That means the subject line and the opening line have to change.
Prompt to copy
Group my verified rows by number of dentists. For 1-2 dentists, write a 10-word subject line aimed at the owner about their own name on the practice. For 3+, write one aimed at an office manager about the front-desk inquiry. Give one line of reasoning for each.
The answer arrives in roughly 30 seconds. The catch: dentist counts come back as unknown more often than you would like. Those rows go to the owner version rather than being thrown out, because a wrong guess costs less than a dropped contact.
Two angles, about 20 minutes to settle for all 480 rows. The whole list is covered before a single email goes out.
The Never-Paste List

Practice names, towns and public web addresses are the only things that belong in that window. Before the very first paste, open "Settings," then "Data controls," and switch off the option that lets your conversations train the company's models.
That switch is off by default on nothing, so it is the reader's job to flip it.
Addresses for a practice site are public and fine. Passwords, patient files, medical or billing details, and anything signed under a confidentiality agreement are not, whatever the pitch says the model can do with them.
Files are the other leak. On the free plan, anything you upload lands in a library that tops out at 500MB, so keep spreadsheets and PDFs out and paste the six columns as plain text instead.
That choice is a second reason to feed this build by hand.
Rows pasted as text, no patient names, no login details: the list stays a prospecting file on a work laptop, not a client-data incident waiting to be filed.
What the free tier clears and what it does not
- 🟢 Paste the niche paragraph — Public business category, city and size. Nothing personal in it.
- 🟢 Paste seed practice names and websites — All of it already public on the practice's own site.
- 🟢 Draft the email angles — Generic copy with a blank for the detail you saw yourself.
- 🟡 Paste a full batch of 25 rows — Fine on volume, but check you are still under the 12-page context.
- 🟡 Upload a client spreadsheet — The 500MB library is not the issue; what is inside the file is.
- 🔴 Paste a patient list or contact contract — Records of other people never enter the chat window.
- 🔴 Trust a named contact without the team page — The model invents people with total confidence.
The Three-Line First Email

The first message names one thing the reader saw with their own eyes.
Never send a claim that was not confirmed during the check, because the model will invent a broken booking page that does not exist, and the practice owner will open their own site and find it working fine.
The template: "Subject: the [practice] site on [phone] – Hi [name], I looked at [website] and the [booking page / service page] does not load on a phone, which is where most new-patient searches start. I rebuild sites like this for [city] practices at $3,500 flat. Worth 10 minutes to show you what I would change? – [name], [phone]."
Rewrite that first line for every row, in your own words, from what the browser showed. Send 480 rows with the same sentence and the replies dry up, because owners can tell a mail merge from a person who looked.
The payoff is speed with a reason behind it: about 40 seconds to personalize a send-ready email, instead of five minutes staring at a blank one.
What one giant ask costs you in the reply
Ask for 1,000 in one go
- Reply arrives with rows cut off at the context limit
- No source column, so nothing to re-check
- Duplicate practices across cities slip through
- Any invented page is sent as fact
- One bad batch, all 1,000 rows to redo
Cap each ask at 25
- Short reply you can read in one screen
- Source URL on every row or the word unknown
- Row fails the check, you drop just that batch
- Dedupe by domain before the CRM import
- About 45 seconds of ChatGPT per batch
The Two Follow-Ups

Two more messages, both written before the first email leaves, so the reader never has to think up a follow-up mid-send.
Here is bump: Following up on the [practice] site note – the mobile booking page still is not loading. Want me to send a 60-second screen recording?
And the last one, which gives the contact a clean way out: Last note from me – I will assume the timing is not right. If the front desk starts losing bookings, reply to this and I will pick it back up.
Space them five business days apart, and send nothing after the second. Only follow up on rows checked in the last 30 days, or a contact who switched practices last month gets chased at a job they no longer hold.
Three touches per contact, fixed in advance. Sending becomes mechanical, and nothing is improvised at 9pm with a list still open.
The HubSpot Free CRM Import

Sends and replies need a home that survives a cleared chat window, and HubSpot's free CRM does that at $0.
Set up the import with nine columns: practice, website domain, city, contact name, role, fit score, source URL, verified date and first-send date.
Sketch the header row once in a sheet, in that order, then map each header to the matching field in HubSpot.
The domain column does the quiet work. HubSpot's free CRM treats the website domain as its duplicate key, so re-importing a batch updates the rows you already have instead of doubling them.
Run the same batch twice on purpose and watch a list of 200 stay at 200.
Check before you scale: free-CRM limits change, so check HubSpot's own pricing page before planning a list size around it.
After that, the list outlives the laptop, the browser and the person. Hand a colleague the login and they see every verified date and first-send date, not a pile of tabs.
The Weekly 250-Row Cadence

A stored list becomes a weekly number, and the number that decides everything is 250 raw rows a week. That is 10 batches. ChatGPT drafts all 10 in about 7 minutes 30 seconds.
Then the work starts. Ten batches at 25 rows and 90 seconds a row is about 6 hours 15 minutes of checks. Merging duplicates and importing adds about 1 hour 10 minutes. Each week keeps roughly 200 contacts.
Five passes at that size is about 1,250 raw rows and roughly 38 hours in total. Under 40 minutes of the 38 is the model typing. So a thousand kept contacts takes about five weeks of steady evenings, not one long night.
The failure mode is the honest one. Skip the check on a busy week and the rows sit unopened in the CRM. A list of 3,000 unverified rows books fewer calls than 300 that someone actually opened.
Write week one's 250 on the calendar before you start. A pace that holds for five weeks beats a weekend burst that dies in the second one.
The Build at a Glance
📄 Free-plan ceiling
27,000 tokens, about 12 pages
✂️ Stop and split at
25 rows per answer
🚫 Kill rule
No URL means unknown, not a guess
🔒 Save before week one
Turn off training in Settings and Data controls
🗑️ If a row fails the check
Drop it, do not patch it
⛔ Skip this build if
You cannot protect 6 hours a week
Ten-batch week
7 minutes 30 seconds of drafting, 6 hours 15 minutes of checks, 1 hour 10 minutes of dedupe and import, about 200 kept.
The Free-vs-Paid Line

Only when the free caps actually interrupt the work. Until then, ChatGPT Free covers the build: $0 a month, unlimited text chats, live web search and enough room for ten 25-row batches a week.
The catches are small and visible. Ads can sit in a sponsored section below answers, and ad-free use means reduced message limits. Neither stops a 250-row week.
Go at $8 a month adds more messages, uploads, image creation and longer memory. Plus at $20 a month, no annual billing option, adds deeper research, projects and custom GPTs.
Pro starts at $100 a month. Custom GPTs and the AI Lead Scout plugin need a paid plan, and the plugin needs its own account.
If drafting is the bottleneck, outside options run cheaper. Apify's Niche B2B Lead Finder starts at $5.00 per 1,000 B2B leads, HubSpot's free CRM stores the results, and Clay's Launch plan at $167 a month billed yearly only makes sense once a team is involved.
Its free plan covers 6,000 AI actions a year.
Rule of thumb: stay on Free until two weeks in a row hit the message or upload cap. Then buy Go, not Plus.
Frequently Asked Questions
Do I need to pay for ChatGPT to do this?
No. ChatGPT Free costs $0 a month and has unlimited text chats plus live web search. The build fits inside the free plan as long as you hold each reply to 25 rows and do the verification yourself.
How long until I have 1,000 leads?
About five weekly passes of 250 raw rows, which works out to roughly 38 hours of work in total. Only under 40 minutes of that is the model typing the rest is your checking, dedupe and import time.
Why only 25 rows per batch?
The free plan's context window is 27,000 tokens, which OpenAI puts at about 12 pages. Seeds plus a long reply push the instructions out, and the columns start collapsing around batch three.
Can ChatGPT find me email addresses?
It will produce addresses, but you cannot trust them without opening the practice's own site and finding the person yourself. Treat every contact field as unknown until your 90-second check confirms it.
Is it safe to paste my client list into the chat?
No. Paste business names, cities and public website addresses only. Passwords, patient records, medical and financial details stay out, and switch off model training under Settings and Data controls first.
What if my niche is not dentists?
Change four things in the brief: who they are, where they are, how big they are, and what you sell at what price. Every prompt in the build reopens with that same paragraph, so nothing else needs rewriting.
Run It Free This Week, Buy Go Only When It Stalls
Run the whole build on ChatGPT Free this week. Move to Go at $8 a month only when two straight weeks stall on message or upload caps. Skip Plus unless you actually want custom GPTs or the paid AI Lead Scout plugin.
Tonight, do one thing. Paste the niche paragraph, pull the first 25 rows, and spend the 90 seconds per row before you write a single email.
The free plan will still hand over a gleaming table of 1,000 practices on request. The difference is that about 480 of these have been opened, dated and kept.
Its 40 minutes were never the valuable part, and that is why this list answers the phone.