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:
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| Property | Type | Description |
|---|---|---|
subject | string | Email subject line (required) |
html | string | HTML email content (required) |
text | string | Plain text fallback |
from | string | Sender name and email |
replyTo | string | Reply-to address |
segment | object | Target specific subscribers |
scheduledAt | Date | Schedule for later sending |
tags | string[] | Tags for organization |
trackOpens | boolean | Track email opens (default: true) |
trackClicks | boolean | Track 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
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%
Link Click Tracking
See which links get the most clicks:
const linkStats = await platform.newsletter.getLinkStats(campaignId)
// [
// { url: 'https://myapp.com/features', clicks: 450, uniqueClicks: 380 },
// { url: 'https://myapp.com/pricing', clicks: 220, uniqueClicks: 195 },
// { url: 'https://myapp.com/docs', clicks: 180, uniqueClicks: 150 },
// ]
// UTM parameters are automatically added:
// https://myapp.com/features?utm_source=newsletter&utm_campaign=new-featuresCampaign Status
Campaigns progress through these statuses:
draftNot yet sent
scheduledWaiting for send time
sendingCurrently sending
sentDelivery complete
pausedSending paused
cancelledSending 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