12 KiB
The open-source agentic cold email and warmup platform.
Features · How it works · Quick start · Self-hosting · Docs · Community · Support
⭐ Help us reach more senders and grow the Warmbly community. Star this repo!
Warmbly
Warmbly runs cold email campaigns from the mailboxes you already own and warms them so they keep landing in the inbox. Opens, clicks, and replies land in a shared dashboard the moment they happen, and it's AI-native, so your team and its agents work in it together, live.
https://github.com/user-attachments/assets/378a510a-bb99-425f-925e-04300184938b
Features
- Campaigns - multi-step sequences with per-mailbox caps and spacing
- Unified inbox - every mailbox and reply in one place
- CRM - contacts, pipelines, deals, tasks, meetings
- Warmup - a pool of monitored mailboxes, not throwaway accounts
- Deliverability - bounces, complaints, suppression, inbox placement
- Automations - visual reply playbooks with AI steps
- Integrations - HubSpot, Slack, Zapier, REST API, webhooks
- Realtime - live presence and edits across your team
How it works
Warmbly splits into a control plane (backend API, consumer, Postgres, Redis, and the event bus) that owns all state, and an execution plane of interchangeable Go workers that send and sync mail. Workers never touch Postgres, and outbound mail leaves through each mailbox's own provider, not the worker's IP, so you add throughput by running more workers.
flowchart LR
MB["Your mailboxes"] --> API
subgraph CP["Control plane"]
direction TB
API["Backend API"] --> DB[("Postgres")]
API --> BUS{{"Event bus"}}
end
BUS --> W1["Worker"]
BUS --> W2["Worker"]
BUS --> W3["Worker"]
W1 --> P["Gmail · Microsoft · SMTP"]
W2 --> P
W3 --> P
P --> R["Recipients"]
Secrets use envelope encryption, with a local AES master key by default or AWS KMS if you prefer. Full write-up in the architecture docs.
Quick start
You need Docker, Go 1.25, and pnpm.
git clone https://github.com/warmbly/warmbly && cd warmbly
make dev
One command brings up the backing services in Docker, applies migrations, seeds
demo data, and starts the backend, worker, and dashboard natively. Open
http://localhost:5173 and log in with dev@warmbly.com / password123, then
read the login code out of Mailpit at http://localhost:18025 (the native dev
stack keeps the emailed code on so the flow stays exercised; a self-hosted
install does not). Full setup lives in the
local development guide.
Warning
make devandmake upshare one Docker Compose project, one volume, and onewarmbly_devdatabase, andmake devseeds fixture accounts by default. Those accounts become your instance's accounts, which permanently retires the first-run claim linkmake upprints. Usemake dev SEED=falseon a database you intend to self-host from. See first run.
Self-hosting
Warmbly runs with no cloud account of any kind: no AWS, no GCP, no Stripe, no Kafka. One command brings up the whole platform on local, open-source pieces:
git clone https://github.com/warmbly/warmbly && cd warmbly
make up
That is the whole install. make up waits for the backend and prints a one-time
link that claims the instance and makes you its admin. Open it, pick a password,
and you are in. You need Docker with Compose v2 and about 10 GB of free disk; the
first run builds the images once, which takes roughly 6 minutes.
Nothing else is required: no SMTP relay, no captcha keys, no cloud account, no
.env to hand-write, and no separate command to grant yourself admin. To change
something, cp .env.example .env and edit it. The template
boots as-is and carries the commands that generate your own secrets; set those
and APP_ENV=prod before anyone else can reach the instance.
| If | Then |
|---|---|
| The claim link is gone | It is single use and lasts 24 hours. make claim prints a fresh one |
| No link was printed at all | The database already has accounts, so the instance is claimed. make cli ARGS="user create --email you@example.com --admin" adds you, prompting for a password to set |
| You would rather skip the link | Set WARMBLY_BOOTSTRAP_EMAIL and WARMBLY_BOOTSTRAP_PASSWORD_HASH before the first start and the owner exists when it comes up |
| Something is wrong | make doctor prints the instance state and every failing check |
Those all run warmblyctl,
the operator CLI baked into the backend image. It talks to the database directly,
so it works when signing in does not.
Note
Signing in never depends on outbound mail. Platform email defaults to
MAIL_TRANSPORT=logunder Compose, so password resets and invitations go to the backend logs until you pointSMTP_*at a relay. Invitations still work without one: invite the person under Settings > Members, then copy the link from their row and send it yourself. See accounts and access.
➡️ Follow the step-by-step self-hosting guide for the full walkthrough: your own secrets, verifying the stack is healthy, mail and single sign-on, HTTPS, connecting Gmail and Microsoft mailboxes, scaling workers, backups, and a troubleshooting table.
Every external dependency is picked by an environment variable, so you swap in a cloud service only if you want one:
| Concern | Self-host default | Optional / cloud |
|---|---|---|
| Database | PostgreSQL 16 | RDS / Cloud SQL, any Postgres |
| Cache | Redis (or Valkey) | ElastiCache |
| Event bus | NATS JetStream | Kafka (-tags kafka) |
| Blob storage | Filesystem | S3, MinIO, R2, B2 |
| KMS / root key | Local AES master key | AWS KMS |
| Payments | Off (everything unlocked) | Stripe |
Scaling is by mailboxes and workers, not IPs.
Documentation
The full docs live at docs.warmbly.com.
| Read this | To learn |
|---|---|
| Self-hosting guide | Step-by-step install, then production, backups, and scaling the worker fleet |
| First run | Claiming the instance, reissuing the setup link, and what to do when accounts already exist |
| Accounts and access | Registration modes, inviting people with or without a mail relay, SSO, and recovering access |
warmblyctl |
The operator CLI: creating accounts, setting passwords, granting admin, and instance status |
| Configuration reference | Every environment variable, its default, and whether changing it needs a restart |
| Instance health | The checks the admin panel runs against your deployment, and make doctor |
| Troubleshooting | The errors self-hosters actually hit, and the command that fixes each one |
| Local development | Every make target, the native services, and how seeding works |
| Architecture | How the control plane and workers split the job, plus the encryption model |
| API reference | Endpoints, auth, permissions, and webhooks |
Community
Have a question, found a bug, or want to shape where Warmbly goes next?
- Discord - chat with the team and other senders
- GitHub Issues - report bugs and request features
- X / @WarmblyHQ - follow along for updates and releases
- Email - reach us at
team@warmbly.com
Support and enterprise
Note
Need a hand? We are happy to help. Ask in Discord, open a GitHub issue, or email
team@warmbly.com, and someone on the team will get back to you.Running Warmbly at scale, or would you rather we run it for you? We offer enterprise support and managed infrastructure: we can host and operate the whole platform for your organization, help you deploy and scale the worker fleet, tune deliverability, migrate your sending onto Warmbly, and stand behind it with a support agreement built around your team. Tell us what you need at
team@warmbly.comor reach out on X.
Star the repository ⭐
Contributing
Pull requests are welcome. Keep each one to a single logical change, and open an
issue first for larger design or product changes. Before you open a PR, run the
checks for the tree you touched (make fmt and make lint for Go, pnpm typecheck and pnpm lint for the frontends). See CONTRIBUTING.md.
Security
Found a vulnerability? Email team@warmbly.com instead of opening a public issue.
We prefer responsible disclosure and credit reporters in the release notes.
License
Apache License 2.0. Copyright 2026 Mindroot Ltd. See LICENSE.

