Email Marketing skill for Codex

Lifecycle email that lands in the inbox. Codex designs email programs around events and exit conditions instead of calendar blasts, splits transactional and marketing streams, and checks SPF, DKIM, DMARC alignment and one-click unsubscribe against the Gmail, Yahoo and Outlook bulk sender rules. It measures flows with clicks and holdout groups because opens are inflated, and it will not activate a send or change DNS without your confirmation.

  • Growth & SEO
  • $email-marketing
  • 181 lines
  • 2 files
  • ~2,050 tokens
  • MIT
  • Updated

Install

curl -fsSL codexskills.dev/install.sh \  | sh -s -- email-marketing

Installs to ~/.agents/skills/email-marketing/ for every project on this machine.

104-line POSIX script. No sudo, no telemetry. Read install.sh

Use it in Codex

Start a prompt with $email-marketing, or pick it from /skills. You can also just describe the task: Codex reads the description below and loads the playbook when your request matches.

What Codex reads before loading it

Plans and builds lifecycle and marketing email programs - welcome, onboarding, activation, trial conversion, win-back and broadcast campaigns - with event-based triggers, segmentation, suppression rules and deliverability set up correctly (SPF, DKIM, DMARC alignment, one-click unsubscribe, Gmail and Yahoo bulk sender rules). Works in Customer.io, Braze, Klaviyo, Loops, Resend, Postmark or SendGrid. Use when asked to design an onboarding sequence, fix emails landing in spam, segment a list, set up DMARC, or measure email performance.

Use it when

  • You need welcome, onboarding, trial or win-back flows mapped to product events
  • Emails land in spam or Postmaster Tools shows rising complaint rates
  • A list needs behavioural segments and suppression rules before a campaign
  • You must meet Gmail and Yahoo bulk sender requirements

Use something else when

How to check the result

A test send shows SPF, DKIM and DMARC PASS for your domain in Gmail's Show original, and each flow's goal conversion beats its holdout group.

The mistake it prevents

Judging flows by open rate, which Apple Mail Privacy Protection inflates, and sending marketing mail from the same domain as password resets.

~/.agents/skills/email-marketing/SKILL.md

--- name: email-marketing description: Plans and builds lifecycle and marketing email programs - welcome, onboarding, activation, trial conversion, win-back and broadcast campaigns - with… license: MIT ---

A lifecycle program is done well when each email is triggered by something the user did (or did not do), goes only to people who consented and are not suppressed, authenticates with aligned SPF/DKIM/DMARC, and is judged by clicks and downstream conversions rather than opens.

Inspect before building

  1. Read AGENTS.md; find the ESP and how email is sent today: rg -n "resend|postmark|sendgrid|@sendgrid|mailgun|customerio|braze|klaviyo|loops|nodemailer|ses" -g '!node_modules'.
  2. Separate the two streams: transactional (receipts, password resets, security) and marketing/lifecycle. Send them from different subdomains or at least separate streams/IP pools so a marketing complaint spike cannot delay password resets.
  3. Check the sending domain’s DNS (needs network):
dig +short TXT example.com | grep -i spf
dig +short TXT _dmarc.example.com
dig +short TXT <selector>._domainkey.mail.example.com   # selector from the ESP's setup page
  1. Find where consent is stored (signup form checkbox, marketing_opt_in column) and where unsubscribes and bounces are recorded. If there is no consent record, stop and raise it before sending any marketing email.

Deliverability baseline (non-negotiable)

Since 2024, Gmail and Yahoo require this for anyone sending around 5,000+ messages a day to their users, and Microsoft Outlook.com applies similar rules from May 2025. Treat it as required for every sender.

RequirementDetail
SPFv=spf1 include:<esp> ~all; stay under 10 DNS lookups
DKIM2048-bit key published by the ESP, signing with your domain (not the ESP’s)
DMARCAt least p=none with rua= reporting; From domain must align with SPF or DKIM domain
One-click unsubscribeList-Unsubscribe with an HTTPS URL plus List-Unsubscribe-Post: List-Unsubscribe=One-Click (RFC 8058); honour within 2 days
Spam complaint rateKeep under 0.1% in Google Postmaster Tools; never reach 0.3%
Valid forward and reverse DNS for sending IPsUsually handled by the ESP

DMARC rollout: p=none with reports for 2-4 weeks, fix every legitimate source that fails alignment, then p=quarantine; pct=25 and step up to p=reject. Changing DNS on a production domain is an outward-facing change; show the exact record and get the user’s confirmation before applying it.

_dmarc.example.com.  TXT  "v=DMARC1; p=none; rua=mailto:[email protected]; adkim=r; aspf=r"

Program design

Map lifecycle emails to the user journey and to one behavioural goal each:

StageTriggerGoal metricExit condition
Welcomeuser_signed_upFirst key action within 24 hKey action done
Onboarding / activationSignup + missing setup event after N hoursActivation eventActivated
Trial conversiontrial_started, 3-5 days before trial endPaid conversionSubscribed
Feature adoptionActive user who never used feature XFeature usedUsed X
Re-engagementNo login for 30 daysReturn sessionLogged in
Win-backSubscription cancelled 30-60 days agoReactivationResubscribed, or 2 sends
SunsetNo opens or clicks for 90-180 daysList hygieneSuppress

