Skip to content
Kandid-aiPublic

About

Open-source AI SDR: email sequences, LinkedIn and WhatsApp outreach, enrichment tables, and an AI CRM that classifies every reply and drafts the answer. Self-hosted, bring your own AI key.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

55 stars

Watchers

0 watching

Forks

Latest commit

 

History

98 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

AgentSDR: the open-source AI SDR. Email, LinkedIn and WhatsApp outreach, with an AI CRM that reads every reply and drafts the answer.

Find leads, reach them on email, LinkedIn and WhatsApp,
and let AI work every reply, from one workspace you run yourself.

Website  ·  Docs  ·  Self-host  ·  Community  ·  Report a bug

CI License: MIT GitHub stars Documentation GitHub Discussions Next.js 16 PostgreSQL 16+


AgentSDR's CRM: replies from every channel land in one queue, AI classifies each and drafts the answer, sent in one click
Replies from every channel land in one queue. AI classifies each and drafts the answer. Watch the 51-second film. Every name in it is fictional.

Why AgentSDR

Outbound usually means stitching together a lead database, an enrichment tool, an email sequencer, a LinkedIn tool, a dialer and a CRM, each with its own seats, its own copy of your leads and its own idea of who replied. Most of them are thin layers over APIs you could call yourself.

  • One workspace instead of six tools. One record per person and company, so a reply on LinkedIn shows up in the same queue and pipeline as an email reply.
  • The AI does the tracking. Every reply, on every channel, is read, classified and given a drafted answer. You approve what goes out.
  • You own it. A single Next.js app and one PostgreSQL database on your own server. Your leads, conversations and recordings never leave infrastructure you control.
  • Your keys, no seats. Connect your own Google Workspace, Unipile, storage and any AI model on OpenRouter. No per-seat or per-contact fees: you pay your server and your providers.

Everything in one workspace

Email, LinkedIn and WhatsApp feeding one AgentSDR workspace

Three channels, one lead record. Email from your own mailboxes, LinkedIn invites and messages, WhatsApp chats and calls. How it fits together →

Tables enriching a list with 15 providers

Enrichment, built in. Tables run 15 providers (Apollo, Hunter, Lusha and more), AI columns and HTTP calls, row by row. Tables →

An email sequence sent from your own mailboxes

Email sequences from your own mailboxes. Google Workspace, merge fields, sending windows and daily limits that keep inboxes healthy. Email →

A LinkedIn invitation with a note, then the conversation

LinkedIn invites and messages. Connection requests with notes, follow-ups after acceptance, inside conservative daily limits. LinkedIn →

A WhatsApp call recorded and summarised into the lead's record

WhatsApp chats and recorded calls. Message campaigns, and calls dialed from AgentSDR, recorded to your bucket and transcribed. WhatsApp →

Action required: every reply classified with a draft ready

AI reads every reply. Interested, meeting requested, not now, out of office: classified with the reason shown, and a draft ready. AI CRM →

Approving a drafted reply and sending it

Approve and send in one click. Edit the draft if you like; it goes out on the channel the lead wrote on. Nothing sends on its own. Drafts →

The pipeline board: needs action, waiting on them, follow-ups exhausted

A pipeline that keeps itself current. Every lead sits where it stands, and follow-up sequences are scheduled for you. Pipeline →

Analytics: replies, positive replies, meetings and customers by channel

See what turns into meetings. Replies, positive replies, meetings and customers, by channel and over time. Analytics →

Self-hosting AgentSDR with Docker Compose

Self-host it in minutes. Download one file, set a few secrets, docker compose up -d. No Redis, no queue server. Self-hosting →

Also inside: a lead database with custom fields, CSV and XLSX import with merge fields, Do Not Contact across every channel, organizations with roles, teams and invitations, and per-organization sending rules with safe defaults.

Works with

Gmail    LinkedIn    WhatsApp    Google Workspace    Unipile    Cloudflare R2    OpenRouter    Apollo    Hunter    Lusha    Findymail    ZeroBounce

Each organization connects its own accounts in Settings, with a guided setup for every field. All integrations →

Service Powers Setup guide
Google Workspace Sending and reading Gmail, through a service account Google Workspace (with a 2-minute video)
Unipile LinkedIn and WhatsApp accounts, messaging and calling Unipile
Cloudflare R2 Call recordings and contact photos Cloudflare R2
OpenRouter Every AI feature, on your own key and any model OpenRouter
15 enrichment providers Tables columns Enrichment providers
Resend Sign-up, password-reset and invitation email Resend

