OpenOutreach

Self-hosted · GPL-3.0 · No account to get banned

Every lead arrives with the reason it was chosen.

Describe what you sell in a paragraph. OpenOutreach discovers people who match, has an LLM judge each one against that description, and writes down why — then opens the conversation from your own mailbox.

Finding is free Addresses cost 1 credit 40 free to start

The deliverable

Everybody exports rows.
Almost nobody exports why this person.

One command writes a CSV of every lead you have — shaped for the importers you already use, so Instantly and Smartlead read it without column mapping. The column that makes it worth reading is the last one you'd get anywhere else.

$ openoutreach find 10 emails > leads.csv Example export
Name Title Email Reason
Priya RamanLedgerwise VP Platform priya@ledgerwise.io Runs a 40-person platform team and has written publicly about migrating off a legacy APM contract this quarter — the exact trigger the target market describes.
Tom OkaforNorthbeam Pay Head of SRE t.okafor@northbeam.co PCI-scope payments infrastructure with two open SRE roles. Team size and compliance surface both match; budget authority sits with this title.
Dana WeissCorva Systems Director, Engineering Fits the ICP on stack and headcount, but no verified address was found. The row still exports — the person and the reasoning are not lost.
Columns: email, first_name, last_name, company, title, website, linkedin_url, reason, lead_id, qualified_at

No score column

On purpose. The model's confidence is a spend gate for the paid lookup, not a quality signal. The verdict is already there, as a sentence you can disagree with.

Correct it in English

Wrong leads mean a wrong description. You fix the paragraph, not a filter builder — there are no boolean rules to maintain.

Rejections never export

A "wrong fit" verdict and a permanent opt-out are both excluded from every file, always.

What one run actually does

Five stages, and only one of them bills you.

01

Describe

Two paragraphs, asked once: what you sell, and who it's for. This is the whole input — it seeds the opening search, trains the qualifier, and is what every message is written from.

Free
02

Discover

Candidates come from a licensed data provider. No browser, no scraping, no social-network account — there is no platform login to get banned, because there is no login.

Free
03

Qualify

An LLM judges every candidate against your description and writes the reason it passed or failed. Runs on your own provider key — OpenAI, Anthropic, Groq, or anything OpenAI-compatible.

Your LLM key
04

Enrich

The only paid step, and strictly opt-in. A bare find 10 cannot spend a credit no matter how many leads clear the gate; you ask for addresses explicitly, and the number you type is the ceiling on the invoice.

1 credit each
05

Send

An outreach agent writes the opener from the prospect's own profile — never from the reason, which is written for you, not them — and sends from your mailbox, inside your sending window and daily cap.

Your mailbox

The whole interface

Nine commands. No daemon, no dashboard, no queue to babysit.

Every verb is a bounded pass that prints and exits. State lives in one SQLite file, so stopping and restarting loses nothing — the number you ask for is always more than you already have.

openoutreach                  onboard if needed, then find and send
openoutreach run 5            ...with an explicit goal  ≤5 credits
openoutreach init             onboard only — nothing spent

openoutreach find 10          ten more qualified leads → CSV  free
openoutreach find 10 emails   ...carrying a verified address  ≤10 credits
openoutreach find 0           no work — re-print what you have  free

openoutreach send             mail what is already stored
openoutreach send 5           ...until five conversations are open
openoutreach status           what is configured, blocked and counted

Typed failures, not tracebacks

Anything short of the goal still prints its rows and exits non-zero with one line: error: goal_unreached, provider_rate_limited, onboarding_incomplete. Stable strings, meant to be branched on.

stdout is result-only

Leads on stdout, everything else on stderr — so > leads.csv is always correct, and --json gives you JSON Lines for anything programmatic.

Drives from your agent

Ships as a Claude Code plugin that knows which flags spend money and which cannot. Any agent can read the same contract and call the same commands.

How it's built

Three packages, one install.

The finding and the sending are two standalone programs with their own CLIs and their own test suites. The third hosts both in one process, one database and one onboarding — so you install once, answer once, and each half still runs alone if you'd rather wire it yourself.

openoutfind

Discovery, qualification, enrichment and the CRM. Decides who fits and writes the reason.

uvx --from openoutfind outfind find 10

openoutsend

The outreach agent, the mailbox, and the guards — sending window, daily cap, pacing, suppression.

uvx --from openoutsend outsend send

openoutreach

One install and one wizard over both. The only thing that remembers what you typed.

outfind find 50 --json | outsend

Before the first run

Four answers, asked once.

01 / Model

An LLM key

OpenAI, Anthropic, Groq, or any OpenAI-compatible endpoint. Verified at the prompt, so a wrong key is something you retype — not a run that dies an hour in.

02 / Data

A BetterContact key

Free account, 40 credits, no card. Powers discovery at no charge; one credit buys one verified work email, and only when you ask.

03 / Input

Your product and target

Two paragraphs of prose, passed as files rather than shell-quoted strings. Narrow them later by editing the words, not a query.

04 / Mailbox

A mailbox to send from

Its address and an app password. Google Workspace works out of the box; anything else names its SMTP and IMAP host. Checked by a real login before setup finishes.

Get started

One install, one wizard, one command.

Everything lives in ~/.openoutreach. No container to orchestrate, no service to keep alive, nothing to log into. Setup resumes wherever you left it.

$ uv tool install openoutreach
$ openoutreach