Cold outreach email platform for job seekers.
Send personalized emails to recruiters at scale with smart scheduling, multi-sender rotation, and follow-up sequences.
Outly is a cold outreach platform designed for job seekers who want to reach recruiters through cold email. Connect your email accounts (Gmail, Outlook, Zoho, Yahoo, or any custom provider), import recipients from a CSV, write personalized emails with template variables, and let Outly handle the scheduling, sending limits, and follow-ups.
Built for deliverability: adaptive sender warmup, intelligent sending limits, natural sending patterns, inbox protection with bounce and reply detection, and automatic blocking of invalid recipients.
- Create campaigns with one or multiple senders (Gmail, Outlook, Zoho, Yahoo, or any custom provider)
- Automatic sender rotation with failover when daily limits are reached
- Pause, resume, and cancel campaigns in real-time
- Schedule campaigns for future delivery
- Live campaign monitoring with auto-refresh
- Smart recipient ordering to maximize deliverability
- Gmail and Google Workspace
- Outlook/Office 365, Zoho, Yahoo
- Any email provider with custom connection settings
- Works out of the box — just enter your email and credentials
- Connection security validation
- Checks if your domain is properly set up for email delivery
- Intelligent sending limits that adapt to provider restrictions
- Natural send timing with realistic delays and pauses between emails
- Business hours window with configurable start/end time and timezone
- Sending speed varies throughout the day to mimic real human behavior
- Random pauses of varying lengths between sends
- Each day's sending pattern is unique and non-repeating
- Every email has a unique structure to avoid spam filter detection
- Clean email headers with no automation markers
- Gradual daily volume increase over 28 days per sender
- Automatically adjusts based on bounce rates, reply rates, and errors
- Randomized starting volume per sender for natural ramp-up
- Daily volume varies slightly to avoid predictable patterns
- Auto-pauses warmup if deliverability signals are poor
- Cautious recovery after issues are resolved
- Fully configurable via settings
- Automatic inbox monitoring for bounces and replies (Gmail, Outlook, Yahoo, Zoho, custom)
- Bounced emails are detected and marked automatically
- Replies are detected and follow-up sequences stop automatically
- Bounced recipients are automatically blocked from future campaigns
- Invalid recipients are filtered out at both campaign creation and send time
- Safe concurrent processing per sender
- Automatic retry on temporary failures
- Configurable monitoring interval
- Follow-up emails appear in the same thread as the original email
- Proper thread grouping across all email providers
- Full conversation chain maintained across all follow-up steps
- Up to 5 automated follow-up steps per campaign
- Configurable wait periods between steps (in days)
- Per-recipient sequence controls: pause, resume, stop
- Sequences stop automatically on reply detection
- Sequences halt on bounce detection
- Bulk controls for all recipients in a campaign
- Rich text editor with formatting, links, colors, and alignment
- Template variables from CSV data:
{{Name}},{{Company}},{{Role}} - Dynamic sender variables:
{{senderEmail}},{{senderName}} - Reusable email templates (save, edit, delete, apply)
- File attachments (10 MB per file, 25 MB total)
- Variable preview before sending
- Open tracking to see who read your emails
- Click tracking to see who clicked your links
- Campaign-level metrics: open rate, click rate, unique opens, unique clicks
- Per-email tracking details with bounce reason display
- Per-link click breakdown
- Bounced and replied status indicators on campaign detail page
- Multi-tier protection to prevent misuse
- Automatic retry when limits are hit
- Google sign-in
- Encrypted storage for all email credentials
- Short-lived sessions with automatic refresh
- Cross-site request protection
- Connection security validation
- User-scoped data isolation on all queries
- Secure HTTP headers
- Automatic recovery of interrupted jobs on startup
- Periodic detection and re-processing of stuck jobs
- Stuck campaign detection and auto-completion
- Graceful shutdown with in-flight job completion
- Auto-resume for campaigns paused due to sender limits
- Scheduled follow-up processing
- Periodic bounce and reply detection
- Automatic retries on failures
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ Frontend │──────▶│ Backend │──────▶│ Database │
│ (Next.js) │◀──────│ (Express) │──────▶│ (Postgres) │
└─────────────┘ └──────┬──────┘ └─────────────┘
│
┌──────▼──────┐
│ Background │
│ Workers │
└──────┬──────┘
│
┌──────────────┼──────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│ Email │ │ Warmup & │ │ Follow-up│
│ Delivery │ │ Inbox │ │ Scheduler│
│ │ │ Monitor │ │ │
└──────────┘ └──────────┘ └──────────┘
The frontend and backend run as separate services. The backend handles API requests and delegates email processing to background workers. Workers manage sending, inbox monitoring, warmup adjustments, and follow-up scheduling independently.
| Layer | Technology |
|---|---|
| Frontend | Next.js 16, React 19, TypeScript, Tailwind CSS 4, TipTap 3 |
| Backend | Express 5, TypeScript, Prisma 6 |
| Database | PostgreSQL 15 |
| Queue | BullMQ 5 with Redis 7 |
| Storage | Cloudinary |
| Auth | Google OAuth 2.0, JWT |
| Nodemailer via SMTP (Gmail, Outlook, Zoho, Yahoo, Custom) | |
| Infra | Docker, Docker Compose |
outly/
├── client/
│ ├── src/
│ │ ├── app/
│ │ │ ├── dashboard/
│ │ │ │ ├── compose/
│ │ │ │ ├── campaigns/
│ │ │ │ └── templates
│ │ │ ├── login/
│ │ │ └── ...
│ │ ├── components/
│ │ ├── hooks/
│ │ ├── context/
│ │ ├── lib/
│ │ └── types/
│ └── public/
│
├── server/
│ ├── src/
│ │ ├── controllers/
│ │ ├── routes/
│ │ ├── middlewares/
│ │ ├── config/
│ │ ├── queues/
│ │ ├── utils/
│ │ └── worker/
│ ├── prisma/
│ ├── Dockerfile
│ ├── Dockerfile.worker
│ └── docker-compose.yml
│
└── docs/
- Node.js 22+
- Docker and Docker Compose (for local PostgreSQL and Redis)
- Google Cloud Console project (for OAuth Client ID)
- Cloudinary account (for attachment storage)
git clone https://github.com/aniket1251/outly.gitcd outlyServer:
cd servercp .env.example .env # Fill in your valuesnpm installClient:
cd ../clientnpm installcp .env.example .env # Fill in your valuescd serverdocker compose up -d # Starts PostgreSQL + Rediscd servernpm run prisma:generatenpx prisma migrate dev --name initTerminal 1 (API Server):
cd servernpm run devTerminal 2 (Email Worker):
cd servernpm run workerTerminal 3 (Frontend):
cd clientnpm run devThe app is now running at http://localhost:3000.
| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | Database connection string |
REDIS_URL |
Yes | Cache connection string |
ENCRYPTION_KEY |
Yes | Key for credential encryption |
JWT_ACCESS_SECRET |
Yes | Auth token secret |
JWT_REFRESH_SECRET |
Yes | Refresh token secret |
GOOGLE_CLIENT_ID |
Yes | Google sign-in Client ID |
CLOUDINARY_CLOUD_NAME |
Yes | File storage cloud name |
CLOUDINARY_API_KEY |
Yes | File storage API key |
CLOUDINARY_API_SECRET |
Yes | File storage API secret |
TRACKING_BASE_URL |
No | Public URL for tracking |
WORKER_CONCURRENCY |
No | Max parallel jobs |
MIN_DELAY_MS |
No | Min delay between sends |
WARMUP_DURATION_DAYS |
No | Warmup period length |
| Variable | Required | Description |
|---|---|---|
NEXT_PUBLIC_BACKEND_URL |
Yes | Backend URL |
NEXT_PUBLIC_GOOGLE_CLIENT_ID |
Yes | Google sign-in Client ID |
See server/.env.example and client/.env.example for all options with generation commands.
Full API documentation is available in API_REFERENCE.md.
1. User signs in with Google. The backend verifies the identity and creates an account.
2. User adds a sender by providing email credentials (Gmail App Password or custom provider). The system verifies the connection, securely stores the credentials, checks if the domain is properly set up for email delivery, and starts a gradual warmup process.
3. User creates a campaign with recipients (manual or CSV), subject, body, optional follow-up steps, attachments, business hours, and tracking preferences. Invalid recipients are filtered out, sending order is optimized for deliverability, and emails are queued for sending.
4. The system processes emails through a multi-step pipeline: validates the job, checks campaign state, verifies the sender, evaluates daily capacity and business hours, checks sending limits, securely retrieves credentials, downloads attachments, fills in template variables, adds tracking, prepares the email for deliverability, sends it, and updates status.
5. The bounce and reply detector monitors sender inboxes periodically. Bounces update email status, halt sequences, and block those recipients from future sends. Replies are detected and follow-up sequences stop automatically.
6. The adaptive warmup adjusts daily sending limits based on deliverability signals from the last 24 hours. Volume adjusts based on bounce rates, reply rates, and error rates.
7. The follow-up scheduler runs periodically, checks which recipients are due for their next follow-up, creates new emails with proper threading, and queues them for sending.
8. Tracking events are recorded when recipients open emails or click links. Metrics are available on the campaign detail page.
This project is licensed under the MIT License. See the LICENSE file for details.