The open-source growth engine that puts your LinkedIn B2B lead generation on autopilot.
OpenOutreach is a self-hosted, open-source LinkedIn automation tool designed for B2B lead generation, without the risks and costs of cloud SaaS services.
It automates the entire outreach process in a stealthy, human-like way:
- Discovers and enriches target profiles
- Ranks profiles using ML (logistic regression + Thompson Sampling) for smart prioritization
- Sends personalized connection requests
- Follows up with custom messages after acceptance
- Tracks everything in a built-in CRM with web UI (full data ownership, resumable workflows)
Why choose OpenOutreach?
- π‘οΈ Undetectable β Playwright + stealth plugins mimic real user behavior
- π Fully customizable β Python-based campaigns for unlimited flexibility
- πΎ Local execution + CRM β You own your data, browse it in a web UI
- π³ Easy deployment β Dockerized, one-command setup
- β¨ AI-ready β Built-in templating for hyper-personalized messages (easy integration with latest models like GPT-5.3-Codex)
Perfect for founders, sales teams, and agencies who want powerful automation without account bans or subscription lock-in.
Get up and running in minutes by running the application directly on your machine.
- Git
- Python (3.11+ recommended)
venvfor creating virtual environments (usually included with Python)
git clone https://github.com/eracle/OpenOutreach.git
cd OpenOutreachIt's highly recommended to use a virtual environment to manage dependencies.
# Create the virtual environment
python -m venv venv
# Activate it
source venv/bin/activate # Windows: venv\Scripts\activateWe use uv for fast dependency management and DjangoCRM for the local database.
# Install deps, run migrations, and bootstrap CRM data
make setup
# Install required browser assets
playwright install --with-deps chromiumYou need to provide your LinkedIn credentials and target profiles.
-
Configure LinkedIn accounts + optional OpenAI key
cp assets/accounts.secrets.template.yaml assets/accounts.secrets.yaml
Edit
assets/accounts.secrets.yamlwith your credentials (and add your OpenAI key underenv:if you want AI follow-ups). -
Add target profiles Paste LinkedIn profile URLs into
assets/inputs/urls.csv.
make load CSV=assets/inputs/urls.csv # import URLs into CRM
make load CSV=assets/inputs/urls.csv HANDLE=myhandle # import for a specific accountmake run # run with first active account
make run HANDLE=myhandle # run with a specific accountThe daemon round-robins through four action lanes (enrich, connect, check pending, follow up) with configurable rate limits. Fully resumable β stop/restart anytime without losing progress.
OpenOutreach includes a full CRM web interface powered by DjangoCRM:
# Create an admin account (first time only)
python manage_crm.py createsuperuser
# Start the web server
make adminThen open:
- Django Admin: http://localhost:8000/admin/
- CRM UI: http://localhost:8000/crm/
We also support running the application via Docker. This is a great option for ensuring a consistent environment and simplifying dependency management.
For full instructions, please see the Docker Installation Guide.
| Feature | Description |
|---|---|
| π€ Advanced Browser Automation | Powered by Playwright with stealth plugins for human-like, undetectable interactions. |
| π‘οΈ Reliable Data Scraping | Uses LinkedIn's internal Voyager API for accurate, structured profile data (no fragile HTML parsing). |
| π Python-Native Campaigns | Write flexible, powerful automation sequences directly in Python. |
| π§ ML-Driven Prioritization | Logistic regression + Thompson Sampling ranks profiles by predicted connection acceptance -- learns and retrains as data grows. |
| π Stateful Workflow Engine | Tracks profile states (DISCOVERED β ENRICHED β PENDING β CONNECTED β COMPLETED) in a local DB -- resumable at any time. |
| β±οΈ Smart Rate Limiting | Configurable daily/weekly limits per action type, respects LinkedIn's own limits automatically. |
| πΎ Built-in CRM | Full data ownership via DjangoCRM with Django Admin UI -- browse Leads, Contacts, Companies, and Deals in your browser. |
| π³ Containerized Setup | One-command Docker + Make deployment. |
| π₯οΈ Visual Debugging | Real-time browser view via built-in VNC server (localhost:5900). |
| βοΈ AI-Ready Templating | Jinja or AI-prompt templates for hyper-personalized messages (plug in latest models like GPT-5.3-Codex easily). |
This project is built in spare time to provide powerful, free open-source growth tools.
Maintaining stealth, fixing bugs, adding features (multi-account scaling, better templates, AI enhancements), and staying ahead of LinkedIn changes takes serious effort.
Your sponsorship funds faster updates and keeps it free for everyone.
Popular Tiers & Perks:
| Tier | Monthly | Benefits |
|---|---|---|
| β Supporter | $5 | Huge thanks + name in README supporters list |
| π Booster | $25 | All above + priority feature requests + early access to new campaigns |
| π¦Έ Hero | $100 | All above + personal 1-on-1 support + influence roadmap |
| π Legend | $500+ | All above + custom feature development + shoutout in releases |
Thank you to all sponsors β you're powering open-source B2B growth! π
Got a specific use case, feature request, or questions about setup?
Book a free 15-minute call β Iβd love to hear your needs and improve the tool based on real feedback.
The daemon (linkedin/daemon.py) round-robins through four action lanes:
| Lane | What it does | Rate limited? |
|---|---|---|
| Enrich | Scrapes DISCOVERED profiles via LinkedIn's Voyager API | Throttled by batch size |
| Connect | ML-ranks ENRICHED profiles, sends connection requests | Daily + weekly limits |
| Check Pending | Checks if PENDING requests were accepted, retrains ML model | Age-gated |
| Follow Up | Sends personalized messages to CONNECTED profiles | Daily limit |
Profile states: DISCOVERED β ENRICHED β PENDING β CONNECTED β COMPLETED (or FAILED / IGNORED)
Pre-existing connections (already connected before automation) are automatically set to IGNORED during enrichment. If connection_degree was unknown at scrape time, they're caught during the connect step.
Configure rate limits, timing, and behavior in the campaign: section of accounts.secrets.yaml.
βββ analytics/ # dbt project (DuckDB analytics, ML training sets)
βββ assets/
β βββ accounts.secrets.yaml # Credentials + campaign config (gitignored)
β βββ data/ # crm.db (SQLite), analytics.duckdb
β βββ inputs/ # Target profile CSVs
βββ docs/
β βββ docker.md # Docker setup guide
β βββ ...
βββ linkedin/
β βββ actions/ # Browser actions (connect, message, scrape)
β βββ api/ # Voyager API client + parser
β βββ daemon.py # Main daemon loop (round-robin across lanes)
β βββ db/crm_profiles.py # CRM-backed profile CRUD (Lead, Contact, Company, Deal)
β βββ django_settings.py # Django/CRM settings (SQLite at assets/data/crm.db)
β βββ lanes/ # Action lanes (enrich, connect, check_pending, follow_up)
β βββ management/setup_crm.py # Idempotent CRM bootstrap (Dept, Stages, Users)
β βββ ml/scorer.py # ML profile ranking (LogisticRegression + Thompson Sampling)
β βββ navigation/ # Login, throttling, browser utilities
β βββ rate_limiter.py # Daily/weekly rate limiting
β βββ sessions/ # Session management
βββ main.py # CLI entry point (load / run subcommands)
βββ manage_crm.py # Django manage.py (migrate, runserver, createsuperuser)
βββ local.yml # Docker Compose
βββ Makefile # Shortcuts (setup, run, load, admin, analytics, test)
Join for support and discussions:
Telegram Group
GNU GPLv3 β see LICENCE.md
Not affiliated with LinkedIn.
Automation may violate LinkedIn's terms (Section 8.2). Risk of account suspension exists.
Use at your own risk β no liability assumed.
Made with β€οΈ

