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.
Import Accounts
Go to the Import tab and add accounts via Microsoft Graph API or SMTP. You need at least one active sending account.
Configure Settings
Visit Settings to configure rotation mode, daily limits, delay, thread count, and optionally enable tracking and AI spinner.
Compose & Send
Use Single Email for one-off emails, or Bulk Send for campaigns. Write content using the rich text editor or raw HTML.
Monitor & Track
View campaign progress in Campaigns, 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 | β | β |
βοΈ Single Email
Send individual emails to a single recipient with full control over content and sender.
Fields
| Field | Required | Description |
|---|---|---|
| Send From | No | Choose a specific account 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 (rich text), HTML (raw code), and Preview using the toggle buttons above the message area.π¨ 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, upload a file (.txt, .csv, or .xlsx), 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
Adding Recipients
There are three ways to populate the recipients list:
- Paste manually β type or paste email addresses directly into the text area, one per line
- Upload File β click the
Upload Filebutton to import recipients from a.txt,.csv, or.xlsxfile - Email Lists β click the
Email Listsbutton to load a previously saved list
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)
Duplicate Handling
When duplicates are detected in your recipient list, a warning badge shows the count. You have two options:
- Remove Duplicates β click the button to automatically de-duplicate the list (recommended for most campaigns)
- Allow Duplicates β check the
Allow duplicatescheckbox to intentionally send to the same email address multiple times (useful when the same recipient needs multiple distinct notifications)
Random Sender Name
Override the default sender display name on each email with a randomly picked name from a list you provide. This helps vary the "From" name across a campaign for better deliverability.
- Toggle
Random Sender Nameon (below the Tracking Domain selector) - Enter names in the text area β one name per line β or click
Upload Fileto load a.txtor.csvfile of names - The counter below the text area shows how many names are loaded
- When the campaign sends, each email picks a random name from the list as its "From" display name
π Campaigns
View, manage, and analyze all your email campaigns from a single dashboard.
Campaign Statuses
Campaign Details
- 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
Filtering & Sorting
- Search by campaign name or UUID
- Filter by status, sort by newest/oldest/name/most recipients
- Export/import campaigns as JSON
- Paginated results for large campaign lists
π Send History
Complete log of every email sent through the platform with powerful filtering.
| 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 |
π’ 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.
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) |
Mail.Send application permission with admin consent.π Graph Delegated
Import Microsoft accounts using delegated permissions with refresh tokens. Each account authenticates individually via OAuth.
JSON Import Format
{
"apps": [{
"app_name": "My Azure App",
"client_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"client_secret": "your-client-secret",
"accounts": [{ "email": "user@domain.com", "refresh_token": "0.AAAA..." }]
}]
}Account Management
- Validate All: Check that all refresh tokens are still valid
- Filter & Search: Filter by status, sort by sent count, search by email
- Bulk Actions: Activate, deactivate, or delete multiple accounts
- Pagination: 10 to 5000 accounts per page
Mail.Send, Mail.ReadWrite, offline_access, User.Readπ₯οΈ 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: Click "Bulk Import" and choose one of two methods:
π Paste Text
Paste accounts directly into the text area, one per line
π Upload File
Upload a .txt, .csv, or .xlsx file
Each account needs: email, password, and SMTP host β host and port are auto-detected for known providers.
Bulk Import Formats
Use the | (pipe) delimiter for best results, especially if your password contains colons:
email@gmail.com|password email@gmail.com|password|smtp.gmail.com|587 email@custom.com|my:complex:password|mail.custom.com|465 email@custom.com|pass|smtp.custom.com|587|John Doe email@custom.com|pass|smtp.custom.com|587|John Doe|auth@provider.com
Triple-dash --- format for separate sender and authentication emails:
sender@domain.com---smtp.host.com:587----auth@provider.com----password sender@domain.com---smtp.host.com:587----password
Slash-star /*/ format with explicit fields (sender, auth, password, host, port, encryption):
sender@domain.com/*/auth@provider.com/*/password/*/smtp.host.com/*/587/*/STARTTLS sender@domain.com/*/auth@provider.com/*/password/*/smtp.host.com/*/465/*/SSL
Colon : delimiter is also supported for simple passwords:
email@gmail.com:password email@gmail.com:password:smtp.gmail.com:587
Encryption Options
| Option | Port | Description |
|---|---|---|
| Auto (Detect) | β | Automatically selects the best encryption based on the port you enter |
| SMTP Port 1 (25) | 25 | No encryption β plain SMTP on port 25, typically used for server-to-server relay |
| SMTP Port 2 (2525) | 2525 | No encryption on port 2525 β an alternative plain port when port 25 is blocked |
| STARTTLS (587) | 587 | Upgrades the connection to TLS after connecting β the standard submission port |
| SSL/TLS (465) | 465 | Full TLS from the start β legacy SSL port, still widely supported |
| delimiter if your password contains colons or special characters. Use the triple-dash format when your sending address differs from your SMTP login. The slash-star /*/ format is useful when you need to explicitly specify the encryption type per account.π« Disabled Accounts
Accounts automatically suspended due to errors, 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.
| 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 |
π₯ Firebase Billing Accounts
Manage Google Cloud billing accounts used for Firebase project creation, connected via OAuth2 for automated project management.
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). Shows a live 6-digit code with 30s countdown. |
π₯ Firebase Delivery Management
Manage tenants, custom domains, and user access across all provisioned Firebase projects. Access via the Delivery Management inner tab inside Firebase / GCP.
Bulk Actions
| Action | Description |
|---|---|
Create Tenants | Create Firebase Auth tenants on selected projects with real-time progress overlay. |
Check Tenants | Verify status and health of existing tenants. If none selected, all projects are checked. |
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. |
Check Tenants periodically before running campaigns. If no projects are selected, all projects are checked automatically.π Templates
Save and reuse email templates with dynamic variables for personalized campaigns.
- Save: Click "Save as Template" from Single Email or Bulk Send
- Load: Click "Templates" to open the Template Manager
- Edit: Modify name, subject, and body from the Template Manager
- Preview: View rendered template before loading
- Delete: Remove templates you no longer need
π§ Email Lists
Import and manage recipient email lists for use in bulk campaigns.
Supported Formats
- Import from file upload or paste emails directly
- Automatic email validation and deduplication
- Load directly into Bulk Send recipients
- Rename, delete, filter by date range, and export lists
π· 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 to select a reason
- Unsubscribed emails are automatically skipped in future campaigns
- View all unsubscribers with reason and campaign info
- Manually add or remove emails from the unsubscribe list
- Bulk import / export unsubscribers
- Search, filter, and view stats
π Attachments
Attach files to both single and bulk emails via Graph API or SMTP.
| Limit | Value |
|---|---|
| Max total size | 25 MB (combined across all files) |
| Max file count | 10 files per email |
π List-Unsubscribe Headers
Choco Mailer automatically adds RFC 8058 compliant List-Unsubscribe headers to improve deliverability and inbox placement.
When your template contains {{unsubscribe_url}}, two headers are automatically added:
List-Unsubscribe: <https://your-domain.com/api/unsubscribe/TOKEN> List-Unsubscribe-Post: List-Unsubscribe=One-Click
- Gmail, Outlook, and Yahoo show a visible "Unsubscribe" button in the email header
- Improves sender reputation and reduces spam complaints
- One-Click unsubscribe (RFC 8058) is the modern standard
{{unsubscribe_url}} in your templates β it enables both the in-body link and the header-based one-click unsubscribe.ποΈ Email Tracking
Track email opens, link clicks, and recipient engagement with pixel-based tracking and link rewriting.
How Tracking Works
Open Tracking
A 1Γ1 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 |
π 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
π Reports & Export
Generate and download detailed campaign reports in multiple 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.
βοΈ Settings
Configure all aspects of the email sending engine. Settings marked Real-time apply immediately to running campaigns.
| Setting | Default | Applies | Description |
|---|---|---|---|
| Email Provider | SMTP | Real-time | SMTP Only, Graph API Only, Firebase / GCP Only, Both (Graph + 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 (0β999,999). Set to 0 for unlimited. |
| 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 |
| Firebase Sender Name | Empty | Real-time | Custom "From" display name for Firebase / GCP accounts. Leave empty to use the default tenant display name. |
β¨ AI Content Spinner
Automatically generate unique subject line and body variations for each email 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 and enter the API key
- Set the number of subject and body variations, then save
βοΈ Test Mails
Send periodic test emails during campaigns to monitor delivery and content quality.
| 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 |
π Application Logs
Real-time application log viewer with filtering, search, and auto-refresh. Admin only.
- 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
Log Retention
- Hot log: Current log file (up to 1MB)
- Daily rotation: Logs rotate daily with 7-day retention
π Language / θ¨θͺ / θ―θ¨
Choco Mailer supports multiple interface languages. Switch the entire UI β including menus, buttons, labels, and modals β to your preferred language.
Supported Languages
| Language | Code | Coverage |
|---|---|---|
| English | en | Full |
| ζ₯ζ¬θͺ (Japanese) | ja | Full |
| δΈζ (Chinese) | zh | Full |
How to Change Language
- Look for the
Languageselector in the dashboard header or settings area - Click the dropdown and choose your preferred language
- The interface updates immediately β no page reload required
- Your language preference is saved and persists across sessions
{ } Template Variables
Use dynamic variables in your email templates for personalization. Variables are replaced with actual values when the email is sent.
Built-in Variables
| 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/... |
Custom Variables
Create your own reusable variables to personalize emails beyond the built-in options. Custom variables can hold a fixed value or a list of random values.
| Field | Description |
|---|---|
| Name | Variable name β letters, numbers, and underscores only (e.g., company_name) |
| Value | The replacement text. For random mode, enter one option per line. |
| Random Mode | When enabled, a random line from the value is picked each time the variable is used |
Managing Custom Variables
- Go to the
Settingstab and scroll to theCustom Variablessection - Click
Add Variableto create a new one - Enter a name (e.g.,
sender_company) and a value - Choose the type:
Staticfor a fixed value, orRandomto pick a random line each time - Click
Saveto store the variable - Use it in your email subject or body as
{{sender_company}}
You can also edit an existing variable by clicking the edit icon, or delete it with the trash icon.
email, date, time, random, unsubscribe_url).π§ 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 SMTP access is enabled.
Slow sending speed
Increase the thread count in Settings. Reduce the delay between sends. Add more active accounts. Formula: accounts Γ threads Γ· delay = emails/second
Choco Mailer Documentation
Professional Email Marketing Platform