One domain in.
Full outreach out.

Type a seed domain. The pipeline finds lookalike companies, surfaces decision-makers, resolves verified emails, and sends personalised outreach — autonomously.

01 Apollo.io Queued
seed domain → lookalike company domains
02 Prospeo Queued
domains → C-suite / VP-level contacts + LinkedIn URLs
03 Prospeo Queued
LinkedIn URLs → verified work emails
04 Brevo Queued
verified emails → personalised outreach sent
Safety Checkpoint
Review before anything sends. This is the only manual step.
Dry-run active — emails will be simulated, nothing will leave your account.
#NameTitleCompanyEmailStatus
Pipeline complete

One input. Four stages.
A full outreach engine.

Every stage's output is the next stage's input. No human touches the data between them — that handoff-free chain is the entire point.

outreach — seed-input

Built for production,
not just demo day.

Six design decisions that separate a real pipeline from a script that strings four API calls together.

Resumable runs
State is checkpointed after every stage. Crash or abort — resume with --resume <id> and pick up exactly where you left off without re-spending credits.
Typed pipeline
Each stage transforms one Pydantic model into the next: domain → Company → Prospect → Contact → EmailResult. Malformed data is caught at the boundary, not inside the send loop.
Rate-limit resilience
Exponential backoff with jitter. Respects Retry-After headers. Only retries transient failures — 4xx errors fail fast so no credits are wasted.
Safety checkpoint
Sourcing and sending are split on purpose. The full recipient list — name, title, email, verification status — is shown before the one irreversible action fires.
Suppression list
Every address that gets a real send is recorded globally across all runs. Re-run the same seed domain tomorrow — nobody receives a second cold email.
Full mock mode
The entire end-to-end flow — safety checkpoint, logs, summary — runs offline with zero API keys via --mock. Demo anywhere, any time.

Common questions.

Stages 1–3 run against real APIs (Apollo.io and Prospeo) so you get real company and contact data. Stage 4 (Brevo) is simulated — emails are constructed and logged but nothing is sent. Perfect for verifying the sourcing before committing to a real send.
The shared HTTP client retries 429s with exponential backoff + jitter, reading the server's Retry-After header first. 4xx errors (bad key, bad filter) fail fast — retrying a real error just wastes credits.
No. Every address that receives a real send is added to a global suppression list in runs/suppression.json. Stage 3 filters against it before adding anyone to the send queue — even across completely separate runs and seed domains.
State is written to runs/<run-id>/state.json after each stage. Run python run.py --domain example.com --resume <run-id> to continue without re-spending any credits. The safety checkpoint is also a natural resume point.
Yes. Set EAZYREACH_MOCK=true in .env and the pipeline generates realistic email addresses from the person's name and company domain. The mock client is also what powers Mock mode in the web UI — great for demoing the full flow before credits are activated.
05 · THE VISION

The autonomous
outreach stack.

One seed domain in, personalised outreach out — sourcing, decision-maker discovery, email resolution and sending, with zero humans in the loop.