Marketing campaign builder skill

Draft and run Mailchimp email campaigns with AI-generated content, subject line A/B testing, and optimal send timing.

by hewi333·MIT license·★ 122 Stars on the repo·GitHub ↗

Use now

Inside this skill

SKILL.md · the author's own words
# Marketing Campaign Builder

## Overview
Most small businesses have a Mailchimp list they never use. They sent a few
campaigns years ago, got busy, and stopped. This skill fixes that by making
campaign creation **fast and owner-gated**:

1. Owner texts a campaign idea in Telegram
2. Agent drafts the email content + 2-3 subject line options
3. Owner picks a subject line (or suggests their own)
4. Agent creates an A/B test campaign in Mailchimp
5. Agent sends a test email to the owner
6. Owner approves → agent schedules the send at optimal time

**The owner never writes HTML, never logs into Mailchimp, never touches a
template editor.** They just describe what they want and approve the draft.

Word-for-word excerpt, not a result. Read the full SKILL.md ↓

Files of Marketing campaign builder

hewi333/main1 file shown
SKILL.md
Show the full text378 lines

Marketing Campaign Builder

Overview

Most small businesses have a Mailchimp list they never use. They sent a few campaigns years ago, got busy, and stopped. This skill fixes that by making campaign creation fast and owner-gated:

  1. Owner texts a campaign idea in Telegram
  2. Agent drafts the email content + 2-3 subject line options
  3. Owner picks a subject line (or suggests their own)
  4. Agent creates an A/B test campaign in Mailchimp
  5. Agent sends a test email to the owner
  6. Owner approves → agent schedules the send at optimal time

The owner never writes HTML, never logs into Mailchimp, never touches a template editor. They just describe what they want and approve the draft.

When to Use

  • "Send a summer special to all partners"
  • "We haven't emailed the list in 3 months — draft a re-engagement campaign"
  • "Send a seasonal reminder to all contacts in our service area"
  • "Create a campaign about our new website estimator tool"
  • "Send a holiday thank you to all customers"

Prerequisites

  • mailchimp-integration skill installed + API key wired
  • MAILCHIMP_AUDIENCE_ID set in environment
  • Owner available in Telegram to approve drafts

The Flow

Step 1: Owner Describes the Campaign

Owner sends a message in Telegram:

"Send a summer special to all partners — mention our partner pricing and that we do free estimates."

Agent extracts:

  • Audience segment: "partners" (or "all contacts" if not specified)
  • Topic: summer special
  • Key points to include: partner pricing, free estimates
  • Tone: matches the business (confident, professional, not salesy)
Step 2: Agent Drafts Content + Subject Lines

Agent generates:

  • 2-3 subject line options (short, punchy, under 50 chars for mobile)
  • Preview text (the snippet recipients see next to subject)
  • Email body in HTML, matching the business brand voice
  • Plain text version (for accessibility + spam filters)

Example output to owner in Telegram:

📧 Campaign Draft — Summer Partner Special

Subject line options:
A) "Summer Listings? Don't Let Odors Kill the Sale"
B) "Free Estimates for Your Summer Listings"
C) "Partner Special: Summer Service Discount"

Preview text: "[BUSINESS_NAME] — professional service for your
listings. Free estimates, partner pricing."

Body: [shows first few lines or summary]

Which subject line do you prefer? (A, B, or C — or type your own)
Step 3: Owner Picks Subject Line

Owner replies: "A" or "B" or "C" or types their own:

"Make it 'Protect Your Summer Listings from Odors'"

Agent updates the draft with the chosen subject line.

Step 4: Agent Creates Campaign in Mailchimp
Regular (single variant) Campaign
source ~/.hermes/.env

# Create campaign
CAMPAIGN=$(curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns" \
  --user "anystring:$MAILCHIMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "regular",
    "recipients": {
      "list_id": "'"$MAILCHIMP_AUDIENCE_ID"'",
      "segment_opts": {
        "saved_segment_id": SEGMENT_ID
      }
    },
    "settings": {
      "subject_line": "Summer Listings? Don'"'"'t Let Odors Kill the Sale",
      "preview_text": "[BUSINESS_NAME] — professional service for your listings.",
      "title": "Summer Partner Special - June 2026",
      "from_name": "[BUSINESS_NAME]",
      "reply_to": "[email protected]",
      "to_name": "*|FNAME|*"
    },
    "tracking": {
      "opens": true,
      "html_clicks": true
    }
  }')