Get started

You need a machine with Docker.

mkdir agentsdr && cd agentsdr
curl -O https://raw.githubusercontent.com/Kandid-ai/AgentSDR/main/docker-compose.yml
docker compose up -d          # PostgreSQL, the app on :3000 (it creates the schema and runs the scheduled jobs)

Open http://localhost:3000: the setup page creates your admin account and organization. Then connect your services in Settings. For a server, replace the # CHANGEME values in docker-compose.yml (or a .env beside it) first; openssl rand -hex 32 makes a secret.

The Docker Compose guide walks through every setting and every service. There are also guides for running from source, deploying on a VPS with Dokploy and going to production.

Run it from source

You need Bun 1.2+ and PostgreSQL 16+.

git clone https://github.com/Kandid-ai/AgentSDR.git && cd AgentSDR
bun install
createdb agentsdr
cp .env.example .env.local   # set DATABASE_URL, BETTER_AUTH_SECRET, INTEGRATION_CREDENTIALS_KEY
bun run db:setup             # create the schema in the empty database
bun run db:seed:demo         # optional: a fictional demo organization
bun run dev                  # http://localhost:3000

With the demo seed, sign in as demo@example.com / demo-password-123.

Environment variables

Environment variables cover only what the app needs before it can read its database. Everything else is per organization, in the app.

Variable Required Purpose
DATABASE_URL yes PostgreSQL 16+ connection string
BETTER_AUTH_SECRET yes Signs sessions
BETTER_AUTH_URL yes Public URL, read at runtime
INTEGRATION_CREDENTIALS_KEY yes Encrypts integration credentials (AES-256-GCM)
UNSUBSCRIBE_SECRET for email Signs unsubscribe links
CRON_SECRET, OUTREACH_TICK_SECRET no Only to call the job endpoints from an external cron
RESEND_API_KEY, AUTH_EMAIL_FROM in production Auth email through Resend
AUTH_SIGNUP no invite-only (default) or open
GOOGLE_CLIENT_ID, GOOGLE_CLIENT_SECRET no "Continue with Google"
DB_POOL_MAX no Connection pool size (default 8)

Every variable, with how to generate it and where it is read: Configuration reference.

How it works

flowchart LR
    A["Leads<br/>import or build a list"] --> B["Tables<br/>enrich with 15 providers and AI"]
    B --> C{"Reach out"}
    C --> D["Email<br/>your mailboxes"]
    C --> E["LinkedIn<br/>invites and messages"]
    C --> F["WhatsApp<br/>messages and calls"]
    D --> G["Every reply<br/>one queue"]
    E --> G
    F --> G
    G --> H["AI CRM<br/>classify and draft"]
    H --> I["You approve<br/>one click"]
    H --> J["Pipeline and analytics"]
Loading

One Next.js app and one PostgreSQL database: pages, API routes and background workers run in a single process, with no queue server or Redis. Every request, job and webhook runs inside one organization's scope, and code that forgets fails closed. Integration credentials are encrypted per organization and verified with a live call before they are saved. More in How it works and the architecture guide.

Architecture diagram
flowchart TB
    subgraph You["Your infrastructure"]
        App["AgentSDR (Next.js)<br/>pages, API, in-process workers and scheduled jobs"]
        DB[("PostgreSQL 16+")]
        Ext["Call Recorder<br/>Chrome extension"]
    end
    App <--> DB
    Ext -- "recordings" --> App
    App <--> Unipile["Unipile<br/>LinkedIn, WhatsApp"]
    App <--> Gmail["Google Workspace<br/>Gmail"]
    App <--> R2["Cloudflare R2<br/>recordings"]
    App <--> OR["OpenRouter<br/>AI models"]
    App <--> Enr["Enrichment providers"]
    Unipile -- "webhooks" --> App
    Gmail -- "Pub/Sub push" --> App
Loading
Project structure and development
src/app/                 Pages (App Router) and API routes
src/lib/<domain>/        Business logic, schema and queries per domain
src/components/          React components, one folder per domain
src/jobs, src/functions  LinkedIn sending engine (run by the in-app scheduled jobs)
src/services/            Unipile API clients
db/                      schema.sql (generated snapshot) and seed.sql
scripts/                 Migration history, audits, database tooling, e2e checks
extensions/whatsapp-recorder/   Chrome extension that dials and records WhatsApp calls
docker/, docker-compose.yml     Self-hosting
docs/                    Documentation (published at docs.agentsdr.ai)
Command What it does
bun run dev Start the app at http://localhost:3000
bun run test 600+ unit tests
bun run typecheck / bun run lint Must pass before every commit
bun run db:setup / db:seed:demo Create the schema / a fictional demo organization
bun run db:check Audit that every table is organization-scoped

