ESP: SendGrid8 min read

SendGrid transactional emails need seed testing, not just marketing

Password resets, receipts, and 2FA codes are the most reputation-critical emails your product sends. Seed testing them is rare. It should not be.

Most deliverability writing focuses on marketing email: newsletters, drip campaigns, product launches. That makes sense — marketing sends are large, rate-limited, and the blast radius of bad placement is huge. So everyone talks about seeding marketing campaigns.

Transactional email gets less attention even though the consequences of failure are worse. If a password reset lands in Spam, the user cannot log in. They file a support ticket, they complain on social, some of them bounce to a competitor. If a 2FA code is delayed 10 minutes, that is an account lockout. If a receipt goes missing, that is a chargeback waiting to happen.

SendGrid is a leading transactional ESP, and its own documentation is clear about warmup, DKIM, and suppression lists. What its documentation is quieter on is folder placement. A 202 response from the SendGrid API means “accepted for delivery,” which is useful but not the same as “landed in Primary.” You need seeds.

Transactional versus marketing in SendGrid

SendGrid separates traffic by use case. Transactional is API-driven mail tied to a user action (sign-up, reset, receipt, alert). Marketing is Marketing Campaigns UI sends to lists. They route differently, apply different spam scrubbing, and report differently.

Two differences make transactional riskier for missed placement:

  • The recipient expects it within seconds. A password reset that takes 2 hours because it is in spam is a broken product, not a slow email.
  • Complaints are invisible. Users do not click “spam” on a reset email. They just fail to receive it and rage at support.

The absence of a complaint signal is particularly tricky. Your SendGrid dashboard shows low complaint rate on transactional, which looks healthy. Meanwhile 5 percent of resets are landing in Promotions at Gmail and nobody knows.

The case for seeding every transactional template

Transactional email is template-driven. You have a small, stable set: signup, reset, 2FA, receipt, shipping update, account alert. Each template is a named object in SendGrid Dynamic Templates. That is a much more tractable surface to seed than a marketing campaign that changes every week.

A practical pattern: for every critical transactional template, add a set of seed recipients as permanent BCCs. When a real user triggers the reset, your seeds receive the same email. You can then open each seed mailbox to confirm placement.

Adding seeds via the SendGrid v3 API

The personalizations array in SendGrid v3 supports per-recipient to, cc, and bcc. The cleanest integration is to add your seed list as BCC on the same personalization as the end user. The user does not see the BCC, but every seed receives the exact same message the user did, with identical headers and content.

curl -X POST https://api.sendgrid.com/v3/mail/send \
  -H "Authorization: Bearer $SENDGRID_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "personalizations": [{
      "to": [{ "email": "user@example.com" }],
      "bcc": [
        { "email": "seed-gmail@your-seed-domain.test" },
        { "email": "seed-outlook@your-seed-domain.test" },
        { "email": "seed-yahoo@your-seed-domain.test" }
      ],
      "dynamic_template_data": {
        "reset_url": "https://app.example.com/reset?token=abc123"
      }
    }],
    "from": { "email": "no-reply@example.com", "name": "Example App" },
    "template_id": "d-abc123reset-template-id"
  }'

In a real codebase you would not hardcode this. Your mail-sending helper would decide whether to include seeds based on an environment flag, a sampling rate (e.g., 1 percent of resets), or on the template ID (always on for reset, never on for newsletter).

Sampling, not BCCing every send

You do not want every password reset BCCed to your entire seed panel forever. That is a lot of mail to seed mailboxes and will train filters on the pattern. Sample instead: 1 percent of resets to the seed panel, 100 percent on a fixed schedule (e.g., every 5th minute), or triggered by a synthetic user hitting the reset endpoint once per hour.

Synthetic transactional tests as an alternative

If BCCing real user traffic is uncomfortable (privacy, dynamic content), run synthetic tests instead. Create a cron job that hits your own reset endpoint every 15 minutes with a seed address as the recipient. The seed receives a real password reset email, generated by your real code, through your real SendGrid account.

Advantages of synthetic tests:

  • No BCCing of real user mail — privacy stays clean.
  • Placement is checked on a predictable schedule, so you can alert on regressions.
  • The test covers the full path — your web app, your SendGrid call, your template — not just the send.
Get 20+ seed addresses free

The free Inbox Check tool generates 20+ fresh seed addresses per test across Gmail, Outlook, Yahoo, Mail.ru, Yandex, ProtonMail and more. No signup, no credit card.

→ Run a free test now

What to watch for on transactional seeds

Transactional placement has patterns that differ from marketing:

  • Gmail Primary vs Promotions. A reset should always land Primary. If it lands Promotions, that is a template issue: too much layout, too many links, a marketing-looking footer. Strip it.
  • Outlook Junk. Microsoft is sensitive to mismatches between From-name and From-address. If your reset says “From: Example App” but the address is team@different-domain.com, Junk is likely.
  • Delayed delivery at Yahoo. Yahoo throttles unknown senders. A 5 to 10 minute delay on reset is a real user-facing bug. Seeds catch this.
  • Greylisting at corporate Microsoft 365. Many corporate tenants greylist on first send. Your seed at a corporate tenant will show this as a 5-minute delay on first message then fine after.

Segregate marketing and transactional IPs

SendGrid supports dedicated IPs and IP pools. The single highest-leverage deliverability decision you will make for a product that sends both marketing and transactional is to separate them onto different IPs. A marketing campaign gone wrong should not take down your password reset flow.

Seed your transactional IP pool independently. If the marketing pool shows Promotions placement after a bad send, you want to confirm that the transactional pool is still landing Primary — and seeds on both pools are how you confirm it.

FAQ

Is 202 from the SendGrid API enough to know the email was delivered?

No. 202 means SendGrid accepted the message for delivery. It does not mean the receiving provider accepted it, and it definitely does not mean the email landed in the Inbox. Dashboard delivery rate tells you SMTP delivery; seeds tell you folder placement.

Should I BCC seeds on every transactional email or sample?

Sample. BCCing 100 percent of password resets for months trains filters on the pattern and increases mail volume to the seeds unnaturally. One percent sampling, or synthetic hourly tests, give you the same signal with much less noise.

Does SendGrid have a native inbox placement feature?

Yes, SendGrid offers Inbox Placement through the enterprise plan. It is useful but gated behind upper tiers. A free seed-testing tool gives you the same per-provider signal without the subscription.

What about 2FA codes — those need to arrive in seconds?

2FA is the extreme case. Delay kills the user flow. Seed 2FA templates on a 5-minute synthetic schedule and alert on delay over 30 seconds or on non-inbox placement. Treat this as a production SLO, not a nice-to-have.
Related reading

Check your deliverability across 20+ providers

Gmail, Outlook, Yahoo, Mail.ru, Yandex, GMX, ProtonMail and more. Real inbox screenshots, SPF/DKIM/DMARC, spam engine verdicts. Free, no signup.

Run Free Test →

Unlimited tests · 20+ seed mailboxes · Live results · No account required