Back to blog
EmailMarketingDeliverabilityDeveloper Guide

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.

SendPigeon TeamMarch 27, 20267 min read

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.

TL;DR

The rules:

  1. Only email people who opted in (double opt-in is best)
  2. Separate marketing and transactional email on different subdomains
  3. Warm up your sending domain before going to full volume
  4. Include a visible unsubscribe link in every email
  5. 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.

TypeSubdomainExample
Transactionalmail.yourdomain.comPassword resets, receipts
Marketingnews.yourdomain.comNewsletters, 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:

PeriodDaily volumeNotes
Days 1-350-100Send to your most engaged users
Days 4-7200-500Monitor open rates and complaints
Week 2500-1,000Check Google Postmaster Tools
Week 31,000-5,000Continue monitoring
Week 4+Full volumeMaintain 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

MetricTargetWhat 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 sendReduce 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

TransactionalMarketing
TriggerUser actionYou decide when
ExamplesPassword reset, receiptNewsletter, promotion
Opt-in required?No (implied by action)Yes (explicit consent)
Unsubscribe link?OptionalRequired
CAN-SPAM applies?PartiallyFully
Send frommail.yourdomain.comnews.yourdomain.com
VolumeAs neededControlled 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