Rules for every flow:

  • Every flow has an exit condition; nobody gets “set up your account” after setting it up.
  • Frequency cap across flows (e.g. max 1 lifecycle email per day, 4 per week).
  • Quiet hours by recipient time zone if the ESP supports it.
  • Broadcasts exclude users currently in a high-intent flow (trial ending) when the broadcast would compete.

Segmentation

Segment on behaviour and lifecycle stage first, demographics second.

-- Example: activated in the last 30 days, never used integrations, consented, not suppressed
SELECT u.id, u.email
FROM users u
WHERE u.marketing_opt_in = true
  AND u.email_status = 'deliverable'
  AND u.activated_at >= now() - interval '30 days'
  AND NOT EXISTS (SELECT 1 FROM events e WHERE e.user_id = u.id AND e.name = 'integration_connected')
  AND NOT EXISTS (SELECT 1 FROM suppressions s WHERE s.email = u.email);

Send events to the ESP with stable names and properties (trial_started { plan, trial_end_at }) rather than syncing computed segments nightly; real-time triggers convert better and stay correct.

Writing each email

  • One goal, one primary link or button. Secondary links are fine; competing CTAs are not.
  • Subject line states the value or the action; 30-50 characters reads fully on mobile. Preheader extends the subject, it does not repeat it.
  • Plain, short body; personal sender name for lifecycle (Maya at Acme) where the brand allows.
  • Personalisation tokens always have fallbacks: {{ first_name | default: "there" }} (Liquid) or the ESP’s equivalent.
  • Accessible: real text not images of text, alt text on images, 14px+ body, sufficient contrast, a plain-text part. HTML build and client rendering belong to email-template-design.
  • Footer: physical postal address and unsubscribe link (CAN-SPAM), plus preference centre if you have one.

Measurement

  • Apple Mail Privacy Protection preloads images, so open rates are inflated and unreliable. Use clicks, click-to-conversion and the goal metric per flow.
  • Measure flows against a holdout group (5-10% of eligible users who receive nothing) to know whether the flow causes the behaviour or just coincides with it.
  • Track per send: delivered, bounce rate (hard bounces under 2%), complaint rate, unsubscribe rate, click rate, goal conversion.
  • Tag links with UTMs consistently (utm_medium=email, utm_campaign=<flow-slug>); conventions in utm-attribution.
  • US CAN-SPAM: no deceptive headers or subjects, physical address, opt-out honoured within 10 business days.
  • EU/UK (GDPR, ePrivacy/PECR): marketing to individuals generally needs prior opt-in consent; soft opt-in for existing customers about similar products in the UK. Keep a record of when and how consent was given.
  • Canada CASL: express or implied consent with strict expiry; identification and unsubscribe in every message.

When the program spans jurisdictions or uses purchased data, the user’s lawyer must review. Never send to purchased or scraped lists from the marketing domain.

Sending safely

Any real send (broadcast, flow activation, bulk re-import of subscribers) reaches people and cannot be recalled. Before activating:

- [ ] Recipient count matches the expected segment size (sanity check vs. total list)
- [ ] Suppression list and unsubscribes applied
- [ ] Test sends to seed inboxes (Gmail, Outlook, Apple Mail) look right, links work
- [ ] UTM tags and tracking present
- [ ] User explicitly confirmed the send or activation

Warm a new domain or IP gradually: start with the most engaged recipients and increase daily volume over 2-4 weeks while watching complaint and bounce rates.

Gotchas

  • Marketing email sent from the root domain with a bad reputation drags down password resets on the same domain. Split subdomains (mail. for marketing, notify. for product).
  • List-Unsubscribe added by hand in templates but the ESP rewrites headers; verify in the raw message source (Gmail “Show original”).
  • DMARC p=reject before fixing all senders (CRM, support desk, invoicing tool) silently drops their mail.
  • Re-engagement emails to long-dead addresses hit spam traps; sunset instead of reviving.
  • Double-sends from overlapping flows; check entry criteria and caps across all flows.

Verification

  • Gmail “Show original” on a test send shows SPF: PASS, DKIM: PASS, DMARC: PASS with your domain.
  • One-click unsubscribe works from the Gmail UI link and records suppression.
  • Google Postmaster Tools spam rate below 0.1% one week after launch.
  • Flow goal conversion beats the holdout group.

Output template

## Email program: <name>
**Streams:** transactional via <ESP/subdomain>, marketing via <ESP/subdomain>
**Auth:** SPF ok / DKIM ok (selector) / DMARC p=<policy>, aligned
| Flow | Trigger | Emails (timing) | Goal | Exit | Holdout |
**Segments:** <definitions>
**Open items needing approval:** DNS changes, first send, legal review

What the zip contains

SKILL.md plus the interface file below. Nothing runs on install.

agents/openai.yamlgenerated from this page

Gives the Codex app a display name, a one-line description and a starter prompt for this skill.

interface:
  display_name: "Email Marketing"
  short_description: "Lifecycle email that lands in the inbox"
  default_prompt: "$email-marketing Design an onboarding email sequence for new trial users based on our product events"

About this skill

Written and maintained by the Codex Skills editors to the same editorial standard as every skill here: a selective description, a real workflow, known pitfalls and a way to verify the work. First published , last updated . MIT licensed. Something wrong or out of date? Tell us.

esc
Just launched

Codex Skills Pro is live

79 premium skills for Codex, each with scripts, references and an evidence report that proves the result.

Bought one by one$882.21
All 79 skills$49
94% off

That's $0.62 a skill, paid once.

Get all 79 for $49Or pick single skills from $4.99 →

Secure checkout by Creem