CAMPAIGN_ID=$(echo "$CAMPAIGN" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
A/B Test (Variate) Campaign
# Create A/B test campaign testing two subject lines
CAMPAIGN=$(curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns" \
  --user "anystring:$MAILCHIMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "type": "variate",
    "recipients": {
      "list_id": "'"$MAILCHIMP_AUDIENCE_ID"'"
    },
    "variate_settings": {
      "winning_combination": "opens",
      "wait_time": 6,
      "test_size": 50,
      "test_segments": [
        {"segment_text": "Subject A"},
        {"segment_text": "Subject B"}
      ],
      "subject_lines": [
        "Summer Listings? Don'"'"'t Let Odors Kill the Sale",
        "Protect Your Summer Listings from Odors"
      ]
    },
    "settings": {
      "title": "Summer Partner Special A/B - June 2026",
      "from_name": "[BUSINESS_NAME]",
      "reply_to": "[email protected]",
      "to_name": "*|FNAME|*"
    }
  }')
Step 5: Set Campaign Content
curl -s -X PUT "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID/content" \
  --user "anystring:$MAILCHIMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "html": "<html><body>...campaign HTML...</body></html>",
    "plain_text": " plain text version..."
  }'
Step 6: Send Test to Owner
curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID/actions/test" \
  --user "anystring:$MAILCHIMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "test_emails": ["[email protected]"],
    "send_type": "html"
  }'

Agent tells owner: "Test email sent — check your inbox. Reply 'send' to send to the full list, or tell me what to change."

Step 7: Owner Approves → Send or Schedule

Send immediately:

curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID/actions/send" \
  --user "anystring:$MAILCHIMP_API_KEY"

Schedule for optimal time:

# Schedule for Tuesday 10am ET (best open rate for B2B per industry data)
curl -s -X PATCH "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID" \
  --user "anystring:$MAILCHIMP_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "schedule": {
      "schedule_time": "2026-07-07T14:00:00+00:00"
    }
  }'

Email Content Guidelines

Brand Voice
  • Confident, not salesy — "This works. Here's why." not "BUY NOW!!!"
  • Professional but warm — like a trusted local business, not a corporation
  • Short paragraphs — 2-3 sentences max, lots of white space
  • One clear CTA — "Get a Free Estimate" or "Call [PHONE]"
  • Mobile-first — 60%+ of recipients read on phones
Email Structure Template
<html>
<body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">

<!-- Header with logo -->
<img src="LOGO_URL" alt="[BUSINESS_NAME]" style="max-width: 200px; margin-bottom: 20px;">

<!-- Headline -->
<h1 style="color: #0C71C3; font-size: 24px;">HEADLINE HERE</h1>

<!-- Body copy -->
<p style="font-size: 16px; line-height: 1.6; color: #1A1A1A;">
BODY COPY HERE — 2-3 short paragraphs
</p>

<!-- CTA button -->
<a href="CTA_URL" style="display: inline-block; background: #0C71C3; color: white;
   padding: 12px 30px; text-decoration: none; border-radius: 5px; font-size: 16px;
   margin: 20px 0;">Get Your Free Estimate</a>

<!-- Footer -->
<hr style="border: none; border-top: 1px solid #ddd; margin: 30px 0;">
<p style="font-size: 12px; color: #888;">
[BUSINESS_NAME] | [SERVICE_DESCRIPTION] | [PHONE]<br>
Serving [SERVICE_AREA]<br>
<a href="*|UNSUB|*">Unsubscribe</a> | <a href="*|UPDATE_PROFILE|*">Update Preferences</a>
</p>

</body>
</html>
Subject Line Best Practices
  • Under 50 characters (mobile cuts off longer)
  • Create curiosity or urgency without being clickbait
  • Personalization with |FNAME| works but don't overuse
  • Test questions vs statements vs benefits
  • Examples that work:
    • "Summer Listings? Don't Let Odors Kill the Sale"
    • "|FNAME|, Free Estimates for Your Spring Listings"
    • "Seasonal Prep: Is Your Property Protected?"
    • "The Guarantee Real Estate Agents Trust"

