Skip to main content

Campaigns

Newsletter

Create, schedule, and send email marketing campaigns with advanced targeting and analytics.

Targeting

Segment your audience

Scheduling

Send at optimal times

A/B Testing

Test subject lines

Analytics

Track engagement

Send a Campaign

Create and send an email campaign:

Basic campaign
import { platform } from '@/lib/platform'

const campaign = await platform.newsletter.sendCampaign({
  subject: 'Exciting News: New Features Released! 🚀',
  html: `
    <h1>What's New</h1>
    <p>We've been busy building amazing features...</p>
    <a href="https://myapp.com/features">Learn More</a>
  `,
  from: 'Product Team <updates@myapp.com>',
})

// campaign.id = 'campaign_abc123'
// campaign.status = 'sending'
// campaign.recipients = 5420
PropertyTypeDescription
subjectstringEmail subject line (required)
htmlstringHTML email content (required)
textstringPlain text fallback
fromstringSender name and email
replyTostringReply-to address
segmentobjectTarget specific subscribers
scheduledAtDateSchedule for later sending
tagsstring[]Tags for organization
trackOpensbooleanTrack email opens (default: true)
trackClicksbooleanTrack link clicks (default: true)

Targeted Campaigns

Send to specific subscriber segments:

// Send to subscribers who opted into product updates
await platform.newsletter.sendCampaign({
  subject: 'New Feature: Dark Mode',
  html: featureHtml,
  segment: {
    preferences: { includes: 'product_updates' },
  },
})

Preview Segment

Use newsletter.countSubscribers() to preview how many recipients match your segment before sending.

Schedule Campaigns

Schedule campaigns to send at the optimal time:

// Schedule for specific time
const campaign = await platform.newsletter.sendCampaign({
  subject: 'Weekly Digest',
  html: digestHtml,
  scheduledAt: new Date('2024-01-20T09:00:00Z'),
})

// campaign.status = 'scheduled'

// Cancel scheduled campaign
await platform.newsletter.cancelCampaign(campaign.id)

// Update scheduled campaign
await platform.newsletter.updateCampaign(campaign.id, {
  subject: 'Updated: Weekly Digest',
  scheduledAt: new Date('2024-01-21T09:00:00Z'),
})

Best Times to Send

Tuesday-Thursday, 9-11am local

Time Zone Aware

Send at 9am in each time zone

A/B Testing

Test different subject lines to optimize opens:

const campaign = await platform.newsletter.sendCampaign({
  // Test multiple subject lines
  subjectVariants: [
    'New Feature Alert! 🚀',
    'You asked, we built it',
    "Here's what's new this month",
  ],
  html: contentHtml,
  abTest: {
    sampleSize: 0.2, // Test on 20% of recipients
    duration: '4h',   // Wait 4 hours for results
    winnerMetric: 'opens', // or 'clicks'
  },
})

// Flow:
// 1. Send variants to 20% of list (split evenly)
// 2. Wait 4 hours, measure open rates
// 3. Automatically send winning variant to remaining 80%

// Get A/B test results
const results = await platform.newsletter.getAbTestResults(campaign.id)
// {
//   variants: [
//     { subject: 'New Feature Alert! 🚀', openRate: 42.5, winner: true },
//     { subject: 'You asked, we built it', openRate: 38.2 },
//     { subject: "Here's what's new", openRate: 35.1 },
//   ],
//   sampleSize: 1000,
//   finalRecipients: 4000,
// }

Campaign Analytics

Track engagement for each campaign:

const stats = await platform.newsletter.getCampaignStats(campaignId)

// {
//   id: 'campaign_abc123',
//   subject: 'New Feature Alert!',
//   status: 'sent',
//   sentAt: '2024-01-15T10:00:00Z',
//   completedAt: '2024-01-15T10:15:00Z',
//
//   // Delivery metrics
//   recipients: 5420,
//   delivered: 5380,
//   bounced: 40,
//
//   // Engagement metrics
//   opened: 2150,
//   uniqueOpens: 1890,
//   clicked: 890,
//   uniqueClicks: 720,
//
//   // Rates
//   deliveryRate: 99.3,
//   openRate: 35.1,
//   clickRate: 13.4,
//   clickToOpenRate: 38.1,
//
//   // Negative events
//   unsubscribed: 12,
//   complained: 2,
//   unsubscribeRate: 0.22,
//   complaintRate: 0.04,
// }

Open Rate

Benchmark: 20-25%

Click Rate

Benchmark: 2-5%

Unsub Rate

Benchmark: < 0.5%

Complaint Rate

Benchmark: < 0.1%

Campaign Status

Campaigns progress through these statuses:

draft

Not yet sent

scheduled

Waiting for send time

sending

Currently sending

sent

Delivery complete

paused

Sending paused

cancelled

Sending cancelled

// Pause a sending campaign
await platform.newsletter.pauseCampaign(campaignId)

// Resume paused campaign
await platform.newsletter.resumeCampaign(campaignId)

// Cancel campaign (can't undo emails already sent)
await platform.newsletter.cancelCampaign(campaignId)

List All Campaigns

Query your campaign history:

// Get recent campaigns
const campaigns = await platform.newsletter.getCampaigns({
  status: 'sent',
  limit: 20,
  orderBy: 'sentAt',
  order: 'desc',
})

// Filter by date range
const januaryCampaigns = await platform.newsletter.getCampaigns({
  sentAfter: '2024-01-01',
  sentBefore: '2024-01-31',
})

// Search by subject
const featureCampaigns = await platform.newsletter.getCampaigns({
  search: 'feature',
})

Templates

Save and reuse campaign templates:

// Create a template
const template = await platform.newsletter.createTemplate({
  name: 'Weekly Digest',
  subject: 'Your Weekly Digest - {{date}}',
  html: weeklyDigestHtml,
  variables: ['date', 'highlights', 'topPosts'],
})

// Send using template
await platform.newsletter.sendCampaign({
  templateId: template.id,
  variables: {
    date: 'January 15, 2024',
    highlights: highlightsList,
    topPosts: topPostsList,
  },
})

Best Practices

Test Before Sending

Send test emails to yourself first

Segment Your Audience

Relevant content = higher engagement

Optimize Send Time

Test different times for your audience

Monitor Complaints

High rates hurt deliverability