Skip to main content
What's actually running

One pipeline, four stages, no seams between them.

Most cold email tools are a UI wrapped around someone else's list and someone else's sending API. outreachstack owns the data supply, the domain infrastructure, and the send engine, so each stage feeds the next instead of stopping at an integration boundary.

01
Supply

The domain dataset

343M domains across ~1,570 zones, refreshed with ~300k new registrations and ~250k drops daily. An ICP is a structured, versioned filter over this dataset — TLD, country, ASN, tech stack, registration-age window, email provider, MX/TXT signals — never a freeform prompt, always something a human can inspect and edit.

02
Domains

Self-provisioning sending infrastructure

Domain purchase, MX/SPF/DKIM/DMARC records, and mailbox connection are API-driven, backed by Cloudflare's DNS API — never a runbook. A warmup ramp runs on a schedule with hysteresis so volume only ever increases along the approved curve.

03
Send

A scheduler that treats correctness as non-negotiable

Send scheduling lives in Postgres, not a queue — rows claimed with SELECT ... FOR UPDATE SKIP LOCKED under per-mailbox rate limits and business-hours windows in the lead's own timezone. A reply halts every pending step for that lead across every campaign before the next send fires, enforced by a database constraint and a claim-time recheck, not just an event handler.

04
Deliverability

Reputation as a monitored system, not an afterthought

Bounce rate, complaint rate, blocklist status, seed-inbox placement, and DMARC aggregate reports feed a control loop every 15 minutes. It throttles, rotates to a healthier mailbox, or pauses a domain — every action logged with the input snapshot that triggered it.

ICP dimensions

An audience is a filter, not a list you bought.

Every dimension below is queryable against the live domain dataset, and every campaign's audience traces back to the exact version of the criteria that produced it — which is what lets the refinement loop attribute a reply-rate change to a specific slice instead of guessing.

  • TLD
  • Country
  • ASN
  • Tech stack
  • Registration age
  • Email provider (MX/TXT)
  • Headcount
  • Industry
Closing the loop

The audience and the message both learn from replies.

A bandit optimizer tunes the message, rewarded on positive reply rate. A separate refinement agent tunes the audience — decomposing outcomes across every ICP dimension, proposing narrowing where a slice underperforms with evidence attached, and proposing lookalike expansion where positive replies share an attribute the ICP doesn't yet filter on. It proposes, it never mutates a live ICP, and a proposal that would shrink the reachable universe below your committed send volume is blocked outright.

Where it runs

EU-hosted, and specific about what that covers.

outreachstack is hosted in the European Union. The application, Postgres, the domain lake and object storage all run on Hetzner infrastructure inside the EU, and tenant data — leads, message bodies, reply history, analytics — is not replicated outside it.

Application and databases
Hetzner, EU region. Postgres for operational data with row-level security per tenant; a ClickHouse lake for the domain dataset and event history; object storage for exports and attachments.
Tenant isolation
Row-level security in Postgres, enforced at the database rather than in application code, so a query written wrong fails closed.
GDPR posture
Per-lead lawful basis and provenance are tracked as data, and erasure cascades across both the operational database and the analytics lake — not just the row a support ticket points at.
The honest caveat
Model inference is routed through OpenRouter, which may execute a request on a provider outside the EU. We would rather write that down than let you discover it. An EU-only routing policy is on the roadmap and is not shipped yet.
Integrations

What it plugs into.

Everything below is reachable from the API and the CLI as well as the dashboard — there is no connector that only exists behind a click.

Google Workspace
Bring your own mailbox over OAuth; sending and reply ingestion via the Gmail API.
Microsoft 365
Bring your own mailbox over OAuth; sending and reply ingestion via Microsoft Graph.
SMTP / IMAP
Any other provider, for teams who do not want to hand over an OAuth grant.
Cloudflare DNS
Backs domain provisioning — MX, SPF, DKIM and DMARC records are written through the DNS API, not by hand.
OpenRouter
Model access, deliberately model-agnostic. Model choice is a per-task policy with a fallback list, never a constant compiled into the product.
API, CLI and MCP
A single /api/v1 surface with scoped, tenant-bound keys. Long-running work returns a job envelope an agent can poll, and anything that spends money or sends mail accepts dry_run=true.