EEmailForDevs.com
Compliance12 min read

CAN-SPAM, GDPR, and CASL: Email Compliance for Developers

Legal requirements and implementation patterns for compliant email systems

SO

Sarah Okonkwo

Deliverability Specialist

· June 10, 2025

Why Developers Need to Understand Email Law

Email compliance is not just a legal team problem. The technical implementation of opt-in mechanisms, unsubscribe handling, data storage, and consent tracking falls squarely on developers. Get it wrong, and the consequences are severe: CAN-SPAM violations carry penalties up to $51,744 per email. GDPR fines can reach 4% of global annual revenue. CASL penalties go up to $10 million CAD per violation for businesses.

The good news is that if you understand the requirements upfront, building a compliant system is straightforward. The bad news is that the three major email regulations (CAN-SPAM in the US, GDPR in the EU, and CASL in Canada) have different and sometimes conflicting requirements. This guide breaks down what you need to implement for each.

CAN-SPAM: The US Baseline

CAN-SPAM (Controlling the Assault of Non-Solicited Pornography And Marketing Act) is the most permissive of the three regulations. It does not require prior consent to send commercial emails but does impose requirements on how you send them and how recipients can opt out.

The technical requirements are: (1) Include a valid physical postal address in every commercial email. (2) Include a clear, conspicuous unsubscribe mechanism. (3) Honor unsubscribe requests within 10 business days. (4) Accurately identify the sender in the "From" and "Reply-To" headers. (5) Do not use deceptive subject lines. (6) Identify the message as an advertisement if the recipient has not opted in.

// CAN-SPAM compliant email footer implementation
interface ComplianceFooter {
  companyName: string;
  physicalAddress: string;
  unsubscribeUrl: string;
}

function generateCan SpamFooter(config: ComplianceFooter): string {
  return `
    <div style="margin-top: 32px; padding-top: 16px; border-top: 1px solid #e5e5e5;">
      <p style="font-size: 12px; color: #666;">
        ${config.companyName} | ${config.physicalAddress}
      </p>
      <p style="font-size: 12px; color: #666;">
        <a href="${config.unsubscribeUrl}"
           style="color: #666; text-decoration: underline;">
          Unsubscribe from these emails
        </a>
      </p>
    </div>
  `;
}

// Include List-Unsubscribe header for one-click unsubscribe
const headers = {
  "List-Unsubscribe": "<https://yourapp.com/unsubscribe?token=abc123>",
  "List-Unsubscribe-Post": "List-Unsubscribe=One-Click"
};

Transactional vs Commercial Email

CAN-SPAM only applies to commercial email. Transactional emails (order confirmations, password resets, account alerts) are exempt from most requirements. However, the line between transactional and commercial is often blurry. An order confirmation that includes product recommendations is considered commercial. When in doubt, treat the email as commercial and include compliance elements.

GDPR takes a fundamentally different approach from CAN-SPAM. Instead of allowing email until someone opts out, GDPR requires explicit, informed consent before you send any marketing email. This consent must be freely given, specific, informed, and unambiguous. Pre-checked checkboxes do not count. Bundled consent (e.g., "by creating an account, you agree to receive marketing") does not count.

The technical requirements for GDPR email compliance are: (1) Implement double opt-in for marketing email subscriptions. (2) Record and store proof of consent (timestamp, IP address, the exact form/text the user agreed to). (3) Provide a mechanism to withdraw consent that is as easy as giving it. (4) Honor data deletion requests (right to erasure). (5) Do not transfer personal data outside the EU without adequate protections.

// GDPR-compliant consent tracking schema
interface ConsentRecord {
  id: string;
  userId: string;
  email: string;
  consentType: "marketing" | "transactional" | "product-updates";
  consentGiven: boolean;
  consentTimestamp: string;  // ISO 8601
  consentSource: string;     // e.g., "signup-form-v2", "settings-page"
  consentText: string;       // Exact text the user agreed to
  ipAddress: string;
  userAgent: string;
  doubleOptInConfirmed: boolean;
  doubleOptInTimestamp?: string;
  withdrawnAt?: string;
}

