Free, open-source CRM with lead automation, AI email generation, campaigns, and a full pipeline dashboard — self-host it in minutes.
Generated by Arkitekt AI — this entire application was built by our AI platform. If you find bugs or want to contribute, PRs are welcome.
- Ingest leads automatically from Meta (Facebook) Lead Ads, webhooks, or manual entry
- Manage your pipeline with a kanban board, table view, notes, follow-up reminders, and deal tracking
- Send outreach emails via Outlook (Microsoft Graph) or Mailgun
- Generate email copy with AI using any OpenAI-compatible API, Anthropic, or local models via Ollama
- Run campaigns — filter your lead database, generate AI copy, and blast or drip emails
- Track everything — reporting dashboard with conversion funnel, source attribution, pipeline value, and leads over time
Connectors are pluggable. Meta and Outlook/Mailgun are the built-in connectors, but the architecture is designed to be extended. Want to pull leads from Google Ads, HubSpot, or Typeform? Want to send via SendGrid or AWS SES? Add a connector — see Connectors below.
┌──────────────┐ ┌──────────────┐ ┌──────────────┐
│ Meta API │ │ SQLite DB │ │ Outlook / │
│ Lead Fetch │──────────│ Storage │─────────│ Mailgun │
│ │ │ │ │ Email Send │
└──────────────┘ └──────────────┘ └──────────────┘
│
┌──────────────────┼──────────────────┐
│ │ │
┌─────┴─────┐ ┌──────┴──────┐ ┌──────┴──────┐
│ Dashboard │ │ Campaigns │ │ LLM AI │
│ (Flask) │ │ & Sequences│ │ (optional) │
└───────────┘ └─────────────┘ └─────────────┘
git clone <repository-url>
cd arkitekt-opencrm
cp .env.example .envEdit .env with your credentials:
# Meta API
META_PAGE_ID=your_page_id
META_PAGE_ACCESS_TOKEN=your_token
# Microsoft Graph API (Outlook)
MS_TENANT_ID=your_tenant_id
MS_CLIENT_ID=your_client_id
MS_CLIENT_SECRET=your_client_secret
MS_SENDER_EMAIL=you@yourdomain.com
# Booking URL (included in outreach emails)
BOOKING_URL=https://calendly.com/you/30min
# Branding
SENDER_NAME=Jane Smith
COMPANY_NAME=Acme Corp
COMPANY_DESCRIPTION=We help small businesses grow with custom software
# AI Email Generation (optional — any OpenAI-compatible API)
LLM_API_KEY=sk-...
# LLM_MODEL=gpt-4o
# LLM_BASE_URL=http://localhost:11434/v1 # for Ollamadocker-compose up -dThis starts two services:
- Pipeline (port 9010) — polls Meta for new leads, sends automated emails
- Dashboard (port 5050) — web UI for managing leads, campaigns, and reporting
Visit http://localhost:5050 — default login: admin / admin
Change credentials via DASHBOARD_USERNAME and DASHBOARD_PASSWORD in .env.
curl http://localhost:9010/healthArkitekt OpenCRM is designed to be self-hosted. For production use:
Recommended setup:
- Spin up a small EC2 instance (or equivalent — DigitalOcean Droplet, Hetzner, etc.). A
t3.smallort3.mediumis plenty. - Install Docker and Docker Compose
- Clone the repo, configure
.env, rundocker-compose up -d - Data is persisted via Docker volumes (
./dataand./logsare bind-mounted), so your database survives container restarts and redeployments - Put it behind a reverse proxy (nginx, Caddy, Traefik) with HTTPS if exposing the dashboard externally
- For backups, periodically copy
./data/leads.dbto S3 or equivalent
Docker persistence: The SQLite database is stored at ./data/leads.db on the host via a bind mount. Your data lives on the host filesystem, not inside the container. Restarting, rebuilding, or updating containers will not lose data.
Updating:
git pull
docker-compose up -d --build- Automated Meta Lead Ads polling (configurable interval, default 15 min)
- Webhook ingestion —
POST /api/webhook/leadsfor any external source (Zapier, forms, n8n, etc.) - Manual lead entry via dashboard
- Duplicate detection by lead ID
- Intelligent field mapping (email, name, phone, company, job title)
- Status tracking:
intake→emailed→contacted→qualified→closed
- Notes — add timestamped notes to any lead
- Follow-up reminders — set reminder dates, see overdue/upcoming in dashboard
- Deal tracking — deal value and expected close date per lead
- Pipeline value — aggregate deal value across your funnel
- Lead assignment — assign leads to team members
- Tagging — industry, source, custom tags
- Microsoft Graph API (Outlook/Exchange) via OAuth2
- Mailgun support for campaign sends
- SMTP fallback (
USE_SMTP=true) - Configurable HTML email templates with
{name}variable substitution - AI email generation — works with OpenAI, Anthropic, Ollama, or any OpenAI-compatible endpoint
- Campaigns — filter leads by status/source/search, generate AI copy, send to matching leads
- Email sequences — multi-step drip campaigns with configurable delays
- Table view — sortable, filterable, searchable, paginated
- Kanban board — drag-free pipeline visualization with deal values and reminder badges
- Reports — conversion funnel, leads by source, pipeline value by status, leads over time (30 days)
- Campaign builder — create campaigns with live audience preview, AI copy generation, and one-click send
- Sequence manager — create multi-step email sequences, enroll/unenroll leads
- User management — multi-user with admin/user roles
- Docker containerization with health checks and auto-restart
- Graceful shutdown (SIGTERM/SIGINT)
- Structured logging with rotation
- Retry logic with exponential backoff
- Thread-safe SQLite with connection pooling
All configuration is via environment variables. See .env.example for the complete list with documentation.
| Variable | Description |
|---|---|
META_PAGE_ID |
Facebook Page ID |
META_PAGE_ACCESS_TOKEN |
Page Access Token with leads_retrieval permission |
MS_TENANT_ID |
Azure AD Tenant ID |
MS_CLIENT_ID |
Azure App Client ID |
MS_CLIENT_SECRET |
Azure App Client Secret |
MS_SENDER_EMAIL |
Email address to send from |
BOOKING_URL |
Scheduling link included in outreach emails |
| Variable | Description | Default |
|---|---|---|
SENDER_NAME |
Name in email signature | The Team |
COMPANY_NAME |
Company name in emails | (empty) |
COMPANY_DESCRIPTION |
Used by AI email generation | (empty) |
| Variable | Description | Default |
|---|---|---|
LLM_API_KEY |
API key for AI features | (disabled) |
LLM_MODEL |
Model to use | gpt-4o |
LLM_BASE_URL |
Custom endpoint (Ollama, Together, etc.) | (provider default) |
LLM_PROVIDER |
openai or anthropic (auto-detected from key) |
openai |
| Variable | Description | Default |
|---|---|---|
MAILGUN_API_KEY |
Mailgun API key (for campaigns) | (disabled) |
MAILGUN_DOMAIN |
Mailgun sending domain | (empty) |
MAILGUN_SENDER_EMAIL |
Mailgun sender address | campaigns@{domain} |
WEBHOOK_API_KEY |
API key for webhook ingestion | (disabled) |
| Variable | Description | Default |
|---|---|---|
POLL_INTERVAL_SECONDS |
Lead polling interval | 900 (15 min) |
DB_PATH |
SQLite database path | /app/data/leads.db |
LOG_LEVEL |
Logging verbosity | INFO |
DASHBOARD_USERNAME |
Dashboard login | admin |
DASHBOARD_PASSWORD |
Dashboard password | admin |
To ingest leads from external sources, set WEBHOOK_API_KEY in your .env and POST to:
curl -X POST http://localhost:5050/api/webhook/leads \
-H "Authorization: Bearer YOUR_WEBHOOK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"email": "jane@example.com",
"first_name": "Jane",
"last_name": "Smith",
"company_name": "Acme Corp",
"lead_source": "website"
}'Accepts single objects or arrays. Works with Zapier, Make, n8n, custom forms, or any HTTP client.
Arkitekt OpenCRM ships with connectors for Meta Lead Ads (inbound) and Outlook/Mailgun (outbound), but it's built to be extended. You don't need Meta or Outlook to use this CRM — leads can come in via the webhook API, manual entry, or a custom connector you write.
To add a new lead source (e.g. Google Ads, HubSpot, Typeform), use meta_client.py as a template:
- Copy
meta_client.pyto a new file (e.g.google_ads_client.py) - Implement a client class with a
get_all_leads()method that returns a list of lead dicts with the standard fields (lead_id,email,full_name,first_name,last_name,phone_number,company_name,job_title,created_time,raw_field_data) - Wire it into
lead_processor.pyor call it from your own script - Or skip all that and just POST leads to the webhook endpoint — that works with any source, no code required
To add a new email provider (e.g. SendGrid, AWS SES, generic SMTP), use the _send_via_mailgun() function in dashboard.py as a template:
- Add your provider's config vars (API key, domain, etc.) to
.env.exampleand load them at the top ofdashboard.py - Write a
_send_via_yourprovider(to_email, subject, html_body)function - Add your provider to the
api_email_providers()endpoint - Add an
elif provider == 'yourprovider':branch inapi_campaign_send()
AI email generation already works with any OpenAI-compatible API out of the box. Just set LLM_BASE_URL to your provider's endpoint. This covers OpenAI, Ollama (local), Together, Groq, Fireworks, and many others.
We'd love community-contributed connectors. To submit one:
- Fork the repo
- Add your connector following the patterns above
- Update
.env.examplewith any new config vars - Submit a PR with a brief description of what it connects to
- Go to Facebook Developers
- Create or select your app
- Generate a Page Access Token with
leads_retrievalpermission - Get your Page ID from Page Settings
- Go to Azure Portal
- Navigate to Azure AD → App registrations → New registration
- Copy the Application (client) ID and Directory (tenant) ID
- Create a Client Secret under Certificates & secrets
- Grant API permissions:
Mail.Send,Mail.ReadWrite - Grant admin consent
├── main.py # Entry point — orchestrates the polling loop
├── config.py # Configuration loading & validation
├── database.py # SQLite operations (CRUD, schema, migrations)
├── meta_client.py # Meta Graph API client (lead fetching)
├── email_client.py # Microsoft Graph API + SMTP email sending
├── lead_processor.py # Lead ingestion orchestration
├── email_sender.py # Email sending orchestration
├── templates.py # HTML/text email templates
├── dashboard.py # Flask web dashboard (all features)
├── health_check.py # HTTP health check server
├── logger.py # Centralized logging
├── scripts/
│ ├── init_db.py # Database initialization
│ ├── manual_send.py # Manual email testing
│ └── test_credentials.py # Credential validation
├── Dockerfile # Multi-stage Docker build
├── docker-compose.yml # Service orchestration
├── .env.example # Configuration template
└── requirements.txt # Python dependencies
- PostgreSQL database support
- Lead scoring and prioritization
- A/B testing for email templates
- Email open/click tracking (via Mailgun webhooks)
- Reply detection and auto-status update
- Slack/Discord notifications
- Kubernetes Helm charts
- Contact deduplication and merging
Contributions are welcome! This project was generated by Arkitekt AI and we'd love help from the community to make it better.
To contribute:
- Fork the repository
- Create a feature branch (
git checkout -b feature/my-feature) - Make your changes and add tests
- Submit a pull request
Found a bug? Please open an issue with steps to reproduce. Include your Python version, OS, and relevant log output.
Feature requests are welcome too — open an issue describing what you'd like and why.
Do NOT open public GitHub issues for security vulnerabilities. Please report them via the repository's security advisory feature or contact us directly.
MIT License — see LICENSE for details.
Generated by Arkitekt AI — AI that builds software. If Arkitekt can build this in a day, imagine what it can build for your business.