A/B Testing Strategy

What to Test (in priority order)
  1. Subject lines — biggest impact on open rates
  2. Send time — Tuesday/Wednesday 10am-12pm ET typically wins for B2B
  3. From name — "[OWNER_NAME] @ [BUSINESS_NAME]" vs "[BUSINESS_NAME]" vs a campaign name
  4. Preview text — the snippet next to subject in inbox
  5. CTA — "Get Free Estimate" vs "See Pricing" vs "Call Now"
Mailchimp A/B Test Setup
  • Test size: 50% (send to 50% of list, 25% each variant, winner goes to remaining 50%)
  • Winning condition: opens (for subject line tests), clicks (for content tests)
  • Wait time: 6 hours (enough for a meaningful pattern, not so long it delays)
  • Don't over-test — 2 variants is plenty for a small business list
Campaign Timing Recommendations
Day Time (ET) Why
Tuesday 10:00am Best overall open rate for B2B
Wednesday 10:00am Second best, avoids Monday noise
Thursday 2:00pm Good for consumer-focused campaigns
Avoid Monday/Friday Buried in weekend cleanup or pre-weekend rush
Avoid Weekends B2B recipients don't check

Segmentation Strategy

Before Sending, Agent Checks Available Segments
# List existing segments
curl -s --user "anystring:$MAILCHIMP_API_KEY" \
  "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/lists/$MAILCHIMP_AUDIENCE_ID/segments"
If No Segments Exist, Agent Creates Them

Useful default segments for small businesses:

  • Active subscribers — opened an email in the last 90 days
  • Partners/Referrers — tagged "partner" (if tags exist)
  • By region — merge field REGION = specific region
  • Engaged — clicked a link in the last 60 days
  • Cold — no opens in 180 days (re-engagement target)

Campaign Report (Post-Send)

After a campaign sends (wait 48 hours), agent can pull the report:

curl -s --user "anystring:$MAILCHIMP_API_KEY" \
  "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/reports/$CAMPAIGN_ID" | python3 -m json.tool

Agent summarizes for owner in Telegram:

📊 Campaign Report — "Summer Partner Special"
Sent to: 1,500 contacts
Opens: 542 (30%) — above industry avg (21%)
Clicks: 28 (1.5%)
Unsubscribes: 3
Best segment: Standard Region (42% open rate)

Agent Integration Patterns

Pattern 1: Seasonal Campaign

Owner: "Send a seasonal campaign to all contacts" Agent: Drafts content about seasonal prep + prevention → subject lines → owner picks → test send → owner approves → scheduled for Tuesday 10am

Pattern 2: Partner Re-engagement

Agent detects (via CRM) that 12 partners haven't sent a lead in 6 months. Agent: Drafts a "We miss you" campaign targeted to cold partner segment → owner approves → send → track who re-engages → update CRM

Pattern 3: Post-Job Review Request

Job completes. Agent: Drafts a campaign asking the customer for a Google review with a direct link → owner approves → send to that one customer (not a bulk send)

Pattern 4: Content from CRM Data

Agent: "You booked 8 jobs from Standard Region partners this quarter — want me to draft a 'Standard Region Partner Thank You' campaign?" Owner: "Yes" → agent drafts.

Common Pitfalls

  1. Don't send without a test. Always send a test to the owner first. One wrong link or typo to 1,800 people can't be undone.
  2. Don't forget the unsubscribe footer. CAN-SPAM requires it. Mailchimp adds it automatically with *|UNSUB|* merge tag.
  3. Don't use too many images. Many email clients block images by default. Text should carry the message; images are enhancement.
  4. Don't send on Friday afternoon. Opens tank. Schedule for Tuesday-Wednesday.
  5. Don't A/B test everything at once. Test one variable per campaign. Subject lines first. Then timing. Then content.
  6. Merge tags need exact match. *|FNAME|* works only if the merge field tag is exactly FNAME. Check merge fields before using.
  7. From name consistency. Don't change from "[BUSINESS_NAME]" to "[OWNER_NAME]" across campaigns — it hurts recognition. Pick one and stick to it.

