Skip to content

Send bulk emails (mail merge)

Request

Send the same email template to multiple recipients with personalization.

Mail merge functionality for:

  • Newsletters with personalized greetings
  • Marketing campaigns with custom variables
  • Bulk transactional emails with recipient-specific data

Features:

  • Template variables: Use {{variable}} syntax in subject, HTML, and text
  • Built-in placeholders: {{unsubscribe}} for unsubscribe links
  • Per-recipient personalization via vars object
  • Automatic variable substitution for each recipient
  • Single template, many recipients
  • File attachments (same for all recipients)
  • Calendar invites (same for all recipients)

Limits:

  • Recommended: Up to 10,000 recipients per call
  • Each recipient gets their own personalized copy

Use cases:

  • Newsletter campaigns: "Hi {{name}}, check out our new {{product}}..."
  • Promotional emails with unique discount codes
  • Event invitations with personalized details

Built-in Placeholders:

  • {{unsubscribe}} - Secure unsubscribe link (unique per recipient)

Not for: Different emails to each recipient → Use /api/batch instead

Security
ApiKeyAuth
Bodyapplication/jsonrequired
campaign_idstring

Optional campaign identifier for grouping related emails and tracking bounce rates.

Auto-pause protection: If bounce rate exceeds thresholds, the campaign will be automatically paused to protect IP reputation.

How Campaign Grouping Works:

  • All emails with the same campaign_id group into ONE campaign session
  • Bounce rates are calculated across the entire group
  • Auto-pause applies to ALL future sends using this campaign_id
  • Campaign reports aggregate all metrics together

⚠️ CRITICAL: Each campaign MUST use a UNIQUE campaign_id

Best Practices:

  • DO: Use unique IDs per campaign send
    • Good: "monthly-newsletter-2026-03-05"
    • Good: "spring-sale-2026-week1"
    • Good: "product-launch-v2-2026-03"
  • DON'T: Reuse campaign_id across different campaigns
    • Bad: "newsletter" (reused every month)
    • Bad: "promo" (reused for all promos)
    • Bad: "bulk-send" (too generic)

Why This Matters: If you reuse a campaign_id:

  • Bounce rates from OLD campaigns affect NEW campaigns
  • New campaign might be immediately paused due to old bounces
  • Campaign reports mix data from different time periods
  • Cannot track individual campaign performance

Recommended Format: {campaign-name}-{date} or {campaign-name}-{version}-{date}

Examples:

  • Monthly newsletters: "newsletter-2026-03", "newsletter-2026-04"
  • Sales campaigns: "spring-sale-2026-w1", "spring-sale-2026-w2"
  • Product launches: "product-x-launch-2026-03-05"

If not provided, system auto-generates: bulk-{timestamp}-{customer_id}

Example:"spring-sale-2026-march"
subjectstringrequired

Email subject with optional variables like {{name}} or {{code}}.

Important: If using personalization, also provide subject_template for proper campaign tracking.

Example:"Hello {{name}}! Your code is {{code}}"
subject_templatestring

Recommended when using personalized subjects. The template before variable substitution.

Why needed: Helps system track campaigns correctly when subjects are personalized.

Example:

  • subject_template: "Hello {{name}}! Your code is {{code}}"
  • Actual subject for each recipient: "Hello John! Your code is SAVE20"

If not provided, system normalizes the subject automatically (less accurate).

Example:"Hello {{name}}! Your code is {{code}}"
preview_textstring

Preview/preheader text shown in email clients next to subject (40-130 characters recommended). Appears in inbox list view before opening the email.

Example:"Exclusive offer just for you - save 20% today!"
htmlstring

HTML email body with variables

Example:"<h1>Hi {{name}}</h1><p>Your discount code: {{code}}</p>"
textstring

Plain text email body with variables. Supports the same {{variable}} merge fields as html.

Auto-generation: If omitted, a plain-text version is automatically generated from html before sending. Supplying your own text is recommended for best plain-text client rendering.

