{"repo":"eracle/OpenOutreach","free":true,"listed":false,"github":"https://github.com/eracle/OpenOutreach","clone":"git clone https://github.com/eracle/OpenOutreach.git","description":"Agentic Email Automation Tool: Describe your product. Define your target market. The AI finds the leads for you.","language":"Python","stars":2712,"topics":["agent","agentic","agentic-marketing","agentic-workflow","automated-outreach","automation","cold-email","cold-email-agent","cold-email-ma","email-automation","email-marketing","llm","marketing","marketing-automation","marketing-outreach","outreach","smtp"],"license":null,"category":"saas_starter","readme_excerpt":"![OpenOutreach Logo](docs/logo.png)\n\n> **Describe your product. Define your target market. The AI finds the leads and emails them for you.**\n\n<div align=\"center\">\n\n[![GitHub stars](https://img.shields.io/github/stars/eracle/OpenOutreach.svg?style=flat-square&logo=github)](https://github.com/eracle/OpenOutreach/stargazers)\n[![GitHub forks](https://img.shields.io/github/forks/eracle/OpenOutreach.svg?style=flat-square&logo=github)](https://github.com/eracle/OpenOutreach/network/members)\n[![License: GPLv3](https://img.shields.io/badge/License-GPLv3-blue.svg?style=flat-square)](https://www.gnu.org/licenses/gpl-3.0)\n[![Open Issues](https://img.shields.io/github/issues/eracle/OpenOutreach.svg?style=flat-square&logo=github)](https://github.com/eracle/OpenOutreach/issues)\n\n<br/>\n\n# Demo:\n\n<img src=\"docs/demo.gif\" alt=\"Demo Animation\" width=\"100%\"/>\n\n</div>\n\n---\n\n### 🚀 What is OpenOutreach?\n\nOpenOutreach is a **self-hosted, open-source, email-first AI sales agent** for B2B lead generation. It discovers leads from a **licensed data provider**, qualifies them on your own machine, and runs **agentic email outreach from a mailbox you own** — with **zero platform-ToS surface**: it is browserless, uses no social-network account, and does no scraping. Unlike other tools, **you don't need a list of profiles to contact** — you describe your product and your target market, and the system autonomously discovers, qualifies, and emails the right people.\n\n**How it works:**\n\n1. **You provide** a product description and a campaign objective (e.g. \"SaaS analytics platform\" targeting \"VP of Engineering at Series B startups\")\n2. **An LLM turns that into an ICP filter** and pages matching firmographic profiles from a **licensed discovery source** (BetterContact **Lead Finder**) — no emails yet, billed nothing\n3. **A model scores the profiles** (Gaussian Process Regressor on profile embeddings) so the expensive steps go to the most promising candidates first — explore/exploit over the pool\n4. **An LLM classifies** each candidate the model selects, and each decision is fed back into the model\n5. **Only the best-fit leads get a paid email lookup.** A confidence gate rations a work-email resolution (one credit per verified hit); a hit routes the lead into **agentic email** — an AI agent sends a personalized opener from your mailbox, then reads replies and runs multi-turn follow-up\n\nThe point of the scoring layer is cost: searching the licensed source is free, so the system can afford to look at a lot and spend paid lookups only on the best fits. *(The learning loop is an active experiment — it is not yet shown to beat picking at random, and no claim is made that it does.)*\n\n**Why choose OpenOutreach?**\n\n- 🧠 **Autonomous lead discovery** — No contact lists needed; AI finds your ideal customers from licensed data\n- 📧 **Email-first outreach** — Resolves a work email per qualified lead and sends from **your own mailbox**, at email volume\n- 🛡️ **Zero platform-ToS surface** — Browserless, no social-network account, no scraping — nothing to get banned\n- 💾 **Self-hosted + full data ownership** — Everything runs locally; browse your CRM in a web UI\n- 🐳 **One-command setup** — Dockerized deployment, interactive onboarding\n- ✨ **AI-powered messaging** — LLM-generated personalized outreach and agentic replies (bring your own model)\n\nPerfect for founders, sales teams, and agencies who want powerful automation **without account bans or subscription lock-in**.\n\n---\n\n## 💸 How OpenOutreach Stays Free\n\nOpenOutreach sends email from a mailbox **you own and control**, under your own sending identity. It sends **two kinds** of email, and you should know about both before you run it:\n\n- **Your outreach** — personalized emails to the leads *you* target, on your behalf, as part of your own campaigns. This is the whole point of the tool.\n- **A promotion for OpenOutreach itself** — the tool ships with a **freemium** campaign that **advertises OpenOutreach**, sent from your mailbox **as if from you**, to recipients unrelated to your own leads. It takes its turn in the sending rotation alongside your own campaigns, so a share of the sending is the project's rather than yours. This is one of the ways the project funds itself for cold-start users, alongside affiliate links and sponsorships.\n\nBoth kinds send from your mailbox under your identity, and both are your responsibility under anti-spam law. The freemium promotion has been part of the project since the beginning. On an install you run yourself it can be disabled by editing the source (the GPLv3 licence permits this). Full detail — how the rotation works, where the content comes from, what is and isn't logged, and your responsibilities — is in the **[Legal Notice](LEGAL_NOTICE.md)** (§4).\n\n---\n\n## 📋 What You Need\n\n| # | What | Example |\n|---|------|---------|\n| 1 | **An LLM API key** | OpenAI, Anthropic, or any OpenAI-compatible endpoint |\n| 2 | **An email-finder API key** ([BetterContact](https://bettercontact.rocks?fpr=openoutreach)) | Powers **both** discovery (Lead Finder) and enrichment (work-email resolution) |\n| 3 | **A sending mailbox** | An app password for a mailbox you own (Gmail / Workspace / own-domain SMTP), or cold-email infra like [IceMail](https://icemail.ai?via=openoutreach) |\n| 4 | **A product description + target market** | \"We sell cloud cost optimization for DevOps teams at mid-market SaaS companies\" |\n\nThat's it. No social-network account, no spreadsheets, no lead databases, no scraping setup. The BetterContact key and a connected mailbox are both required — the key drives discovery *and* enrichment, and the mailbox is where outreach is sent from.\n\nThe BetterContact and IceMail links above are **affiliate links** — signing up through them supports OpenOutreach, at no markup to you. You can sign up for either service directly instead; IceMail in particular is only a suggestion, since any SMTP mailbox you own works.\n\n---\n\n## ⚡ Quick Start (Docker — Recommended)\n\nPre-built images are published to GitHub Container Registry.\n\n```bash\ndocker run --pull always -it -v ~/.openoutreach/data:/app/data ghcr.io/eracle/openoutreach:latest\n```\n\nThe interactive onboarding walks you through the inputs above on first run — product/objective → LLM key (live-verified) → mailbox (paste an app password → SMTP auth-check) → BetterContact key → your email → country → newsletter/legal. All data persists in `~/.openoutreach/data` on your host across restarts. The image is a slim Python runtime — **no browser, no VNC**.\n\nFor Docker Compose, build-from-source, and more options see the **[Docker Guide](./docs/docker.md)**.\n\n---\n\n## ⚙️ Local Installation (Development)\n\nFor contributors or if you prefer running directly on your machine.\n\n### Prerequisites\n\n- [Git](https://git-scm.com/)\n- [Python](https://www.python.org/downloads/) (3.12+)\n\n### 1. Clone & Set Up\n```bash\ngit clone https://github.com/eracle/OpenOutreach.git\ncd OpenOutreach\n\n# Install deps, run migrations, and bootstrap CRM\nmake setup\n```\n\n### 2. Run the Daemon\n\n```bash\nmake run\n```\nThe interactive onboarding prompts for your LLM key, mailbox, BetterContact key, and campaign details on first run. Fully resumable — stop/restart anytime without losing progress.\n\n### 3. View Your Data (CRM Admin)\n\nOpenOutreach includes a full CRM web interface via Django Admin:\n```bash\n# Create an admin account (first time only)\npython manage.py createsuperuser\n\n# Start the web server\nmake admin\n```\nThen open:\n- **Django Admin:** http://localhost:8000/admin/\n\n---\n## ✨ Features\n\n| Feature                            | Description                                                                                                          |\n|------------------------------------|----------------------------------------------------------------------------------------------------------------------|\n| 🧠 **Autonomous Lead Discovery**   | No contact lists needed — an LLM turns your product + objective into an ICP filter and pages matching profiles from a licensed discovery source. |\n| 🎯 **Pay Only For What Resolves**  | Search against the licensed source is free; a confidence gate rations the paid lookups, billed only on a verified hit. Cost scales with qualified leads, not with how much you searched. |\n| 🔒 **Licensed Discovery**          | Firmographic profiles come from a paid, licensed provider (BetterContact Lead Finder) — no scraping, no browser, no account. |\n| 📧 **Agentic Email Outreach**      | Resolves a work email per best-fit lead (one credit per hit), sends an AI-written opener from your own mailbox over SMTP, then reads replies (IMAP) and runs multi-turn follow-up. |\n| 🔄 **Stateful Pipeline**          | Tracks deal states (`QUALIFIED` → `READY_TO_FIND_EMAIL` → `FINDING_EMAIL` → `READY_TO_EMAIL` → `EMAILED` → `COMPLETED`/`FAILED`) in a local DB — fully resumable. |\n| ⏱️ **Send-Gated Spend**           | Paid email lookups ride on send capacity — a per-mailbox daily cap bounds how many leads enter the pipeline, so you never resolve more than you can send. |\n| 🕗 **Sends On Your Hours**        | Cold email leaves Mon–Fri, 08:00–20:00 in your own timezone, spaced minutes apart from each mailbox. Replies are answered whenever they arrive. |\n| 💾 **Built-in CRM**               | Full data ownership via Django Admin — browse Leads, Deals, and conversations.                                     |\n| 🐳 **One-Command Deployment**      | Dockerized setup with interactive onboarding; a slim runtime with no browser and no VNC.                            |\n| ✍️ **AI-Powered Messaging**        | Agentic multi-turn conversations — the AI agent reads the thread and composes replies. Nobody is chased: it writes when they write back. |\n\n---\n\n## 📖 How the Pipeline Works\n\nThe daemon runs a short cycle that asks the deals what they need — there is no queue table and nothing is scheduled in advance. Each pass walks one ordered list and stops at the first thing it can do, so priority *is* that order:\n\n| # | St","default_branch":"main","files":247,"tree":[".dockerignore",".github/FUNDING.yml",".github/workflows/deploy.yml",".github/workflows/tests.yml",".gitignore","ARCHITECTURE.md","CLAUDE.md","LEGAL_NOTICE.md","LICENCE.md","Makefile","PRIVACY_NOTICE.md","README.md","compose/openoutreach/Dockerfile","compose/openoutreach/entrypoint","compose/openoutreach/start","data/.gitkeep","docs/architecture.md","docs/configuration.md","docs/default_campaign.md","docs/demo.gif","docs/docker.md","docs/logo.png","docs/outreach_agent.md","docs/profile_lifecycle.md","docs/template-variables.md","docs/templating.md","docs/testing.md","local.yml","manage.py","openoutreach/__init__.py","openoutreach/chat/__init__.py","openoutreach/chat/apps.py","openoutreach/chat/migrations/0001_initial.py","openoutreach/chat/migrations/0002_add_sync_fields.py","openoutreach/chat/migrations/0003_chatmessage_deal_fk.py","openoutreach/chat/migrations/0004_pivot_external_id.py","openoutreach/chat/migrations/0005_alter_chatmessage_external_id.py","openoutreach/chat/migrations/0006_remove_chatmessage_uniq_deal_external_id_and_more.py","openoutreach/chat/migrations/__init__.py","openoutreach/chat/models.py","openoutreach/contacts/__init__.py","openoutreach/contacts/service.py","openoutreach/core/__init__.py","openoutreach/core/admin.py","openoutreach/core/agents/__init__.py","openoutreach/core/agents/outreach.py","openoutreach/core/agents/prompt.py","openoutreach/core/apps.py","openoutreach/core/business_time.py","openoutreach/core/conf.py","openoutreach/core/cycle.py","openoutreach/core/db/__init__.py","openoutreach/core/db/deals.py","openoutreach/core/db/leads.py","openoutreach/core/db/summaries.py","openoutreach/core/geo.py","openoutreach/core/llm.py","openoutreach/core/logblock.py","openoutreach/core/logging.py","openoutreach/core/management/__init__.py","openoutreach/core/management/commands/__init__.py","openoutreach/core/management/commands/migrate.py","openoutreach/core/management/commands/reset_data.py","openoutreach/core/management/commands/reset_pipeline.py","openoutreach/core/management/commands/rundaemon.py","openoutreach/core/management/commands/setup_crm.py","openoutreach/core/management/setup_crm.py","openoutreach/core/migration_compat.py","openoutreach/core/migrations/0001_initial.py","openoutreach/core/migrations/0002_rename_engine_tables.py","openoutreach/core/migrations/0003_siteconfig_finder_api_key.py","openoutreach/core/migrations/0004_pivot_email_config.py","openoutreach/core/migrations/0005_rename_campaign_objective_campaign_campaign_target.py","openoutreach/core/migrations/0006_campaign_country_code_discoveryquery.py","openoutreach/core/migrations/0007_seed_frontier_drop_legacy_cursor.py","openoutreach/core/migrations/0008_clause_lattice.py","openoutreach/core/migrations/0009_remove_clause_is_live.py","openoutreach/core/migrations/0010_campaign_discovery_minted_at_qualified.py","openoutreach/core/migrations/0011_collapse_prescreen_empties.py","openoutreach/core/migrations/0012_campaign_anchor_embeddings_campaign_anchor_profiles.py","openoutreach/core/migrations/0013_keyword_querynode_remove_clause_uniq_clause_and_more.py","openoutreach/core/migrations/0014_delete_discoveryquery.py","openoutreach/core/migrations/0015_delete_task_drop_action_fraction.py","openoutreach/core/migrations/__init__.py","openoutreach/core/ml/__init__.py","openoutreach/core/ml/embeddings.py","openoutreach/core/ml/hub.py","openoutreach/core/ml/qualifier.py","openoutreach/core/models.py","openoutreach/core/onboarding.py","openoutreach/core/onboarding_wizard.py","openoutreach/core/operator.py","openoutreach/core/pipeline/__init__.py","openoutreach/core/pipeline/discover.py","openoutreach/core/pipeline/freemium_pool.py","openoutreach/core/pipeline/icp.py","openoutreach/core/pipeline/qualify.py","openoutreach/core/pipeline/ready_pool.py","openoutreach/core/pipeline/select.py","openoutreach/core/pipeline/top_up.py","openoutreach/core/pipeline/vocabulary.py","openoutreach/core/sending_window.py","openoutreach/core/setup/__init__.py","openoutreach/core/setup/freemium.py","openoutreach/core/templates/__init__.py","openoutreach/core/templates/prompts/anchor_profiles.j2","openoutreach/core/templates/prompts/icp_filters.j2","openoutreach/core/templates/prompts/outreach_agent.j2","openoutreach/core/templates/prompts/qualify_lead.j2","openoutreach/core/vendor/__init__.py","openoutreach/core/vendor/mem0/__init__.py","openoutreach/core/vendor/mem0/configs/__init__.py","openoutreach/core/vendor/mem0/configs/prompts.py","openoutreach/core/vendor/mem0/memory/__init__.py","openoutreach/core/vendor/mem0/memory/utils.py","openoutreach/core/version.py","openoutreach/crm/__init__.py","openoutreach/crm/apps.py","openoutreach/crm/migrations/0001_initial.py","openoutreach/crm/migrations/0002_rename_description_to_profile_data.py","openoutreach/crm/migrations/0003_public_identifier_unique.py","openoutreach/crm/migrations/0004_alter_deal_state.py","openoutreach/crm/migrations/0005_lead_urn.py","openoutreach/crm/migrations/0006_deal_summaries.py","openoutreach/crm/migrations/0007_drop_legacy_lead_fields.py","openoutreach/crm/migrations/0008_vacuum.py","openoutreach/crm/migrations/0009_outcome.py","openoutreach/crm/migrations/0010_deal_next_check_pending_at.py","openoutreach/crm/migrations/0011_repoint_campaign_fk_to_core.py","openoutreach/crm/migrations/0012_lead_api_email_lead_contact_info.py","openoutreach/crm/migrations/0013_alter_deal_state.py","openoutreach/crm/migrations/0014_pivot_lead_reshape.py","openoutreach/crm/migrations/0015_lead_discovered_by.py","openoutreach/crm/migrations/0016_alter_deal_state.py","openoutreach/crm/migrations/0017_migrate_no_email_failures.py","openoutreach/crm/migrations/0018_lead_source_fields_alter_lead_discovered_by.py","openoutreach/crm/migrations/0019_alter_deal_state.py","openoutreach/crm/migrations/0020_deal_not_before_and_lookup_handle.py","openoutreach/crm/migrations/0021_remove_deal_email_message_id_deal_thread.py","openoutreach/crm/migrations/__init__.py","openoutreach/crm/models/__init__.py","openoutreach/crm/models/deal.py","openoutreach/crm/models/lead.py","openoutreach/crm/models/to_translate.txt","openoutreach/discovery.py","openoutreach/emails/__init__.py","openoutreach/emails/admin.py","openoutreach/emails/apps.py","openoutreach/emails/bettercontact.py","openoutreach/emails/classify.py","openoutreach/emails/delivery_policy.py","openoutreach/emails/mail_pass.py","openoutreach/emails/migrations/0001_initial.py","openoutreach/emails/migrations/0002_mailbox_signature.py","openoutreach/emails/migrations/0003_alter_mailbox_daily_limit.py","openoutreach/emails/migrations/0004_alter_mailbox_daily_limit_sendverdict.py","openoutreach/emails/migrations/0005_mailbox_unsub_scan_uid_and_more.py","openoutreach/emails/migrations/0006_mailbox_next_send_at.py","openoutreach/emails/migrations/0007_deliveryevent_foldercoverage_message_thread_and_more.py","openoutreach/emails/migrations/0008_backfill_mail_log.py","openoutreach/emails/migrations/__init__.py","openoutreach/emails/models/__init__.py","openoutreach/emails/models/mailbox.py","openoutreach/emails/models/maillog.py","openoutreach/emails/newsletter.py","openoutreach/emails/parsing.py","openoutreach/emails/project.py","openoutreach/emails/report.py","openoutreach/emails/sender.py","openoutreach/emails/smtp.py","openoutreach/emails/steps/__init__.py","openoutreach/emails/steps/lookup.py","openoutreach/emails/steps/reply.py","openoutreach/emails/steps/send.py","openoutreach/emails/sync.py","openoutreach/emails/threads.py","openoutreach/emails/warmth.py","openoutreach/legacy/__init__.py","openoutreach/legacy/apps.py","openoutreach/legacy/migrations/0001_initial.py","openoutreach/legacy/migrations/0002_profile_self_lead.py","openoutreach/legacy/migrations/0003_siteconfig.py","openoutreach/legacy/migrations/0004_compress_campaign_model_blob.py","openoutreach/legacy/migrations/0005_remove_task_error.py","openoutreach/legacy/migrations/0006_update_default_limits.py","openoutreach/legacy/migrations/0007_siteconfig_llm_provider.py","openoutreach/legacy/migrations/0008_drop_connect_weekly_limit.py","openoutreach/legacy/migrations/0009_drop_legacy_pending_tasks.py","openoutreach/legacy/migrations/0010_move_engine_models_to_core.py","openoutreach/legacy/migrations/0011_pivot_drop_channel_models.py","openoutreach/legacy/migrations/__init__.py","openoutreach/legacy/models.py","openoutreach/settings.py","openoutreach/urls.py","pytest.ini","requirements/base.txt","requirements/crm.txt","requirements/local.txt","requirements/production.txt","tests/__init__.py","tests/agents/__init__.py","tests/agents/test_outreach.py","tests/conftest.py","tests/contacts/__init__.py","tests/contacts/test_service.py","tests/db/__init__.py","tests/db/test_deals.py","tests/db/test_summaries.py","tests/emails/__init__.py","tests/emails/fake_imap.py","tests/emails/maillog.py","tests/emails/test_bettercontact.py","tests/emails/test_classify.py","tests/emails/test_delivery_policy.py","tests/emails/test_lookup.py","tests/emails/test_mail_pass.py","tests/emails/test_mailbox.py","tests/emails/test_project.py","tests/emails/test_reply.py","tests/emails/test_send.py","tests/emails/test_smtp.py","tests/emails/test_sync.py","tests/emails/test_unsubscribe.py","tests/emails/test_warmth.py","tests/factories.py","tests/fixtures/pages/.gitkeep","tests/ml/__init__.py","tests/ml/test_embeddings.py","tests/ml/test_qualifier.py","tests/test_anchors.py","tests/test_business_time.py","tests/test_cycle.py","tests/test_db_option.py","tests/test_discovery.py","tests/test_discovery_wiring.py","tests/test_geo.py","tests/test_llm.py","tests/test_mail_log_backfill.py","tests/test_migration_compat.py","tests/test_onboarding.py","tests/test_onboarding_wizard.py","tests/test_qualify.py","tests/test_ready_pool.py","tests/test_reset_pipeline.py","tests/test_select.py","tests/test_sending_window.py","tests/test_version.py"],"storefront":"/r/eracle","claimed":false,"request_supported":{"post":"https://gitbuyer.com/r/eracle/OpenOutreach/request-supported","requests":0},"note":"indexed from public GitHub; nothing is for sale on this page. Clone it from GitHub. Paid listings live at /search."}