Mert Ozcetin
Available for AI roles · Mert’s timePORTFOLIO — 2026

Case study

Outreach engine

Finding businesses is easy. Finding ones you are allowed to approach, and can prove are still there, is the actual work.

Any tool can return a thousand companies. The hard part is that most of them are wrong in ways a list cannot show you.

Some are out of policy and nothing on their listing says so. Some closed eighteen months ago. Some are run by a person who left. A list that hands you all thousand has moved the work rather than done it, and every bad lead in it costs a real message to a real person.

This engine is built around that. Ten services, seventeen niches, fifty states, and a pipeline whose whole design is refusing to put a lead in front of a human until it has earned the place. It sources, checks, ranks, drafts, and remembers. It never sends anything.

  • 72business owners found, each with a verified profile
  • $0.13total spend for that run, across six searches
  • 2blocked by the policy gate before a human saw them
SOURCESExa · Places · OvertureINTAKEvalidate · dedupeNAME RULESevery lead, firstPOLICY GATEreads their own pagesVERIFYtrading? role current?BOARDone card per leadDRAFTdossier · Loom · InMailSYNC BACKwho was already workednever contacted twice

The dashed line is the part that took longest to get right. Without it the engine produces leads and learns nothing.

  • The quota was the product decision

    The old people-search returned a hard 100 results a month, so an API quota — not the market, not the offer — decided how many businesses could be approached. Swapping it for a semantic search index that returns 8 to 15 owners per query at about two cents moved the ceiling to something real: how many owners of that kind actually exist. A limit you can feel in the product is a design problem, not a billing one.

  • Gate before you spend

    Checks are ordered by what they cost. Reading a business name is free, so the rules that can reject a lead outright run first. Fetching and reading a company’s catalogue pages is several requests, so it runs last and only on what survived. Getting those two in the wrong order is the difference between a sweep that finishes and one that does not.

  • Three verdicts, not two

    The policy gate returns clean, blocked, or needs-review. The third one is the point. A binary check forces a guess on every ambiguous case, and the ambiguous cases are exactly the ones a person should decide. So the middle is surfaced with the reason attached and a human rules on it. The engine is never the one that decides a close call.

  • A failed fetch is not a pass

    If the site is dead, blocked, or renders only in JavaScript, the verdict is needs-review — never clean. Recording an unread page as clean is absence of evidence read as evidence of absence, and it is the most expensive bug this class of tool can have, because it looks exactly like success.

  • Close the loop or learn nothing

    The board is the record of what happened to each lead, and for a long time nothing read it back. So the pipeline had no memory: run it next month and the same businesses resurface with no sign anyone had already been contacted. The sync is read-only and one-directional by design — stage changes are a human judgement, and the engine’s job is only to remember them.

  1. 01

    Choose the niche

    One registry holds 17 niches across 50 states: which categories to search, which job titles count, and which policy gate that niche needs. Adding a niche is one entry, not a code change.

  2. 02

    Find the owners

    A semantic search index returns public professional profiles for a plain-English query. Each result carries the person, their title, their company, their city and their following, so one call produces qualified leads rather than names to chase.

  3. 03

    Take them in

    Both the automatic source and a hand-typed one write the same file, so everything downstream is source-agnostic. Malformed rows are rejected by spreadsheet line number. Anyone already worked is suppressed.

  4. 04

    Apply the name rules

    The cheapest check runs on every single lead before anything is fetched.

  5. 05

    Run the policy gate

    For niches that need it, read the company’s own product and catalogue pages and decide from what they actually sell, not from how they are categorised.

  6. 06

    Prove they are trading

    DNS records, mail servers, a live read of the site, and the business’s public map status. A company that still runs email is almost certainly still operating.

  7. 07

    Prove the person is still there

    The profile URL is checked for a real 404 rather than a refusal, and the person’s current roles are checked against the company we think they run.

  8. 08

    Rank and explain

    Every lead is scored and every score prints its reasons. Suppression counts print even at zero, because a silent filter is indistinguishable from a broken one.

  9. 09

    Draft

    From the fetched site: a research dossier, a short first-touch message, and a longer one sized to the platform it is going to. Nothing invented, everything traceable to a page that was actually read.

  10. 10

    Remember

    The board is read back into the repo so next month’s run cannot resurface someone already contacted.

ServiceWhat it answersBudget
Semantic search indexWho owns a business like this?~$0.02 per search
Google PlacesIs it trading? How big? What time zone?1,000 / month
Overture MapsFree, uncapped place datano key, no cap
Page readerWhat does this company actually sell?1,000 / month
Person data APIDoes this owner still hold the role?100 / month
Two email findersA work address, stacked and verified125 / month
ClaudeWrites the dossier and the outreachper draft
ClickUpThe board, and the system of recorduncapped

Every one is wired as a direct API — a key and a small script, not a plugin. It loads no tool schemas into context, it can be budget-guarded per service, and each integration leaves a written reference behind. The engine uses no plugin servers at all, and that is a decision rather than an omission.

The list of things this engine will not do is longer than the list of things it will, and that is deliberate.

It will not invent a company name. If a profile does not clearly state one, the field is left blank and the lead is rejected on the way in rather than mailed to somebody. It will not treat a page it could not read as a page that was fine. It will not rule on a close call — those come back marked, with the reason, for a person to settle.

It will not claim someone has left a company on weak evidence, because the platform returns the same refusal code for a deleted profile and for a request it simply did not like. And it will not send anything. No automated messages, no dialler, no posting. Every path ends at a file or a card that a human opens first.

One bug from this build is worth stating plainly. The name rules originally ran inside the website check, which needs a domain — and leads from the new source arrive without one. So the cheapest and most important check in the pipeline was silently skipped for an entire source, and two out-of-policy brands reached the output marked clean. It was caught by reading the results of a real run rather than by a test. The rules now run first, on every lead, before anything else.