Example:"Hi {{name}}, Your discount code: {{code}}"
fromstring, (email)

From email (must use verified domain, optional)

Example:"hello@mail.yourdomain.com"
from_namestring

Display name for the sender (appears as "From Name ")

Example:"Your Company"
domainstring

Sending domain (optional - auto-extracted from from email if not provided). If provided, must match the domain in from email address.

Example:"mail.yourdomain.com"
reply_tostring, (email)

Reply-to address

Example:"support@yourdomain.com"
track_opensboolean

Enable open tracking (default: true)

Default:true
Example:true
track_clicksboolean

Enable click tracking (default: true)

Default:true
Example:true
tagstring

Tag for organizing/filtering emails

Example:"newsletter-2025-12"
stream_typestring

Stream type is locked to broadcast for bulk sending. Bulk/mail merge emails are marketing/newsletter content and must use the broadcast stream to protect transactional IP reputation.

Default:"broadcast"
Value:"broadcast"
Example:"broadcast"
attachmentsArray of objects

File attachments sent with every email (sent directly, not stored). Same attachments sent to all recipients.

icalEventstring

iCal calendar event in RFC 5545 format (sent directly, not stored). Same calendar invite sent to all recipients.

recipientsArray of objectsrequired

Array of recipients with personalization variables

Example:
[ { "email": "john@example.com", "vars": {} }, { "email": "jane@example.com", "vars": {} } ]
curl -i -X POST \
  https://api.mailerlogic.net/api/v1/bulk-send \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: YOUR_API_KEY_HERE' \
  -d '{
    "campaign_id": "spring-sale-2026-discount-20",
    "subject": "Hello {{name}}! Special offer inside",
    "subject_template": "Hello {{name}}! Special offer inside",
    "preview_text": "Exclusive discount code just for you - save 20% today!",
    "html": "<h1>Hi {{name}}</h1><p>Use code <strong>{{code}}</strong> for 20% off!</p><p><a href=\"{{unsubscribe}}\">Unsubscribe</a></p>",
    "text": "Hi {{name}}, Use code {{code}} for 20% off!\n\nUnsubscribe: {{unsubscribe}}",
    "from": "hello@mail.yourdomain.com",
    "from_name": "Your Company",
    "track_opens": true,
    "track_clicks": true,
    "tag": "holiday-sale-2025",
    "stream_type": "broadcast",
    "recipients": [
      {
        "email": "john@example.com",
        "vars": {
          "name": "John",
          "code": "JOHN20"
        }
      },
      {
        "email": "jane@example.com",
        "vars": {
          "name": "Jane",
          "code": "JANE20"
        }
      }
    ]
  }'

Responses

Bulk send request accepted and queued for delivery

Bodyapplication/json
messagestring
Example:"Emails queued for delivery"
queuedinteger

Number of emails successfully queued

Example:2
errorsinteger

Number of emails that failed to queue

Example:0
campaign_idstring, (uuid)

Campaign tracking UUID - Use this ID to query campaign reports via /api/v1/campaign-reports/{campaign_id}.

This is the bulk_session_id that groups all emails in this campaign together for analytics.

IMPORTANT: Save this ID to track campaign performance, bounce rates, opens, and clicks.

Example:"f1e2d3c4-b5a6-7890-cdef-123456789abc"
bulk_session_idstring, (uuid)

Alias for campaign_id - Same UUID, different name for backwards compatibility.

Both campaign_id and bulk_session_id reference the same campaign session.

Example:"f1e2d3c4-b5a6-7890-cdef-123456789abc"
jobsArray of objects

Array of queued email jobs with tracking information

error_detailsArray of objects

Array of errors for failed recipients (only included if errors > 0)

Response
{ "message": "Emails queued for delivery", "queued": 2, "errors": 0, "campaign_id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", "bulk_session_id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", "jobs": [ {}, {} ] }