Overview
Email Campaigns are the tool you use to compose, schedule, send, and track emails to a defined audience. They rely on a prerequisite called a Campaign.
- Campaign (prerequisite): a named audience/list that groups Contacts and/or Organizations for marketing. In short, “who to send to.”
- Email Campaign: the message and delivery settings you apply when sending to that audience. In short, “what to send and when.”

Typical flow:
- Create a Campaign (Marketing > Campaigns) and ensure it contains the intended recipients.
- Go to Marketing > Email Campaigns and click “Send Email.”
- Fill in message content, pick the Campaign (audience), schedule and rate limit, then send.
- Track delivery, opens, clicks, bounces, and export reports.
Key capabilities at a glance:
- HTML/Markdown editor, variables for personalization (e.g., {{first_name}})
- Asset/image library and live preview
- Scheduling with emails-per-hour throttling and quiet-hours shift
- Delivery, open/click tracking, unsubscribe handling, and bounce processing
- Reports per campaign (+ CSV export)
Creating an Email Campaign
Open: Marketing > Email Campaigns → “Send Email” (route: email-messages.create). The form saves to email-messages.store and creates one queued message per contact in the selected Campaign.
Field-by-field guide (top to bottom):
- Campaign (select) — required
- Field:
campaign_id - Purpose: choose the audience list (Campaign) to send to. Only contacts in this Campaign with a valid primary email will receive messages.
- Tip: curate the Campaign first under Marketing > Campaigns.
- Field:
- Subject (input) — required
- Field:
subject - Purpose: the email subject line for all recipients.
- Recommendation: keep concise and benefit-led; avoid spammy phrasing.
- Field:
- Template Type (radio: HTML | Markdown) — required
- Field:
template_type(values:html,markdown) - Purpose: choose the editor mode.
- HTML: rich formatting, images, branded layout.
- Markdown: quick writing; converted to HTML on send.
- Field:
- Content (editor area)
- HTML mode:
body_html- Rich editor with toolbar.
- Helpers:
- Insert Variable: inject tokens like
{{first_name}},{{last_name}},{{primary_email}}, etc. These are replaced per-contact at send time. - Images: opens the image library modal. Upload supported types (jpg, png, gif, webp) up to 5 MB; uploaded assets are stored under
public/email-campaigns. - Preview: opens a modal showing the rendered content with sample variable values.
- Insert Variable: inject tokens like
- Markdown mode:
body_md- SimpleMDE editor; supports standard Markdown.
- Preview uses a basic Markdown → HTML conversion for a quick look.
- HTML mode:

- Scheduling (card)
- Emails per hour (number) — required
- Field:
emails_per_hour - Purpose: throttle sending to minimize spam filtering and protect sender reputation. Default: 200/hour (configurable per send).
- Field:
- Start time (datetime) — optional
- Field:
start_at - Purpose: begin sending later. If blank, sending starts immediately.
- Field:
- Respect quiet hours (checkbox)
- Field:
respect_quiet_hours(boolean) - Purpose: if enabled, scheduled batches that fall between 22:00–08:00 will shift to 08:00.
- Field:
- Emails per hour (number) — required

Other behaviors on Save:
- One Email Message row is created per eligible contact in the Campaign (table:
email_messages). - Each message receives a
batch_idand a scheduleddelaycomputed fromemails_per_hourandstart_at. - HTML sends are enhanced with tracking pixel, link tracking, and unsubscribe footer before dispatch.

Personalization variables available in content:
{{first_name}},{{last_name}},{{primary_email}},{{primary_phone}},{{mobile_phone}},{{username}},{{password}}
Campaign Reports
In the top right corner of the index page you will see a button that takes you to the Campaign Reports. For each Campaign Entity that you send out, you will have a Report record that includes:
- Columns/summary per Campaign:
- Status badge (draft/running/completed/failed)
- Total emails (
total_emails) - Delivered (
delivered_emails) - Failed (failed + bounced)
- Queued (
queued_emails) - Progress bar (computed from delivered + failed vs total)
- Started / Finished timestamps
- Actions:
- Details: route
email-campaigns.details→ shows all individual messages for the selected Campaign. - Download Report: route
email-campaigns.report→ CSV export with both a summary section and a detailed row-per-message section.
- Details: route
CSV export (what you get)
- Summary section (timestamp, counts: total, delivered, failed, queued, processing).
- Detailed rows (one per message) with:
id, campaign_id, batch_id, contact_id, to_email, subject, template_type, status, sent_at, delivered_at, error, created_at, updated_at. - Optional filter: you can pass a
batch_idquery string to narrow the CSV to a specific batch of a Campaign.
