How to Send Marketing Emails (Without Getting Blacklisted)
A developer's guide to sending marketing emails that reach the inbox. Covers list management, warmup, throttling, unsubscribe handling, and compliance — with code examples.
Marketing emails are different from transactional ones. Transactional emails (password resets, order confirmations) are triggered by user actions. Marketing emails (newsletters, product updates, promotions) are sent proactively — and they come with stricter rules, higher spam risk, and more compliance requirements.
This guide covers how to send marketing emails that actually reach the inbox, from list management to domain setup to unsubscribe handling.
The rules:
- Only email people who opted in (double opt-in is best)
- Separate marketing and transactional email on different subdomains
- Warm up your sending domain before going to full volume
- Include a visible unsubscribe link in every email
- Monitor bounce rate (<2%) and complaint rate (<0.1%)
Set Up Your Sending Infrastructure
Use a separate subdomain
Send marketing email from a dedicated subdomain like news.yourdomain.com or updates.yourdomain.com. Keep transactional email on a different subdomain.
| Type | Subdomain | Example |
|---|---|---|
| Transactional | mail.yourdomain.com | Password resets, receipts |
| Marketing | news.yourdomain.com | Newsletters, announcements |
Why? Reputation isolation. If your marketing emails get spam complaints, your transactional emails keep delivering normally.
Authenticate your subdomain
Set up SPF, DKIM, and DMARC on your marketing subdomain. Without these, inbox providers will filter your emails regardless of content.
# SPF
news.yourdomain.com TXT "v=spf1 include:sendpigeon.com ~all"
# DKIM (your provider gives you the exact record)
sp._domainkey.news.yourdomain.com CNAME ...
# DMARC
_dmarc.news.yourdomain.com TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com"
See our DKIM, SPF, and DMARC setup guide for step-by-step instructions.
Warm up the subdomain
New subdomains have no reputation. Start small and ramp up:
| Period | Daily volume | Notes |
|---|---|---|
| Days 1-3 | 50-100 | Send to your most engaged users |
| Days 4-7 | 200-500 | Monitor open rates and complaints |
| Week 2 | 500-1,000 | Check Google Postmaster Tools |
| Week 3 | 1,000-5,000 | Continue monitoring |
| Week 4+ | Full volume | Maintain consistent sending |
For a detailed schedule, see How to Warm Up an Email Domain.
Build Your Email List the Right Way
Use double opt-in
Double opt-in means the user signs up, receives a confirmation email, and clicks a link to confirm. This ensures:
- The email address is real (reduces bounces)
- The person actually wants your emails (reduces complaints)
- You have proof of consent (GDPR compliance)
import { SendPigeon } from "sendpigeon";
const pigeon = new SendPigeon(process.env.SENDPIGEON_API_KEY!);
async function sendConfirmation(email: string, token: string) {
await pigeon.send({
from: "news@yourdomain.com",
to: email,
subject: "Confirm your subscription",
html: `
<h1>Confirm your email</h1>
<p>Click below to subscribe to our newsletter:</p>
<a href="https://yourdomain.com/confirm?token=${token}">
Confirm subscription
</a>
<p>If you didn't sign up, ignore this email.</p>
`,
});
}
Never buy email lists
Purchased lists contain spam traps, invalid addresses, and people who never opted in. Sending to them will destroy your sender reputation.
Clean your list regularly
Remove addresses that:
- Hard bounced (invalid address) — remove immediately
- Soft bounced 3+ times — remove after investigation
- Haven't opened in 6+ months — send a re-engagement email, then remove if no response
- Complained (marked as spam) — remove immediately, never re-add
Handle Unsubscribes Properly
Include List-Unsubscribe headers
Gmail, Outlook, and Yahoo show an unsubscribe button when this header is present:
List-Unsubscribe: <https://yourdomain.com/unsubscribe?id=abc123>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
The List-Unsubscribe-Post header enables one-click unsubscribe — Gmail requires this for bulk senders.
Visible unsubscribe link
Every marketing email must include a visible unsubscribe link. Place it in the footer — don't hide it or make it hard to find. Making it easy to unsubscribe reduces spam complaints, which is better for your reputation than trapping people on your list.
Process unsubscribes instantly
app.post("/unsubscribe", async (req, res) => {
const { email } = req.body;
// Add to suppression list immediately
await db.suppressions.create({
data: { email, reason: "unsubscribe", createdAt: new Date() },
});
// Remove from active subscribers
await db.subscribers.update({
where: { email },
data: { status: "unsubscribed" },
});
res.json({ success: true });
});
Check your suppression list before every send. Never email an unsubscribed address.
Send Marketing Emails with Throttling
Don't send 50,000 emails at once. Throttle your sends to avoid triggering spam filters.
import { SendPigeon } from "sendpigeon";
const pigeon = new SendPigeon(process.env.SENDPIGEON_API_KEY!);
async function sendNewsletter(
subscribers: { email: string; name: string }[],
subject: string,
html: string,
) {
const batchSize = 100;
const delayMs = 1000; // 1 second between batches
for (let i = 0; i < subscribers.length; i += batchSize) {
const batch = subscribers.slice(i, i + batchSize);
await pigeon.sendBatch(
batch.map((sub) => ({
from: "news@yourdomain.com",
to: sub.email,
subject,
html: html.replace("{{name}}", sub.name),
})),
);
// Throttle between batches
if (i + batchSize < subscribers.length) {
await new Promise((r) => setTimeout(r, delayMs));
}
}
}
SendPigeon handles rate limiting on its end, so you don't strictly need client-side throttling. But spacing out large sends is still good practice — it avoids overwhelming your own infrastructure and gives you time to catch issues early.
Compliance Requirements
CAN-SPAM (United States)
- Include your physical mailing address
- Include a clear unsubscribe mechanism
- Honor unsubscribe requests within 10 business days
- Don't use misleading subject lines or headers
- Identify the message as an ad
GDPR (European Union)
- Explicit opt-in required before sending (no pre-checked boxes)
- Double opt-in is strongly recommended
- Record proof of consent (when, how, what they agreed to)
- Process data deletion requests (right to be forgotten)
- Include your privacy policy link
Both
- Never send to people who didn't sign up
- Never send to people who unsubscribed
- Keep records of consent
Monitor Your Metrics
| Metric | Target | What to do if exceeded |
|---|---|---|
| Bounce rate | <2% | Clean your list, remove invalid addresses |
| Complaint rate | <0.1% | Improve opt-in, check content, reduce frequency |
| Open rate | >20% | Improve subject lines, send to engaged users |
| Unsubscribe rate | <0.5% per send | Reduce frequency, improve content relevance |
Google Postmaster Tools (free) shows your domain reputation with Gmail. If it drops to "Low" or "Bad", reduce volume and clean your list before continuing.
Marketing vs Transactional: Quick Reference
| Transactional | Marketing | |
|---|---|---|
| Trigger | User action | You decide when |
| Examples | Password reset, receipt | Newsletter, promotion |
| Opt-in required? | No (implied by action) | Yes (explicit consent) |
| Unsubscribe link? | Optional | Required |
| CAN-SPAM applies? | Partially | Fully |
| Send from | mail.yourdomain.com | news.yourdomain.com |
| Volume | As needed | Controlled schedule |
For a deeper comparison, see Transactional vs Marketing Email.
FAQ
What is the difference between transactional and marketing email?
Transactional emails are triggered by user actions (password resets, order confirmations). Marketing emails are sent proactively (newsletters, promotions). Marketing emails require explicit opt-in and must include an unsubscribe link.
Do I need permission to send marketing emails?
Yes. CAN-SPAM requires a way to opt out. GDPR requires explicit opt-in before sending. Always use double opt-in — it reduces bounces, complaints, and gives you proof of consent.
How many marketing emails can I send per day?
It depends on your domain age and reputation. New domains should start with 50-100/day and ramp up over 4 weeks. See the warmup schedule above.
Should I separate marketing and transactional email?
Yes. Use different subdomains so reputation problems with marketing email don't affect your transactional delivery.
How do I avoid the spam folder?
Authenticate your domain (SPF, DKIM, DMARC), only email opted-in users, warm up new domains, include a clear unsubscribe link, keep bounce rate below 2%, and monitor complaints.
What should I do when someone unsubscribes?
Stop emailing them immediately. Add them to a suppression list. Never re-add unsubscribed addresses — this violates CAN-SPAM and GDPR.
Next Steps
- Set up email authentication on your marketing subdomain
- Warm up your domain before sending at volume
- Review the email deliverability checklist
- Read why emails go to spam if you're having deliverability issues
- See Introducing Broadcasts for SendPigeon's marketing email features