CI runs typecheck, lint, tests, a secret scan, the production build, the extension build and a fresh install on PostgreSQL 16, 17 and 18. See the development guide.

Built with Next.js 16 and React 19, TypeScript, Drizzle ORM, Better Auth, Tailwind CSS with AlignUI, and Bun.

Security and privacy

  • Your data stays with you. Leads, conversations and analytics live in your PostgreSQL; call recordings in your own R2 bucket, reached only through short-lived signed links.
  • Encrypted credentials. Every saved API key and token is encrypted with AES-256-GCM.
  • Tenant isolation, tested. An end-to-end suite signs in as a second organization and proves it can see, change and count nothing of the first.
  • Humans approve outbound replies. AI drafts wait for a person, and outbound work can be paused instantly.
  • Report vulnerabilities privately through GitHub security advisories. See SECURITY.md.

Responsible use

AgentSDR contacts people on your behalf, so how it is used is your responsibility. LinkedIn's terms do not allow automation and accounts can be restricted; WhatsApp bans numbers that send unsolicited bulk messages; cold email is regulated by laws such as CAN-SPAM, GDPR and CASL; and many places require consent before a call is recorded. Sending limits, unsubscribe links and Do Not Contact reduce the risk but do not make any use compliant. Read Responsible use before you start.

FAQ

Is AgentSDR free?

Yes. It is open source and you host it yourself, so there are no seats, tiers or per-contact fees. You pay for your server, the accounts you connect (Google Workspace, Unipile) and your own AI usage. It is MIT-licensed, so you can also use, change and build on it commercially.

Which email providers can it send from?

Google Workspace mailboxes, connected once through a service account with domain-wide delegation. Each mailbox has its own daily limit (30 by default), sending hours and signature. Microsoft 365 is not supported yet.

Will LinkedIn automation get my account restricted?

No tool can promise that, but AgentSDR stays well inside LinkedIn's limits: 30 invitations a day on premium accounts and 5 on free, a random 30 to 60 second gap between invitations, optional working hours per account, and an account that hits LinkedIn's own limit pauses for the day.

How does WhatsApp calling work?

You link your number through Unipile and install the AgentSDR Call Recorder Chrome extension. When you call a lead from AgentSDR, the extension dials inside WhatsApp Web and records both sides; the recording goes to your storage bucket and your chosen model transcribes it. It relies on WhatsApp Web's English interface.

Which AI models can I use?

Any model on OpenRouter, with your own key. Each call is pinned to the provider you picked, with fallbacks turned off, so your data only goes where you chose.

Does the AI send replies on its own?

No. Drafts, including follow-up sequence steps, wait in Action required until someone sends them, as written or edited. The AI can move a lead forward in the pipeline when it is confident; anything else is held for a person.

Can my whole team use it?

Yes. Invite teammates from Settings → Members with the owner, admin or member role. One deployment can also hold several organizations, each fully separate.

Community and support

Where Best for
Docs Setup guides, every feature, troubleshooting
GitHub Discussions Questions, ideas, and showing what you built
GitHub Issues Bugs and feature requests (in the app: Help → Report a bug)
Security advisories Vulnerabilities, reported privately

Contributing

Contributions are welcome: bug reports, fixes, enrichment providers, docs. Start with CONTRIBUTING.md for the development setup, the checks a pull request must pass and the commit conventions; issues labelled good first issue are a good way in. Also see the Code of Conduct, how the project is run and what changed.

License

AgentSDR is open source under the MIT License:

  • You may use, copy, modify, self-host, distribute and sell AgentSDR, including in commercial products and as a hosted service.
  • You don't have to publish your changes, though contributions back are always welcome.
  • Keep the copyright and license notice in copies you distribute.

The LICENSE file is the binding text.

Acknowledgements

AgentSDR
Made by Kandid · If AgentSDR is useful to you, a ⭐ helps others find it.

About

Open-source AI SDR: email sequences, LinkedIn and WhatsApp outreach, enrichment tables, and an AI CRM that classifies every reply and drafts the answer. Self-hosted, bring your own AI key.

Topics

Resources

Code of conduct

Contributing

Security policy

Stars

55 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages