Skip to content

Send email to a segment

Request

Send emails to contacts matching segment criteria using dynamic segmentation or saved segments.

Features:

  • Send to saved segments (by segment_id)
  • Send with inline segment filters (dynamic targeting)
  • NEW: Exclude unengaged contacts (improve deliverability & engagement metrics)
  • Account-level merge fields (same for all recipients)
  • Contact-level personalization (name, email, custom properties)
  • Asynchronous processing (returns immediately, processes in background)

Unengaged Filtering (NEW): Automatically exclude contacts who haven't opened or clicked any email in the last N days. This improves sender reputation, reduces costs, and increases engagement rates.

  • Set exclude_unengaged: true and unengaged_days: 90 (recommended)
  • Contacts with NO email activity in the lookback period are excluded
  • Perfect for newsletters, promotions, and regular campaigns
  • Disable for transactional emails (password resets, receipts, etc.)

Merge Fields:

  • Account-level: account_merge_fields - same value for all recipients (e.g., company_name, promo_code)
  • Contact-level: Automatically available ({{name}}, {{email}}, {{first_name}}, {{last_name}}, plus all custom properties)

Segmentation Options:

  • Option 1: Use existing segment → Provide segment_id
  • Option 2: Dynamic filters → Provide segment_filters object with filter conditions

Segment Filter Structure:

{
  "match_type": "all",  // "all" (AND) or "any" (OR)
  "filter_conditions": [
    {
      "property": "status",
      "operator": "equals",
      "value": "subscribed"
    },
    {
      "property": "tags",
      "operator": "contains",
      "value": "vip"
    }
  ]
}

Available Operators:

  • equals, not_equals, contains, not_contains
  • greater_than, less_than, greater_than_or_equal, less_than_or_equal
  • is_empty, is_not_empty, is_true, is_false

Limits:

  • Max 10 filter groups
  • Max 20 filters per group
  • Max 100 total filters

Use Cases:

  • Newsletter to all subscribed contacts
  • Promotional email to contacts tagged "vip"
  • Re-engagement campaign for inactive subscribers
  • Product updates to contacts with specific custom properties
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"
    • Good: "vip-flash-sale-2026-week12"
    • Good: "product-update-v3-2026-03-05"
  • DON'T: Reuse campaign_id across different campaigns
    • Bad: "newsletter" (reused every month)
    • Bad: "segment-send" (too generic)
    • Bad: "promo" (reused for all promos)

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"
  • VIP promotions: "vip-sale-2026-w1", "vip-sale-2026-w2"
  • Segment campaigns: "re-engagement-inactive-2026-q1"

If not provided, system auto-generates: segment-{segment_id}-{timestamp}

Example:"monthly-newsletter-2026-march"
segment_idstring, (uuid)

ID of saved segment (use this OR segment_filters, not both)

Example:"a1b2c3d4-e5f6-7890-abcd-ef1234567890"
segment_filtersobject

Inline segment filters (use this OR segment_id, not both)

subjectstringrequired

Email subject with merge field support.

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

Example:"Hello {{first_name}}!"
subject_templatestring

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

Why needed: Helps system track campaigns correctly when subjects are personalized. Without this, emails with different personalized subjects (e.g., "Hello John" vs "Hello Mary") are treated as separate campaigns, breaking bounce rate tracking.

Campaign Grouping:

  • With subject_template: All emails group into ONE campaign
  • Without: Each personalized subject creates a separate campaign

Example:

  • subject_template: "Hello {{first_name}}! Special offer inside"
  • Actual subject for John: "Hello John! Special offer inside"
  • Actual subject for Mary: "Hello Mary! Special offer inside"
  • Result: Both emails tracked together under the same campaign

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

Example:"Hello {{first_name}}! Special offer inside"
preview_textstring

Preview text shown in email clients (40-130 chars recommended)

Example:"Exclusive offer just for you"
htmlstringrequired

HTML email body with merge field support

Example:"<h1>Hi {{name}}</h1><p>Use code {{promo_code}}</p>"
textstring

Plain text email body with merge field support. Supports the same {{variable}} syntax 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}}, Use code {{promo_code}}"
fromstring, (email)required

From email address (must use verified domain)

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

Display name for sender

Example:"Your Company"
track_opensboolean

Enable open tracking

Default:false
track_clicksboolean

Enable click tracking

Default:false
tagstring

Tag for organizing/filtering this campaign

Example:"newsletter-2025-02"
stream_typestring

Stream type (locked to broadcast for segment sending)

Default:"broadcast"
Value:"broadcast"
account_merge_fieldsobject

Account-level merge fields (same value for all recipients)

Example:
{ "promo_code": "SAVE20", "company_name": "Acme Corp", "unsubscribe_url": "https://example.com/unsubscribe" }
exclude_unengagedboolean

NEW: Exclude unengaged contacts from this campaign

An unengaged contact is one who hasn't opened or clicked ANY email in the last N days (specified by unengaged_days parameter).

Benefits:

  • Improves sender reputation by avoiding inactive contacts
  • Reduces costs by not sending to non-responders
  • Increases campaign engagement metrics (higher open/click rates)

Best Practices:

  • Use 90 days for regular newsletters (recommended)
  • Use 30 days for time-sensitive promotions
  • Use 180+ days for re-engagement campaigns
  • Disable (false) for transactional emails

Example Use Cases:

  • Monthly newsletter → exclude_unengaged: true, unengaged_days: 90
  • Flash sale → exclude_unengaged: true, unengaged_days: 30
  • Win-back campaign → exclude_unengaged: false (send to all)
  • Password reset → exclude_unengaged: false (transactional)
Default:false
Example:true
unengaged_daysinteger

Number of days to look back when determining engagement

Only used if exclude_unengaged is true.

A contact is considered "engaged" if they opened or clicked any email from your account in the last N days.

Recommended values:

  • 30 days: Aggressive filtering, very active users only
  • 60 days: Moderately active users
  • 90 days: Standard (recommended for most campaigns)
  • 180 days: Conservative, includes less frequent engagers
  • 365 days: Very conservative, annual engagement check

Impact on List Size: Typical engagement rates:

  • 30 days: ~40-60% of list (most aggressive)
  • 90 days: ~60-80% of list (balanced)
  • 180 days: ~70-90% of list (conservative)
Default:90
Enum:306090180365
Example:90
curl -i -X POST \
  https://api.mailerlogic.net/api/v1/send-segment \
  -H 'Content-Type: application/json' \
  -H 'X-API-Key: YOUR_API_KEY_HERE' \
  -d '{
    "campaign_id": "monthly-newsletter-2026-march",
    "segment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
    "segment_filters": {
      "match_type": "all",
      "filter_conditions": [
        {
          "property": "status",
          "operator": "equals",
          "value": "subscribed"
        }
      ]
    },
    "subject": "Hello {{first_name}}!",
    "subject_template": "Hello {{first_name}}! Special offer inside",
    "preview_text": "Exclusive offer just for you",
    "html": "<h1>Hi {{name}}</h1><p>Use code {{promo_code}}</p>",
    "text": "Hi {{name}}, Use code {{promo_code}}",
    "from": "hello@mail.yourdomain.com",
    "from_name": "Your Company",
    "track_opens": false,
    "track_clicks": false,
    "tag": "newsletter-2025-02",
    "stream_type": "broadcast",
    "account_merge_fields": {
      "promo_code": "SAVE20",
      "company_name": "Acme Corp",
      "unsubscribe_url": "https://example.com/unsubscribe"
    },
    "exclude_unengaged": true,
    "unengaged_days": 90
  }'

Responses

Segment email queued for processing

Bodyapplication/json
successboolean
Example:true
messagestring
Example:"Segment email queued for delivery"
job_idstring, (uuid)

Background job ID for tracking

Example:"f1e2d3c4-b5a6-7890-cdef-123456789abc"
statusstring
Example:"processing"
Response
{ "success": true, "message": "Segment email queued for delivery", "job_id": "f1e2d3c4-b5a6-7890-cdef-123456789abc", "status": "processing" }