Verification Checklist

  • Can create a regular campaign via API
  • Can create a variate (A/B test) campaign via API
  • Can set campaign content (HTML + plain text)
  • Can send a test email to owner
  • Can send or schedule a campaign
  • Can pull campaign report (opens, clicks, unsubscribes)
  • Can create segments by tag/region/engagement
  • Owner approval workflow tested end-to-end

One-Shot Recipes

"Quick campaign: seasonal reminder"
# Owner says: "Send a seasonal prevention tip to all contacts for summer"
# Agent drafts 3 short tips + CTA → creates campaign → test → owner approves → send
"Re-engagement: cold contacts"
# Agent identifies contacts with no opens in 180 days
# Creates segment "Cold - 180 days"
# Drafts "We miss you" campaign with special offer
# Owner approves → send → track re-engagement → update CRM
"Monthly newsletter from CRM data"
# Agent pulls: new leads, jobs booked, revenue this month
# Drafts "[BUSINESS_NAME] Monthly" newsletter with stats + customer spotlight
# Owner approves → send → track engagement
# Schedule as monthly cron job
1---
2name: marketing-campaign-builder
3description: "Draft and run Mailchimp email campaigns with AI-generated content, subject line A/B testing, and optimal send timing. Agent drafts the email + subject variants, owner approves in Telegram, agent creates the campaign in Mailchimp. Turns a dormant contact list into an active marketing channel."
4version: "1.0.0"
5author: Hermes Agent
6license: MIT
7metadata:
8 hermes:
9 tags: [mailchimp, marketing, ab-testing, campaigns, email, small-business]
10 related_skills: [mailchimp-integration, crm-lite, lead-to-payment]
11---
12 
13# Marketing Campaign Builder
14 
15## Overview
16Most small businesses have a Mailchimp list they never use. They sent a few
17campaigns years ago, got busy, and stopped. This skill fixes that by making
18campaign creation **fast and owner-gated**:
19 
201. Owner texts a campaign idea in Telegram
212. Agent drafts the email content + 2-3 subject line options
223. Owner picks a subject line (or suggests their own)
234. Agent creates an A/B test campaign in Mailchimp
245. Agent sends a test email to the owner
256. Owner approves → agent schedules the send at optimal time
26 
27**The owner never writes HTML, never logs into Mailchimp, never touches a
28template editor.** They just describe what they want and approve the draft.
29 
30## When to Use
31- "Send a summer special to all partners"
32- "We haven't emailed the list in 3 months — draft a re-engagement campaign"
33- "Send a seasonal reminder to all contacts in our service area"
34- "Create a campaign about our new website estimator tool"
35- "Send a holiday thank you to all customers"
36 
37## Prerequisites
38- `mailchimp-integration` skill installed + API key wired
39- MAILCHIMP_AUDIENCE_ID set in environment
40- Owner available in Telegram to approve drafts
41 
42## The Flow
43 
44### Step 1: Owner Describes the Campaign
45Owner sends a message in Telegram:
46> "Send a summer special to all partners — mention our partner pricing
47> and that we do free estimates."
48 
49Agent extracts:
50- **Audience segment:** "partners" (or "all contacts" if not specified)
51- **Topic:** summer special
52- **Key points to include:** partner pricing, free estimates
53- **Tone:** matches the business (confident, professional, not salesy)
54 
55### Step 2: Agent Drafts Content + Subject Lines
56Agent generates:
57- **2-3 subject line options** (short, punchy, under 50 chars for mobile)
58- **Preview text** (the snippet recipients see next to subject)
59- **Email body** in HTML, matching the business brand voice
60- **Plain text version** (for accessibility + spam filters)
61 
62Example output to owner in Telegram:
63```
64📧 Campaign Draft — Summer Partner Special
65 
66Subject line options:
67A) "Summer Listings? Don't Let Odors Kill the Sale"
68B) "Free Estimates for Your Summer Listings"
69C) "Partner Special: Summer Service Discount"
70 
71Preview text: "[BUSINESS_NAME] — professional service for your
72listings. Free estimates, partner pricing."
73 
74Body: [shows first few lines or summary]
75 
76Which subject line do you prefer? (A, B, or C — or type your own)
77```
78 
79### Step 3: Owner Picks Subject Line
80Owner replies: "A" or "B" or "C" or types their own:
81> "Make it 'Protect Your Summer Listings from Odors'"
82 
83Agent updates the draft with the chosen subject line.
84 
85### Step 4: Agent Creates Campaign in Mailchimp
86 
87#### Regular (single variant) Campaign
88```bash
89source ~/.hermes/.env
90 
91# Create campaign
92CAMPAIGN=$(curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns" \
93 --user "anystring:$MAILCHIMP_API_KEY" \
94 -H "Content-Type: application/json" \
95 -d '{
96 "type": "regular",
97 "recipients": {
98 "list_id": "'"$MAILCHIMP_AUDIENCE_ID"'",
99 "segment_opts": {
100 "saved_segment_id": SEGMENT_ID
101 }
102 },
103 "settings": {
104 "subject_line": "Summer Listings? Don'"'"'t Let Odors Kill the Sale",
105 "preview_text": "[BUSINESS_NAME] — professional service for your listings.",
106 "title": "Summer Partner Special - June 2026",
107 "from_name": "[BUSINESS_NAME]",
108 "reply_to": "[email protected]",
109 "to_name": "*|FNAME|*"
110 },
111 "tracking": {
112 "opens": true,
113 "html_clicks": true
114 }
115 }')
116 
117CAMPAIGN_ID=$(echo "$CAMPAIGN" | python3 -c "import sys,json; print(json.load(sys.stdin)['id'])")
118```
119 
120#### A/B Test (Variate) Campaign
121```bash
122# Create A/B test campaign testing two subject lines
123CAMPAIGN=$(curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns" \
124 --user "anystring:$MAILCHIMP_API_KEY" \
125 -H "Content-Type: application/json" \
126 -d '{
127 "type": "variate",
128 "recipients": {
129 "list_id": "'"$MAILCHIMP_AUDIENCE_ID"'"
130 },
131 "variate_settings": {
132 "winning_combination": "opens",
133 "wait_time": 6,
134 "test_size": 50,
135 "test_segments": [
136 {"segment_text": "Subject A"},
137 {"segment_text": "Subject B"}
138 ],
139 "subject_lines": [
140 "Summer Listings? Don'"'"'t Let Odors Kill the Sale",
141 "Protect Your Summer Listings from Odors"
142 ]
143 },
144 "settings": {
145 "title": "Summer Partner Special A/B - June 2026",
146 "from_name": "[BUSINESS_NAME]",
147 "reply_to": "[email protected]",
148 "to_name": "*|FNAME|*"
149 }
150 }')
151```
152 
153### Step 5: Set Campaign Content
154```bash
155curl -s -X PUT "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID/content" \
156 --user "anystring:$MAILCHIMP_API_KEY" \
157 -H "Content-Type: application/json" \
158 -d '{
159 "html": "<html><body>...campaign HTML...</body></html>",
160 "plain_text": " plain text version..."
161 }'
162```
163 
164### Step 6: Send Test to Owner
165```bash
166curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID/actions/test" \
167 --user "anystring:$MAILCHIMP_API_KEY" \
168 -H "Content-Type: application/json" \
169 -d '{
170 "test_emails": ["[email protected]"],
171 "send_type": "html"
172 }'
173```
174 
175Agent tells owner: "Test email sent — check your inbox. Reply 'send' to send
176to the full list, or tell me what to change."
177 
178### Step 7: Owner Approves → Send or Schedule
179 
180**Send immediately:**
181```bash
182curl -s -X POST "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID/actions/send" \
183 --user "anystring:$MAILCHIMP_API_KEY"
184```
185 
186**Schedule for optimal time:**
187```bash
188# Schedule for Tuesday 10am ET (best open rate for B2B per industry data)
189curl -s -X PATCH "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/campaigns/$CAMPAIGN_ID" \
190 --user "anystring:$MAILCHIMP_API_KEY" \
191 -H "Content-Type: application/json" \
192 -d '{
193 "schedule": {
194 "schedule_time": "2026-07-07T14:00:00+00:00"
195 }
196 }'
197```
198 
199## Email Content Guidelines
200 
201### Brand Voice
202- **Confident, not salesy** — "This works. Here's why." not "BUY NOW!!!"
203- **Professional but warm** — like a trusted local business, not a corporation
204- **Short paragraphs** — 2-3 sentences max, lots of white space
205- **One clear CTA** — "Get a Free Estimate" or "Call [PHONE]"
206- **Mobile-first** — 60%+ of recipients read on phones
207 
208### Email Structure Template
209```html
210<html>
211<body style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; padding: 20px;">
212 
213<!-- Header with logo -->
214<img src="LOGO_URL" alt="[BUSINESS_NAME]" style="max-width: 200px; margin-bottom: 20px;">
215 
216<!-- Headline -->
217<h1 style="color: #0C71C3; font-size: 24px;">HEADLINE HERE</h1>
218 
219<!-- Body copy -->
220<p style="font-size: 16px; line-height: 1.6; color: #1A1A1A;">
221BODY COPY HERE — 2-3 short paragraphs
222</p>
223 
224<!-- CTA button -->
225<a href="CTA_URL" style="display: inline-block; background: #0C71C3; color: white;
226 padding: 12px 30px; text-decoration: none; border-radius: 5px; font-size: 16px;
227 margin: 20px 0;">Get Your Free Estimate</a>
228 
229<!-- Footer -->
230<hr style="border: none; border-top: 1px solid #ddd; margin: 30px 0;">
231<p style="font-size: 12px; color: #888;">
232[BUSINESS_NAME] | [SERVICE_DESCRIPTION] | [PHONE]<br>
233Serving [SERVICE_AREA]<br>
234<a href="*|UNSUB|*">Unsubscribe</a> | <a href="*|UPDATE_PROFILE|*">Update Preferences</a>
235</p>
236 
237</body>
238</html>
239```
240 
241### Subject Line Best Practices
242- Under 50 characters (mobile cuts off longer)
243- Create curiosity or urgency without being clickbait
244- Personalization with *|FNAME|* works but don't overuse
245- Test questions vs statements vs benefits
246- Examples that work:
247 - "Summer Listings? Don't Let Odors Kill the Sale"
248 - "*|FNAME|*, Free Estimates for Your Spring Listings"
249 - "Seasonal Prep: Is Your Property Protected?"
250 - "The Guarantee Real Estate Agents Trust"
251 
252## A/B Testing Strategy
253 
254### What to Test (in priority order)
2551. **Subject lines** — biggest impact on open rates
2562. **Send time** — Tuesday/Wednesday 10am-12pm ET typically wins for B2B
2573. **From name** — "[OWNER_NAME] @ [BUSINESS_NAME]" vs "[BUSINESS_NAME]" vs a campaign name
2584. **Preview text** — the snippet next to subject in inbox
2595. **CTA** — "Get Free Estimate" vs "See Pricing" vs "Call Now"
260 
261### Mailchimp A/B Test Setup
262- Test size: 50% (send to 50% of list, 25% each variant, winner goes to remaining 50%)
263- Winning condition: opens (for subject line tests), clicks (for content tests)
264- Wait time: 6 hours (enough for a meaningful pattern, not so long it delays)
265- Don't over-test — 2 variants is plenty for a small business list
266 
267### Campaign Timing Recommendations
268| Day | Time (ET) | Why |
269|-----|-----------|-----|
270| Tuesday | 10:00am | Best overall open rate for B2B |
271| Wednesday | 10:00am | Second best, avoids Monday noise |
272| Thursday | 2:00pm | Good for consumer-focused campaigns |
273| Avoid | Monday/Friday | Buried in weekend cleanup or pre-weekend rush |
274| Avoid | Weekends | B2B recipients don't check |
275 
276## Segmentation Strategy
277 
278### Before Sending, Agent Checks Available Segments
279```bash
280# List existing segments
281curl -s --user "anystring:$MAILCHIMP_API_KEY" \
282 "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/lists/$MAILCHIMP_AUDIENCE_ID/segments"
283```
284 
285### If No Segments Exist, Agent Creates Them
286Useful default segments for small businesses:
287- **Active subscribers** — opened an email in the last 90 days
288- **Partners/Referrers** — tagged "partner" (if tags exist)
289- **By region** — merge field REGION = specific region
290- **Engaged** — clicked a link in the last 60 days
291- **Cold** — no opens in 180 days (re-engagement target)
292 
293## Campaign Report (Post-Send)
294After a campaign sends (wait 48 hours), agent can pull the report:
295```bash
296curl -s --user "anystring:$MAILCHIMP_API_KEY" \
297 "https://$MAILCHIMP_SERVER_PREFIX.api.mailchimp.com/3.0/reports/$CAMPAIGN_ID" | python3 -m json.tool
298```
299 
300Agent summarizes for owner in Telegram:
301```
302📊 Campaign Report — "Summer Partner Special"
303Sent to: 1,500 contacts
304Opens: 542 (30%) — above industry avg (21%)
305Clicks: 28 (1.5%)
306Unsubscribes: 3
307Best segment: Standard Region (42% open rate)
308```
309 
310## Agent Integration Patterns
311 
312### Pattern 1: Seasonal Campaign
313Owner: "Send a seasonal campaign to all contacts"
314Agent: Drafts content about seasonal prep + prevention → subject lines →
315owner picks → test send → owner approves → scheduled for Tuesday 10am
316 
317### Pattern 2: Partner Re-engagement
318Agent detects (via CRM) that 12 partners haven't sent a lead in 6 months.
319Agent: Drafts a "We miss you" campaign targeted to cold partner segment →
320owner approves → send → track who re-engages → update CRM
321 
322### Pattern 3: Post-Job Review Request
323Job completes. Agent: Drafts a campaign asking the customer for a Google review
324with a direct link → owner approves → send to that one customer (not a bulk send)
325 
326### Pattern 4: Content from CRM Data
327Agent: "You booked 8 jobs from Standard Region partners this quarter — want me to
328draft a 'Standard Region Partner Thank You' campaign?" Owner: "Yes" → agent drafts.
329 
330## Common Pitfalls
331 
3321. **Don't send without a test.** Always send a test to the owner first.
333 One wrong link or typo to 1,800 people can't be undone.
3342. **Don't forget the unsubscribe footer.** CAN-SPAM requires it. Mailchimp
335 adds it automatically with `*|UNSUB|*` merge tag.
3363. **Don't use too many images.** Many email clients block images by default.
337 Text should carry the message; images are enhancement.
3384. **Don't send on Friday afternoon.** Opens tank. Schedule for Tuesday-Wednesday.
3395. **Don't A/B test everything at once.** Test one variable per campaign.
340 Subject lines first. Then timing. Then content.
3416. **Merge tags need exact match.** `*|FNAME|*` works only if the merge field
342 tag is exactly FNAME. Check merge fields before using.
3437. **From name consistency.** Don't change from "[BUSINESS_NAME]" to "[OWNER_NAME]"
344 across campaigns — it hurts recognition. Pick one and stick to it.
345 
346## Verification Checklist
347- [ ] Can create a regular campaign via API
348- [ ] Can create a variate (A/B test) campaign via API
349- [ ] Can set campaign content (HTML + plain text)
350- [ ] Can send a test email to owner
351- [ ] Can send or schedule a campaign
352- [ ] Can pull campaign report (opens, clicks, unsubscribes)
353- [ ] Can create segments by tag/region/engagement
354- [ ] Owner approval workflow tested end-to-end
355 
356## One-Shot Recipes
357 
358### "Quick campaign: seasonal reminder"
359```python
360# Owner says: "Send a seasonal prevention tip to all contacts for summer"
361# Agent drafts 3 short tips + CTA → creates campaign → test → owner approves → send
362```
363 
364### "Re-engagement: cold contacts"
365```python
366# Agent identifies contacts with no opens in 180 days
367# Creates segment "Cold - 180 days"
368# Drafts "We miss you" campaign with special offer
369# Owner approves → send → track re-engagement → update CRM
370```
371 
372### "Monthly newsletter from CRM data"
373```python
374# Agent pulls: new leads, jobs booked, revenue this month
375# Drafts "[BUSINESS_NAME] Monthly" newsletter with stats + customer spotlight
376# Owner approves → send → track engagement
377# Schedule as monthly cron job
378```

Discussion