Email campaigns are the workhorse of marketing email. A single message, sent to a defined audience, at a specific time. Simple in concept — but there's more nuance than most developers expect.
What Makes a Good Campaign
A campaign has four components:
- Audience — who receives it (a list, tag, or segment)
- Content — the email itself (subject, HTML body, optional plain text)
- Sending config — which provider and from address to use
- Schedule — when to send (now or a future date/time)
Get all four right and your campaign will land in inboxes. Get any wrong and you're looking at bounces, spam complaints, or worse — an email that nobody opens.
Building Your Audience
Before you send a campaign, you need contacts. PushMail gives you three ways to organize them:
Lists
Lists are explicit groupings. A contact can belong to multiple lists. Common examples: "Newsletter subscribers", "Beta users", "Enterprise leads".
POST /api/v1/lists
{ "name": "Newsletter Subscribers" }
POST /api/v1/contacts/42/lists
{ "listId": 1 }Tags
Tags are lightweight labels. Use them for attributes that cut across lists: "purchased", "attended-webinar", "churned".
POST /api/v1/contacts/42/tags
{ "tag": "purchased" }Segments (coming soon)
Dynamic groups based on contact properties and behavior. "Contacts tagged 'purchased' who opened an email in the last 30 days."
Scheduling and Sending
Campaigns can be sent immediately or scheduled for a future time:
POST /api/v1/campaigns
{
"name": "Product Update",
"subject": "We shipped 3 new features",
"html": "<h1>What's new</h1>...",
"listId": 1,
"sendingConfigId": 1,
"scheduledAt": "2026-03-10T14:00:00Z"
}When scheduledAt is set, the campaign enters scheduled status. The cron worker picks it up at the right time and sends in batches to avoid overwhelming your provider or triggering rate limits.
Batch sending
Large campaigns don't send all at once. PushMail's campaign processor sends in configurable batches with pauses between them. This protects your sender reputation and stays within provider rate limits.
Template Variables
Use {{variable}} syntax in your campaign HTML to personalize content:
<h1>Hey {{first_name}},</h1>
<p>We noticed you signed up on {{created_at}}. Here's what's new since then.</p>Variables are pulled from the contact's properties. Unreplaced variables are automatically removed so you never send {{first_name}} literally.
Conditional content
Show different content based on contact properties:
{{#if plan equals "pro"}}
<p>As a Pro user, you get early access.</p>
{{#else}}
<p>Upgrade to Pro for early access.</p>
{{/if}}Supported operators: equals, not_equals, contains, gt, lt, exists, not_exists.
Tracking and Events
Every email sent through a campaign generates events:
- queued — added to the send queue
- sent — accepted by the provider
- delivered — confirmed delivery to the recipient's server
- opened — recipient opened the email (pixel tracking)
- clicked — recipient clicked a link
- bounced — delivery failed (hard or soft bounce)
- complained — recipient marked as spam
Query events via the API:
GET /api/v1/sends?campaignId=5Deliverability Tips
-
Warm up new sending configs. Don't send 10,000 emails on day one. Start small and ramp up over a week or two. See our email warmup guide.
-
Authenticate your domain. SPF, DKIM, and DMARC are non-negotiable. Our setup guide walks through it.
-
Clean your lists. Remove contacts who haven't engaged in 90+ days. High bounce rates destroy sender reputation.
-
Watch your complaint rate. Stay under 0.1%. PushMail's trust system will warn you — and pause sending if it gets too high.
-
Use a real from address.
noreply@is fine for transactional email, but campaigns should come from an address people recognize.
Common Mistakes
- Sending to purchased lists. Never do this. Purchased lists have high bounce and complaint rates that will get your domain blacklisted.
- No unsubscribe link. Required by law (CAN-SPAM, GDPR). PushMail's suppression system handles this, but make sure you include one.
- Ignoring time zones. Scheduling for 9 AM in your time zone means 3 AM for some recipients. Consider your audience's location.
- Testing in production. Use the test send feature on your dashboard or
POST /api/v1/sendwith your own email first.
Ready to send your first campaign? Head to the campaigns page in your dashboard, or check out the API reference.