Email Broadcasts
Setup (one time)
Fill in references/config.md (brand, from/reply-to, physical address for CAN-SPAM, audience
- test segment IDs, test recipients). Set:
export RESEND_API_KEY="your-key" # free key at https://resend.com
Manage contacts in your Resend Audience (import a CSV, or sync from your own source). This
skill treats the Resend audience as the source of truth — no specific backend is assumed.
Routing — what does the user want?
| User says |
Route to |
| "send/draft a broadcast", "announce", "newsletter" |
→ Draft & Send workflow |
| "how many contacts/subscribers" |
→ Resend: list contacts / audience count |
| "what have we sent", "email history" |
→ History |
| "open rate", "stats" |
→ Resend: list/get broadcast |
| "how does unsubscribe / CAN-SPAM work" |
→ Knowledge lookup (below) |
Draft & Send Workflow
Phase 1 — Prepare
- Confirm the audience + count (Resend
list-contacts / audience).
- Ask: purpose (product update, announcement, review request, custom)? What to highlight? CTA?
Phase 2 — Draft
Compose the email (HTML + plain text). Proven structure:
Short, warm intro (2-3 sentences)
WHAT'S NEW — section header + one card per item
A SMALL ASK — the CTA + a short line of context
Sign-off + footer + unsubscribe
Subject lines: short (<40 chars), friendly, no "review/survey", no ALL CAPS, no emoji.
HTML rules: table-based layout; all styles inline (no <style> tag); 600px max width;
bgcolor alongside CSS for Outlook; no JS, no background images; keep it text-heavy on early
sends for deliverability; always include a plain-text version.
Phase 3 — Test (MANDATORY)
Never skip. Never send without explicit confirmation.
- Create a broadcast on the test segment (id from config).
- Send the test (only goes to your test recipients).
- Ask the user to check: inbox placement (not Promotions/Spam), rendering, CTA target, the
unsubscribe link, mobile, and the from-name.
- Wait for explicit approval: "yes send it" or "schedule it for X".
Phase 4 — Send
Only after explicit confirmation:
- Create the broadcast on the general audience/segment (id from config).
- Send or schedule via Resend.
- Record it in
history.md.
Phase 5 — Clean up
Update history.md (keep last 5 full, older → one-line). Verify delivery via Resend
list-broadcasts / get-broadcast.
CAN-SPAM Compliance
Every marketing email MUST include:
- A physical mailing address (from config).
- A working unsubscribe link (Resend Broadcasts auto-manage this; it injects a
List-Unsubscribe header and skips unsubscribed contacts on future sends).
- An honest subject line, no deception.
- A real reply-to / support contact (from config).
Tools — when to use what
| Task |
Tool |
| List/manage contacts |
Resend MCP/API (list-contacts, create-contact, update-contact) |
| Create/send broadcast |
Resend MCP/API (create-broadcast, send-broadcast) |
| One-off transactional email |
Resend MCP/API (send-email) |
| Check broadcast stats |
Resend MCP/API (list-broadcasts, get-broadcast) |
History
history.md format per entry:
## [Date] — [Subject]
- Recipients: [N]
- Segment: General / Test
- Status: sent / scheduled [date]
- Key content: [1-line summary]
Keep the last 5 full entries; older → one-line archive at the bottom.
1---2name: email-broadcasts3description: Draft, test, and send marketing / product-update email broadcasts to an audience via Resend. Use when the user asks to "send a broadcast", "email blast", "newsletter", "product update email", "announce something to users", "marketing email", "review request", "how many contacts", "email history", or "what have we sent". Config-driven brand + sender; mandatory test send and explicit confirmation before any real send; CAN-SPAM compliant; bounded history.4---56# Email Broadcasts78<objective>9Manage product-update and marketing email broadcasts via Resend Broadcasts. Covers the full10workflow: audience sync/count, drafting (per design rules), a **mandatory test-send preview**,11an explicit user confirmation gate, sending to your audience, and history tracking with12rolling-window pruning. CAN-SPAM compliant. You set your brand, sender, addresses, and13segment IDs in `references/config.md`. NEVER sends to the full audience without an explicit14confirmation phrase ("yes send it").15</objective>1617<context>18@references/config.md19@history.md20</context>2122<execution_context>23- 🟢 Auto: contact/audience counts, history reads, knowledge lookups24- 🟡 ASK on: draft generation (preview required), test-segment send (still asks before the real send)25- 🔴 NEVER: send to the general audience without an explicit "yes send it" (or "schedule it for X")26- Mandatory self-preview: ALWAYS send a test broadcast to the test segment first, wait for "looks good"27- History: keep the last 5 broadcasts full, archive older to one-line at the bottom of `history.md`28</execution_context>2930## Setup (one time)3132Fill in `references/config.md` (brand, from/reply-to, physical address for CAN-SPAM, audience33+ test segment IDs, test recipients). Set:3435```bash36export RESEND_API_KEY="your-key" # free key at https://resend.com37```3839Manage contacts in your Resend **Audience** (import a CSV, or sync from your own source). This40skill treats the Resend audience as the source of truth — no specific backend is assumed.4142## Routing — what does the user want?4344| User says | Route to |45|-----------|----------|46| "send/draft a broadcast", "announce", "newsletter" | → **Draft & Send workflow** |47| "how many contacts/subscribers" | → **Resend: list contacts / audience count** |48| "what have we sent", "email history" | → **History** |49| "open rate", "stats" | → **Resend: list/get broadcast** |50| "how does unsubscribe / CAN-SPAM work" | → **Knowledge lookup** (below) |5152## Draft & Send Workflow5354### Phase 1 — Prepare551. Confirm the audience + count (Resend `list-contacts` / audience).562. Ask: purpose (product update, announcement, review request, custom)? What to highlight? CTA?5758### Phase 2 — Draft59Compose the email (HTML + plain text). Proven structure:60```61Short, warm intro (2-3 sentences)62WHAT'S NEW — section header + one card per item63A SMALL ASK — the CTA + a short line of context64Sign-off + footer + unsubscribe65```66**Subject lines:** short (<40 chars), friendly, no "review/survey", no ALL CAPS, no emoji.6768**HTML rules:** table-based layout; all styles inline (no `<style>` tag); 600px max width;69`bgcolor` alongside CSS for Outlook; no JS, no background images; keep it text-heavy on early70sends for deliverability; always include a plain-text version.7172### Phase 3 — Test (MANDATORY)73**Never skip. Never send without explicit confirmation.**741. Create a broadcast on the **test segment** (id from config).752. Send the test (only goes to your test recipients).763. Ask the user to check: inbox placement (not Promotions/Spam), rendering, CTA target, the77 unsubscribe link, mobile, and the from-name.784. Wait for explicit approval: **"yes send it"** or **"schedule it for X"**.7980### Phase 4 — Send81Only after explicit confirmation:821. Create the broadcast on the **general audience/segment** (id from config).832. Send or schedule via Resend.843. Record it in `history.md`.8586### Phase 5 — Clean up87Update `history.md` (keep last 5 full, older → one-line). Verify delivery via Resend88`list-broadcasts` / `get-broadcast`.8990## CAN-SPAM Compliance9192Every marketing email MUST include:93- A physical mailing address (from config).94- A working unsubscribe link (Resend Broadcasts auto-manage this; it injects a95 `List-Unsubscribe` header and skips unsubscribed contacts on future sends).96- An honest subject line, no deception.97- A real reply-to / support contact (from config).9899## Tools — when to use what100101| Task | Tool |102|------|------|103| List/manage contacts | Resend MCP/API (`list-contacts`, `create-contact`, `update-contact`) |104| Create/send broadcast | Resend MCP/API (`create-broadcast`, `send-broadcast`) |105| One-off transactional email | Resend MCP/API (`send-email`) |106| Check broadcast stats | Resend MCP/API (`list-broadcasts`, `get-broadcast`) |107108## History109110`history.md` format per entry:111```112## [Date] — [Subject]113- Recipients: [N]114- Segment: General / Test115- Status: sent / scheduled [date]116- Key content: [1-line summary]117```118Keep the last 5 full entries; older → one-line archive at the bottom.119120<saved_rules_format>121Stored in `history.md` "Saved Rules" section, surfaced each run as:122> "Previous rule found: '<rule>'. Apply? (Yes / No / Delete)"123Common topics: subject-line preferences, CTA copy, do-not-send-to-X rules.124</saved_rules_format>125126<recovery_protocol>127If `history.md` shows `status: scheduled` for a broadcast that should have sent → verify in the128Resend dashboard. If a draft was interrupted mid-workflow → offer Resume from last phase / Start129fresh / Review.130</recovery_protocol>131132<error_handling>133- Resend rate limit → sleep and retry; respect the free-tier limit.134- Test send doesn't arrive → wait, then check; if still missing, stop (don't proceed to the general send).135- Ambiguous approval phrase → re-ask explicitly: "Confirm: send to [N] contacts? Reply 'yes send it'."136</error_handling>137138<success_criteria>139- [ ] Audience count verified before the broadcast140- [ ] Test broadcast sent to the test segment FIRST141- [ ] User confirmed the test looked good142- [ ] Explicit "yes send it" (or "schedule it for X") before the general send143- [ ] history.md updated; last 5 full, older compacted144- [ ] Delivery verified after send