DEV Community

Benny
Benny

Posted on

Leadfinder: evidence-backed WhatsApp pitches for Lagos freelancers, on Gemma for $0.32 per 1,000 leads

Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle Submission 💸

This is a submission for the Hacktoberfest Open-Source AI Challenge Week 2: Side Hustle

What I Built

Cold pitches in Lagos fail because they say nothing

Freelancers in Lagos who sell to local businesses (video editors, web designers, social media managers) find most of their clients one WhatsApp message at a time. Most of those messages look the same:

"Hi, I edit videos, let me know if you need anything."

They get ignored.

A pitch that gets a reply needs a reason something specific and true about that business, that the owner can check in ten seconds. Finding that reason by hand means opening the Maps listing, the website, the reviews, and thinking.

Do that for 20 businesses and your evening is gone.

Leadfinder does the looking

Leadfinder is one search box:

  • Type "event centers in Lekki" and it searches Google Maps.
  • Type a website or business name, and it audits that one business.

Leadfinder getting you event centres in Lekki

Every business gets a score from 1 to 5, a list of evidence (problems, things that passed, things it couldn't check), and a top reason to pitch. You save the good ones to a board and move them through a series of tasks till it is won or lost.

Open a saved lead, and Gemma reads the website and the business's lowest-rated Google reviews, then writes a 50–125 word pitch. The pitch opens with one problem the owner can verify, says why it matters to their customers, and ends with one question. You can then use the Open in WhatsApp to send a message.

Gemma audit of the site

You can also move leads to Pitched sets and set a follow-up reminder for three days later.

Who pays? Freelancers who sell services to local businesses and are tired of sending messages nobody answers.

Demo

Live app: https://leadfinder-9aep.onrender.com

You can create an account and test or..

Just use this email and password. Click to reveal more..

Email: TestJudge@gmail.com
Password: 1234567890

Here is a demo video.

Code

GitHub logo Bennykillua / leadfinder

Find local businesses, see what's weak about them online, and send evidence-based WhatsApp pitches. Gemma does the thinking.

leadfinder

A lead finder for freelancers in Lagos who sell to local businesses: video editors, web designers, social media managers. Search for businesses, see what's weak about each one online, save the good ones to a board, and work them from first pitch to won, one WhatsApp message at a time.

Gemma (open-weight) does the thinking: it reads each business's website, judges how good a lead it is for your offer, and writes a short pitch where every claim comes from evidence the business owner can check.

What it does

  • Find: one text box. Type "salons in Yaba" to search Google Maps (via SerpApi), or a website / business name to audit it.
  • Audit: code checks the site (down, no HTTPS, not mobile-friendly, stale content, no contact path, no video, weak Google reviews, PageSpeed scores), then Gemma reads the page text and spots what rules can't.
  • Board: Saved → Pitched…

How I Built It

Code finds the facts, but Gemma reads them

I didn't want a model guessing what's wrong with a business. So the work is split.

Code checks facts. The crawler (SerpApi) reads the homepage and contact page (10-second timeout, robots.txt respected), and deterministic checks turn into evidence: no website, site down, no HTTPS, no mobile viewport, Google PageSpeed scores, stale content, no contact path, a WhatsApp button pointing at a placeholder number, no video, weak Maps presence.

SerpApi is a real-time API to access Google search results. We handle proxies, solve captchas, and parse all rich structured data for you.

Gemma does the three jobs code can't:

  1. Read the site, not just check it. It gets about 1,800 characters of page text, the business's worst reviews and the check results, and returns up to three findings the checks missed.
  2. Judge fit for this user. "No video anywhere" is the lead for a video editor and noise for a web designer. The score and top reason are for the person using the app.
  3. Write the pitch from the evidence gathered.

Every answer gets checked before you see it

Small models make things up, so nothing Gemma writes goes straight to the screen. Every reply is validated with zod, then checked by rules in code:

  • Every pitch must cite evidence IDs, and its opening must say what that evidence says.
  • Numbers about the business (ratings, review counts, scores, years) must appear in the cited evidence.
  • Quotes from reviews must be exact.
  • No hard-sell words, no lists of services, one question at the end, and no compliment unless a passed check or a good review backs it.

A rejected answer gets one retry with the reason fed back. If the retry fails too, the parts that pass are kept and the rest is dropped. Every call is logged with tokens, latency, cost and whether it passed on the first try.

The bugs that taught me the most

  • Gemma got stuck repeating itself. Ollama kept aborting with "token repeat limit reached". The cause: newer Ollama versions turn repeat_penalty off by default. Setting every option explicitly fixed it.
  • My validator was too strict. It rejected "1 quick question" because "1" wasn't in the evidence. Now it only checks numbers about the business.
  • The model copied my example pitch about couples booking a venue, word for word, for an apartment. Examples in prompts are dangerous with small models.
  • My first Render deploy failed because the database connection opened at import time, and Render doesn't mount the disk during the build. Opening it on first query fixed it.

Stack

Next.js, TypeScript, Tailwind, shadcn/ui, Motion, SQLite with Drizzle, zod. Gemma runs through Ollama on my laptop and OpenRouter in production; one setting switches between them. SerpApi for Google Maps search and reviews. Render for hosting.

Lastly, the type-and-it-becomes-a-card search box is inspired by Shapeshift (MIT).

What isn't done yet

The audit only crawls two pages, and checks like booking forms, prices, and link previews aren't built. I also tested a second mode, "find people who are already looking for a video editor", using SerpApi's Google Jobs and LinkedIn results. 10 Google Jobs results for Lagos gave about 2 strong freelance fits, which was very promising.

Why Does Open Innovation Matter?

1. Because the AI has to cost almost nothing

My users are Lagos freelancers. They won't pay much, and every search means auditing 10 businesses, plus a pitch (often rewritten) for every lead they save. If the AI cost scales with every rewrite, the business doesn't work.

So I measured it. Same 8 real leads, same prompts, same checks:

Model Deep read: passed / first try Pitch: passed / first try Per 1,000 leads
gemma-3-4b (OpenRouter) 50% / 0% 63% / 38% $0.21
gemma-3-12b (OpenRouter) 75% / 25% 67% / 67% $0.23
gemma-3-27b (OpenRouter) 100% / 13% 100% / 88% $0.32
qwen3-32b (OpenRouter) 100% / 50% 100% / 100% $0.27
gemma3:12b (Ollama, my laptop) 100% / 63% 100% / 100% $0

On almost the same token volume, Claude Sonnet 5.5 would cost about $8.34 per 1,000 leads and GPT-5.4 about $11.05 (published prices, checked 16 October 2026; approximate, since tokenizers differ). Gemma 27B does it for $0.32, roughly 26 to 35 times cheaper. At that price, the AI isn't the expensive part of my product anymore. The SerpApi searches are.

2. Because I could switch models with one setting

That table took one command. The model name is an environment variable, so comparing five setups cost me under a cent. I picked gemma-3-27b for production because it passed every check on every lead.

3. Because I'm not stuck with one host

The most interesting row is the last one. The same Gemma 12B that OpenRouter rate-limited and timed out on passed 8 out of 8 on my own laptop, with the best first-try rate in the table. Open weights meant that when a host failed me, I could just run the model myself.

4. Where closed models might win

To be fair: small open models needed a strict validator and a retry to be trustworthy. A big closed model might pass on the first try more often. I didn't test that. My bet is that a validator I control, plus a model 26 times cheaper, beats paying more and hoping. And to be clear on privacy: in production, business data passes through OpenRouter to a model host, so I'm not claiming it never leaves my server. The data is public business information anyway.

My Agent Session

https://dev.to/agent_sessions/catching-a-stale-build-instruction-before-it-wiped-out-real-storage-cz3suy

My First User

I sent it with a friend, Chinemerem. She works as a marketing lead. According to her, the experience is smooth, and she was able to find a list of companies and even discover new places around me. Her fav features were the board management and how she can more easily send and manage lead interactions.

She, however, felt sales would appreciate this better.

Another friend also tried it out.

So create an account and give it a try

Sign up

Prize Categories

  • Best Use of Gemma: Gemma reads every site, judges fit, and writes every pitch, locally through Ollama and in production through OpenRouter.
  • Best Use of Render: The app, login, and SQLite database run on a Render web service with a persistent disk.
  • Best Use of SerpApi: Google Maps search and name lookups, plus Google Maps Reviews for the lowest-rated reviews Gemma reads.

Who built it?

I built it myself

Top comments (0)