Choco Mailer Documentation
Complete guide to using the email marketing platform
Welcome to Choco Mailer
A professional, self-hosted email marketing platform with smart account rotation, real-time tracking, multi-provider support, and campaign management built for high-volume email delivery.
Bulk Sending
Tracking
Rotation
AI Spinner
Key Features at a Glance
Single & Bulk Email
Send individual emails or run large campaigns with multi-threaded delivery (up to 1000 threads).
Smart Account Rotation
Round-robin, random, or least-used rotation across unlimited accounts with daily limits.
Email Tracking
Track opens, clicks, and IPs with custom tracking domains and detailed analytics reports.
Multi-Provider Support
Microsoft Graph API, SMTP (Gmail, Outlook, Yahoo, Zoho, SendGrid, Mailgun, Amazon SES), and Firebase / GCP.
AI Content Spinner
Auto-generate subject and body variations using OpenAI, Google Gemini, or Claude.
Safety & Protection
Auto account suspension, failure tracking, brute force protection, and error categorization.
Quick Start Guide
Get up and running in 5 steps:
Log In
Access the dashboard using your admin or client credentials. Admin users have full access; client users have limited access (no settings, tokens, or disabled accounts management).
Import Accounts
Go to the Import tab and add accounts via Microsoft Graph API (App Permission or Delegated) or SMTP. You need at least one active sending account.
Configure Settings
Visit the Settings tab to configure rotation mode, daily limits, delay between sends, thread count, and optionally enable tracking and AI spinner.
Compose & Send
Use the Single Email tab for one-off emails, or the Bulk Send tab for campaigns. Write your content using the rich text editor or raw HTML.
Monitor & Track
View campaign progress in the Campaigns tab, check delivery history in History, and analyze open/click rates in tracking reports.
Login & User Roles
Choco Mailer supports two user roles with different access levels:
| Feature | Admin | Client |
|---|---|---|
| Single Email | ✓ | ✓ |
| Bulk Send | ✓ | ✓ |
| Campaigns | ✓ | ✓ |
| History | ✓ | ✓ |
| Email Lists | ✓ | ✓ |
| Unsubscribes | ✓ | ✓ |
| SMTP Accounts | ✓ | ✗ |
| Disabled Accounts | ✓ | ✗ |
| Settings | ✓ | ✗ |
| Logs | ✓ | ✗ |
Brute Force Protection: After 5 failed login attempts within 5 minutes, the IP is locked out for 15 minutes.
Single Email
Send individual emails to a single recipient with full control over the content and sender.
Fields
| Field | Required | Description |
|---|---|---|
| Send From | No | Choose a specific account to send from, or leave as "Auto" to use rotation. (Admin only) |
| Recipient | Yes | The email address to send to |
| CC | No | Carbon copy recipients |
| BCC | No | Blind carbon copy recipients |
| Subject | Yes | Email subject line |
| Message | Yes | Email body — use the rich text Editor, raw HTML, or Preview mode |
| Attachments | No | Drag & drop or browse files. Max 25 MB total, up to 10 files per email. |
Editor Modes: Switch between Editor (rich text with Quill.js), HTML (raw code), and Preview (rendered output) using the toggle buttons above the message area.
Tip: You can save your email as a template using the "Save as Template" button, and load saved templates using the "Templates" button next to the subject field.
Bulk Send
Run large email campaigns with multi-threaded delivery, real-time progress tracking, and campaign controls.
How to Send a Campaign
- Enter a Campaign Name to identify this send (e.g., "Newsletter Jan 2026")
- Add Recipients — paste emails one per line, or load from an Email List
- Write your Subject and Message (supports rich text and HTML)
- Optionally check "Validate accounts before sending" to verify all tokens first
- Select a Tracking Domain if you want branded tracking links
- Click Send Campaign
Campaign Controls
Once a campaign starts, you get real-time controls:
Pause
Temporarily halt sending
Resume
Continue from where you paused
Stop
Permanently stop the campaign
Progress Tracking
The progress panel shows:
- Progress bar with sent/total count
- Success count (green)
- Failed count (red)
- Send rate (emails per minute)
Tip: Use the "Remove Duplicates" button to clean your recipient list before sending. The system also automatically skips unsubscribed emails.
Campaigns
View, manage, and analyze all your email campaigns from a single dashboard.
Campaign Statuses
Campaign Details
Click on any campaign to view:
- Total, sent, failed counts and success rate
- Per-recipient delivery status with timestamps
- Email content preview (subject and body)
- Tracking report (opens, clicks, IPs)
- Option to resend failed emails
Export & Import
Campaigns can be exported as JSON files containing all data (recipients, send log, tracking). Import campaigns from JSON to restore or transfer between instances.
Filtering & Sorting
- Search by campaign name or UUID
- Filter by status (running, paused, completed, stopped, draft)
- Sort by newest, oldest, name, or most recipients
- Paginated results for large campaign lists
Send History
Complete log of every email sent through the platform with powerful filtering.
Available Filters
| Filter | Options |
|---|---|
| Time Range | Last 1hr, 6hr, 12hr, Today, Yesterday, 7 days, 30 days, Custom range |
| Campaign | Filter by specific campaign |
| Status | Success, Failed, Retried |
| Type | Single, Bulk, Retry, Test |
| Error Type | Filter by specific error categories |
Email Details: Click the eye icon on any row to view the full email details including recipient, sender, subject, body, and error message (if failed).
Graph App Permission
Import Microsoft 365 accounts using application permissions. One Azure AD app can send as all users in a tenant — no refresh tokens needed.
How to Import
- Go to the Import tab and select Microsoft Graph API
- Select the Graph App Permission inner tab
- Enter an optional App Name to identify this app
- Enter your Tenant ID, Client ID, and Client Secret from Azure AD
- Add the user emails (one per line) that this app should send as
- Click Import Accounts
Required Fields
| Field | Required | Description |
|---|---|---|
| App Name | No | A friendly label for this Azure AD app |
| Tenant ID | Yes | Your Azure AD tenant identifier (GUID) |
| Client ID | Yes | The application (client) ID from Azure AD |
| Client Secret | Yes | A client secret value created in Azure AD |
| User Emails | Yes | Email addresses to send as (one per line) |
Azure AD Setup: Your Azure AD app needs the Mail.Send application permission with admin consent. See the setup guide linked on the Import page for step-by-step instructions.
Tip: App permission accounts don't require individual refresh tokens — a single app registration covers all users in the tenant, making bulk account management much simpler.
Graph Delegated
Import Microsoft accounts using delegated permissions with refresh tokens. Each account authenticates individually via OAuth.
How to Import
- Go to the Import tab and select Microsoft Graph API
- Select the Graph Delegated (Refresh Token) inner tab
- Prepare a JSON file with your apps and accounts (see format below)
- Click Import Tokens and select your JSON file
JSON Import Format
{
"apps": [
{
"app_name": "My Azure App",
"client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"client_secret": "your-client-secret-value",
"accounts": [
{
"email": "user@yourdomain.com",
"refresh_token": "0.AAAA..."
}
]
}
]
}Each app can contain multiple accounts. The import page includes a step-by-step guide for generating refresh tokens.
Account Management
After importing, you can manage delegated accounts directly from this tab:
- Validate All: Check that all refresh tokens are still valid
- Filter & Search: Filter by status (active/inactive), sort by sent count, and search by email
- Bulk Actions: Select multiple accounts to activate, deactivate, or delete them
- Pagination: Choose how many accounts to display per page (10 to 5000)
Token Validation
Click Validate All to check every account's refresh token. The validation process shows:
- A progress bar with current/total count
- Valid (green) and invalid (red) counts
- Pause, resume, and stop controls
Required Permissions: Your Azure AD app needs delegated permissions for Mail.Send, Mail.ReadWrite, offline_access, and User.Read.
Tip: Refresh tokens are long-lived and auto-renew. You typically only need to generate them once per account. If a token expires, follow the refresh token guide on the Import page to regenerate it.
SMTP Accounts
Add SMTP accounts for direct server-based email sending.
Supported Presets
Adding SMTP Accounts
- Single Add: Click "Add SMTP Account", select a preset or enter custom server details
- Bulk Import: Paste multiple accounts in email:password format (one per line)
- Each account needs: email, password, SMTP host, port, and encryption type (TLS/SSL)
Provider Selection: Go to Settings → Email Provider to choose which provider(s) to use: SMTP only, Graph API only, Firebase / GCP only, both (Graph + SMTP), or all providers together.
Disabled Accounts
Accounts that have been automatically suspended due to errors are listed here, categorized by ban type.
Permanent Ban
Cannot be re-enabled. Only delete is available.
- Invalid credentials or token errors
- Account suspended by Microsoft
- 2 consecutive unknown failures
Soft Ban (Daily Limit)
Can be restored manually or resets the next day.
- Daily sending limit exceeded
- Rate limiting / quota errors
- Temporary throttling
Account Rotation
Automatically distribute email sending across multiple accounts to stay within limits and improve deliverability.
Rotation Modes
| Mode | Behavior |
|---|---|
| Round Robin | Cycles through accounts in order, one after another |
| Random | Randomly selects an account for each email |
| Least Used | Picks the account with the fewest sends today |
Daily Limits
Each account has a configurable daily sending limit (1–10,000). When an account reaches its limit, it's automatically soft-banned for the day and rotation moves to the next available account.
Recommended: 100 emails/day per account for safe sending.
Real-time: Rotation mode and daily limit changes apply immediately to running campaigns — no restart needed.
Firebase Billing Accounts
Manage Google Cloud billing accounts used for Firebase project creation. Each billing account stores credentials and can be connected via OAuth2 for automated project management.
Adding a Billing Account
- Navigate to the Firebase section
- Click Add Billing Account
- Enter a Display Name to identify this account
- Enter the Google account Email and Password
- Optionally enter a TOTP Secret if the account uses two-factor authentication
- Click Save
Required Fields
| Field | Required | Description |
|---|---|---|
| Display Name | Yes | A friendly label to identify this billing account |
| Yes | The Google account email address | |
| Password | No | The account password |
| TOTP Secret | No | Two-factor authentication secret (base32). When provided, a live 2FA code is displayed in the accounts table with a countdown timer. |
OAuth2 Connection
Connect a billing account to Google Cloud via OAuth2 for automated project and resource management:
- Open the billing account and go to the OAuth section
- Copy the Redirect URI shown below the OAuth fields — click the copy icon next to it to copy it to your clipboard, then add it as an authorized redirect URI in your Google Cloud OAuth credentials
- Enter your Google Cloud OAuth2 Client ID and Client Secret
- Click Save Credentials
- Click Connect to start the Google authorization flow
- Authorize access in the Google consent screen that opens
- Once redirected back, a green status banner appears showing the authenticated Google email and confirming the OAuth2 connection is active
Managing Accounts
- Live 2FA Codes: If a TOTP secret is saved, the accounts table shows a live 6-digit code that refreshes every 30 seconds. A countdown bar indicates when the next code generates. Click the copy icon next to the code to copy it to your clipboard.
- Edit: Update display name, email, password, or TOTP secret at any time
- Connection Status: When connected, a green banner displays the authenticated Google email. If you experience permission errors, use the Reconnect link in the amber hint below the banner to re-authorize with all required scopes.
- Disconnect OAuth: Revoke the Google OAuth connection by clicking Disconnect on the green status banner. This clears the stored tokens and sets the account status back to disconnected. You can reconnect at any time by clicking Connect again.
- Delete: Removes the billing account and all associated Firebase projects and tenants
- Status: View connection status and the linked Google email
Prerequisites — API & OAuth Setup
Before connecting an account, complete these one-time steps in Google Cloud Console:
- Enable the following APIs in your Google Cloud project:
- Cloud Resource Manager API
- Cloud Billing API
- IAM API
- Create an OAuth2 App at the Google Auth Overview page (choose External app type)
- Set the callback URL to your app's Redirect URI (displayed in the Firebase tab under the OAuth fields — click the copy icon to copy it)
- Publish the OAuth app: go to the OAuth Consent Screen and click Publish App to move it from Testing to Production
- Copy the OAuth2 Client ID and Client Secret into the account detail view
Project Provisioning
Once your Google account is connected via OAuth, you can provision Firebase on your GCP projects:
- Open a billing account and scroll to Setup Firebase on Projects
- Click Fetch Projects to load your GCP projects from Google
- Select the projects you want to provision using the checkboxes (or use Select All)
- Click Provision Selected to start the automated setup
Each project goes through 8 automated steps:
Provisioning Progress & Error Hints
During provisioning, each step shows a live status indicator. If a step fails, an inline error message and actionable troubleshooting hints appear directly in the progress panel:
| Step | Common Error | What to Check |
|---|---|---|
| Step 2 — Link Billing | 400 or FAILED_PRECONDITION | Verify the billing account is active. Try linking the project to billing manually in the Google Cloud Console. |
| Step 4 — Add Firebase | 403 Forbidden / Terms of Service | Firebase ToS not accepted for this Google account. Go to the Firebase Console, start creating any project (you can cancel after the spinner), then retry. This is a one-time step per Google account. |
Steps that depend on a failed earlier step (e.g., steps 5–6 when step 4 fails) are shown as Skipped with a gray indicator instead of red, so you can focus on fixing the root cause.
Fix Service Account Permissions
If a provisioned project has permission issues, select it and click Fix SA Permissions to re-apply the required service account roles.
Creating Tenants
After provisioning, create Firebase Auth tenants on your projects:
- Open the Create Tenants modal from the Firebase tab
- Set the number of Tenants per project (default is 100, max 1000)
- Filter projects by account or search by name
- Select the projects you want to create tenants on
- Click Create Tenants
Auto-Registration: Newly created tenants are automatically registered as sendable accounts in the system. Each tenant gets a unique sender email derived from its display name (e.g., firstname.lastname@{project-id}.firebaseapp.com) and uses the tenant's display name as the sender name. If user creation fails for a tenant, it falls back to noreply@{project-id}.firebaseapp.com. All new accounts immediately appear in your account rotation and can be used for sending emails — no extra setup needed.
Warning: Deleting a billing account also removes all Firebase projects and tenants linked to it. This action cannot be undone.
OAuth2 Setup: You need a Google Cloud project with the OAuth consent screen configured and credentials created. Use the "Web application" credential type and add your app's callback URL as an authorized redirect URI.
Tip: Use the Refresh button to reload the project list after creating new GCP projects in the Google Cloud Console.
Tab Layout: The Firebase / GCP section is organized into two inner tabs: Accounts & Setup for managing billing accounts, OAuth connections, and project provisioning, and Delivery Management for tenant and domain operations across your provisioned projects.
Firebase Delivery Management
Manage tenants, custom domains, and user access across all your provisioned Firebase projects from a single view. Access this via the Delivery Management inner tab inside the Firebase / GCP section.
Projects Table
The Delivery Management view shows all provisioned projects in a table with the following columns:
| Column | Description |
|---|---|
| Billing Account | The parent billing account that owns this project |
| Project | The GCP project name |
| Domain | Custom domain configured for this project (if any) |
| API Key | The Firebase API key for the project |
| Project Status | Whether the project is fully provisioned |
| Tenants | Number of tenants created on this project |
| Tenants Status | Health status of the tenants |
| Access | User access configuration for the project |
Bulk Actions
Select one or more projects using the checkboxes, then use the toolbar buttons:
| Action | Description |
|---|---|
| Create Tenants | Create Firebase Auth tenants on the selected projects. New tenants are automatically registered as sendable accounts using noreply@{project-id}.firebaseapp.com as the sender email and the tenant's display name as the sender name. |
| Check Tenants | Verify the status and health of existing tenants |
| Delete Tenants | Remove all tenants from the selected projects |
| Setup Domain | Configure a custom domain for the selected projects |
| User Access | Manage which users can access the selected projects |
Filtering & Pagination
- Use the Search box to filter projects by name
- Change the rows per page (10, 25, or 50) using the dropdown
- The project count is displayed next to the section heading
Warning: Deleting tenants is irreversible. Make sure no active sending operations depend on the tenants before removing them.
Tip: Use Check Tenants periodically to verify that all tenants are healthy and properly configured before running campaigns.
Templates
Save and reuse email templates with dynamic variables for personalized campaigns.
Managing Templates
- Save: Click "Save as Template" from the Single Email or Bulk Send tab
- Load: Click "Templates" button to open the Template Manager and load a saved template
- Edit: Modify template name, subject, and body from the Template Manager
- Preview: View rendered template before loading
- Create New: Build templates directly in the Template Manager
- Delete: Remove templates you no longer need
Email Lists
Import and manage recipient email lists for use in bulk campaigns.
Supported Formats
Features
- Import from file upload or paste emails directly
- Automatic email validation and deduplication
- Preview list contents before using
- Load directly into Bulk Send recipients
- Rename and delete lists
- Filter lists by date range
- Export list emails
Unsubscribe Management
Manage email unsubscriptions with automatic link generation and recipient filtering.
How It Works
- Add {{unsubscribe_url}} to your email template footer
- Each recipient gets a unique, token-based unsubscribe link
- When clicked, recipients see an unsubscribe page where they can select a reason
- Unsubscribed emails are automatically skipped in future campaigns
Management Features
- View all unsubscribers with reason and campaign info
- Manually add or remove emails from the unsubscribe list
- Bulk import unsubscribers
- Export unsubscriber list
- Search and filter unsubscribers
- Stats: total unsubscribed, this week's count
Attachments
Attach files to both single and bulk emails. Files are sent inline with each email via Graph API or SMTP.
Limits
| Limit | Value |
|---|---|
| Max total size | 25 MB (combined across all files) |
| Max file count | 10 files per email |
How to Attach Files
- Drag and drop files onto the attachment zone in the Single Email or Bulk Send tab
- Or click the attachment zone to browse and select files
- Files are uploaded immediately and listed with name and size
- Click the X button on any file to remove it before sending
Bulk campaigns: Attachments are shared across all recipients in the campaign. Every recipient receives the same set of files.
Note: Large attachments increase send time and may trigger spam filters. Keep attachments small and relevant. Some email providers may reject messages over 25 MB.
List-Unsubscribe Headers
Choco Mailer automatically adds RFC 8058 compliant List-Unsubscribe headers to improve deliverability and inbox placement.
How It Works
- When your email template contains {{unsubscribe_url}}, the system automatically adds two headers to each outgoing email:
List-Unsubscribe: <https://your-domain.com/api/unsubscribe/TOKEN> List-Unsubscribe-Post: List-Unsubscribe=One-Click
These headers are added for both Graph API and SMTP emails.
Why It Matters
- Gmail, Outlook, and Yahoo show a visible "Unsubscribe" button in the email header
- Improves sender reputation and reduces spam complaints
- Required by many email providers for bulk senders
- One-Click unsubscribe support (RFC 8058) is the modern standard
Tip: Always include {{unsubscribe_url}} in your email templates. It enables both the in-body unsubscribe link and the header-based one-click unsubscribe for email clients.
Email Tracking
Track email opens, link clicks, and recipient engagement with pixel-based tracking and link rewriting.
How Tracking Works
Open Tracking
A 1x1 transparent pixel is injected into HTML emails. When the recipient opens the email and loads images, the pixel fires and records the open event with timestamp, IP, and user agent.
Click Tracking
All links in the email are rewritten to pass through the tracking server. When clicked, the click is recorded and the user is redirected to the original URL.
Tracking Metrics
| Metric | Description |
|---|---|
| Total Opens | Total number of times emails were opened (includes repeat opens) |
| Unique Opens | Number of unique recipients who opened the email |
| Open Rate | Unique opens ÷ total sent × 100% |
| Total Clicks | Total link clicks across all recipients |
| Click Rate | Unique clickers ÷ total sent × 100% |
| Click-to-Open Rate | Unique clickers ÷ unique openers × 100% |
| Unsubscribes | Number of recipients who unsubscribed from this campaign |
| Top Clicked Links | Ranking of most-clicked URLs in the email |
Note: Open tracking requires the recipient's email client to load images. Some clients block images by default, so actual open rates may be higher than reported.
Tracking Domains
Use custom domains for branded tracking links instead of your server's IP or default domain.
Setup Steps
- Go to Settings → Custom Tracking Domain
- Enter your domain (e.g., track.yourdomain.com)
- Click "Add" — the system generates a TXT DNS record for verification
- Add the TXT record to your domain's DNS settings
- Click "Verify" — the system checks the DNS record
- Once verified, click "Activate" to start using the domain
Auto SSL: When a domain is activated, the system automatically configures Caddy reverse proxy with SSL certificates for HTTPS tracking links.
Tip: You can have multiple tracking domains and select which one to use per campaign from the Bulk Send tab.
Reports & Export
Generate and download detailed campaign reports in multiple formats.
Export Formats
PDF Report
Professional PDF with campaign summary, tracking stats, and detailed recipient data.
Excel Report
Spreadsheet with all tracking data, opens, clicks, and recipient details for analysis.
How to export: Open a campaign → Click "View Tracking Report" → Click "Export Report" → Choose PDF or Excel.
Settings
Configure all aspects of the email sending engine. Some settings apply in real-time to running campaigns.
Settings Reference
| Setting | Default | Applies | Description |
|---|---|---|---|
| Email Provider | SMTP | Real-time | SMTP Only, Graph API Only, Firebase / GCP Only, Both (Graph API + SMTP), or All Providers |
| Rotation Enabled | On | Real-time | Toggle account rotation |
| Rotation Mode | Round Robin | Real-time | Round Robin, Random, Least Used |
| Daily Limit | 100 | Real-time | Max emails per account per day (1–10,000) |
| Delay | 25s fixed | Real-time | Fixed or random range (1–300 seconds) |
| Thread Count | 5 | New campaigns | Parallel sending threads (1–1,000) |
| Max Retries | 2 | Real-time | Retry attempts before banning (1–5) |
| Tracking | Off | New campaigns | Enable open/click tracking |
Real-time settings (marked with a green badge in the UI) take effect immediately on running campaigns without needing to restart them.
AI Content Spinner
Automatically generate unique subject line and body variations for each email in a campaign to improve deliverability and avoid spam filters.
Supported AI Providers
OpenAI
GPT-4o-mini
Google Gemini
Gemini API
Anthropic Claude
Claude API
How It Works
- Subject Variations: AI generates 1–20 unique subject line variations from your original
- Body Variations: Local synonym-based spinning creates 1–10 body versions
- Each email in the campaign gets a randomly selected variation
- If AI fails, the system falls back to the local spinner
Setup
- Go to Settings → AI Content Spinner
- Enable the AI Spinner toggle
- Select your preferred AI provider
- Enter the API key for your chosen provider
- Set the number of subject and body variations
- Save settings
API Keys: Only the key for the selected provider is used. Keys are stored encrypted on the server.
Test Mails
Send periodic test emails during campaigns to monitor delivery and content quality.
Configuration
| Option | Description |
|---|---|
| Test Recipients | Up to 25 email addresses (one per line). A random one receives each test. |
| Content Type | Stats: Campaign progress report | Copy: Exact email as recipients see it |
| Trigger: Time-based | Send a test every X minutes/seconds |
| Trigger: Interval-based | Send a test after every X emails sent |
Note: Test emails are sent when a campaign starts/resumes and stop when paused/stopped/completed. View test logs in the History tab by filtering for type "Test".
Application Logs
Real-time application log viewer with filtering, search, and auto-refresh. Admin only.
Features
- Time Range: Quick filters for 30min, 1hr, 2hr, 6hr
- Log Level: Filter by DEBUG, INFO, WARNING, ERROR, CRITICAL
- Module: Filter by application module
- Search: Full-text search across log entries
- Auto-refresh: Toggle real-time log streaming
- Download: Export logs as a file
- Stats: Visual count of entries by log level
Log Retention
- Hot log: Current log file (up to 1MB)
- Daily rotation: Logs rotate daily with 7-day retention
Template Variables
Use dynamic variables in your email templates for personalization. Variables are replaced with actual values when the email is sent.
| Variable | Description | Example Output |
|---|---|---|
| {{email}} | Recipient's email address | user@example.com |
| {{date}} | Current date | 2026-03-05 |
| {{time}} | Current time | 14:30:00 |
| {{unsubscribe_url}} | Unique unsubscribe link for the recipient | https://track.domain.com/api/unsubscribe/... |
Troubleshooting
Accounts getting permanently banned
This usually means the account credentials are invalid or the provider has blocked the account. Re-check the SMTP credentials and try re-importing. Check the Disabled Accounts tab for the specific error message.
Accounts getting soft banned quickly
Your daily limit per account may be too high. Microsoft typically allows ~100 emails/day for consumer accounts. Lower the daily limit in Settings and add more accounts.
Tracking not working
- Ensure tracking is enabled in Settings
- Verify your tracking domain is set up and activated
- Ensure the tracking domain DNS is pointing to your server
Campaign stuck or not progressing
- Check if all accounts are disabled (go to Disabled Accounts tab)
- Verify the campaign status is "running" (not paused or stopped)
- Check the Logs tab for error messages
SMTP connection errors
Verify the SMTP host, port, and encryption settings. For Gmail, you need an App Password (not your regular password). For other providers, check if "less secure apps" or SMTP access is enabled.
Slow sending speed
Increase the thread count in Settings (each thread uses a different account). Reduce the delay between sends. Add more active accounts. Formula: accounts × threads ÷ delay = emails/second
Choco Mailer Documentation
Professional Email Marketing Platform