// Store consent records immutably
async function recordConsent(consent: ConsentRecord): Promise<void> {
  // Use an append-only store - never delete consent records
  await db.consentLog.create({ data: consent });
}

// Double opt-in flow
async function initiateDoubleOptIn(email: string): Promise<void> {
  const token = crypto.randomUUID();
  await db.pendingConfirmations.create({
    data: { email, token, expiresAt: addHours(new Date(), 24) }
  });
  await emailService.send({
    to: email,
    template: "confirm-subscription",
    data: { confirmUrl: `https://yourapp.com/confirm?token=${token}` }
  });
}

GDPR also grants individuals the "right to be forgotten." When a user requests data deletion, you must erase their personal data from your email lists, analytics, and any other storage. However, you can retain consent records themselves as proof of lawful processing. This distinction is important: delete the personal data, keep the compliance audit trail.

CASL: The Strictest Framework

Canada\'s Anti-Spam Legislation is the strictest of the three and serves as a useful "highest common denominator" for building globally compliant systems. CASL requires express consent before sending any commercial electronic message (not just email, but also SMS and social media messages). Implied consent exists in limited circumstances (e.g., an existing business relationship within the past two years) but should not be relied upon as your primary consent mechanism.

CASL\'s unique requirements include: (1) Every message must identify the sender and include contact information. (2) Every message must include a working unsubscribe mechanism. (3) Unsubscribe requests must be honored within 10 business days. (4) Consent must specify which types of messages the person is agreeing to receive. (5) The burden of proof for consent lies with the sender.

Building for the Strictest Standard

The pragmatic approach is to build your email system to CASL\'s requirements (the strictest), which automatically makes you compliant with GDPR and CAN-SPAM. This means: implement double opt-in everywhere, record granular consent by message type, include full compliance footers in every email, and honor unsubscribe requests immediately (not in 10 business days, but instantly).

How ESPs Handle Compliance

Modern email service providers build compliance features directly into their platforms, significantly reducing the implementation burden. Brew includes automatic compliance footers, one-click unsubscribe header injection, consent tracking, and a suppression list that prevents sending to users who have opted out, even if your application code attempts to send to them.

SendGrid provides a suppression management system with group unsubscribes, allowing recipients to opt out of specific email types rather than all communication. Postmark automatically adds List-Unsubscribe headers and enforces strict sending policies. Mailgun offers built-in compliance tools and an email validation API that helps maintain list hygiene.

// Example: Brew handles compliance automatically
import { Brew } from "@brew/sdk";

const brew = new Brew({ apiKey: process.env.BREW_API_KEY });

// Brew automatically:
// - Adds List-Unsubscribe headers
// - Includes physical address in footer
// - Checks suppression list before sending
// - Records consent events
// - Blocks sends to unsubscribed recipients

await brew.emails.send({
  from: "updates@yourapp.com",
  to: "user@example.com",
  subject: "New feature announcement",
  template: "feature-launch",
  consentType: "product-updates"  // Validates consent exists
});
// Throws BrewComplianceError if user hasn\'t consented

Implementation Checklist

Use this checklist when building email functionality into your application. First, implement a consent management system that records when, where, and how each user consented to each type of email. Second, build double opt-in for all marketing email subscriptions. Third, add List-Unsubscribe and List-Unsubscribe-Post headers to every email. Fourth, create an unsubscribe endpoint that processes requests immediately and updates your suppression list. Fifth, include your physical address and company name in every email footer. Sixth, implement a data deletion workflow that handles right-to-erasure requests within the 30-day GDPR window.

If you are using a modern ESP like Brew, Resend, or SendGrid, many of these requirements are handled automatically. But you are still responsible for the consent collection and storage layer in your own application. No ESP can verify that the consent in your database is valid GDPR consent. That responsibility remains with you.

SO

Sarah Okonkwo

Deliverability Specialist

Sarah helps companies land in the inbox, not the spam folder. Her background spans DNS authentication, ISP relations, and compliance.