Newsletter
SKILL.md
HOW_TO_USE.md
sample_input.json
expected_output.json
skillsmarketingSKILL.md
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# Newsletter
A newsletter is a promise: something worth opening, on a schedule. This skill keeps the promise with evidence. It reads what you published, what people read and what past issues got clicked, then writes the issue around that. Every item it features has a reason you can see, and every fact in the copy comes from a page it read.
## Before you start
You need the InsightfulPipe MCP. The more of these are connected, the better the picks, but none is required:
| Source | What it adds | Platform |
|---|---|---|
| Google Analytics 4 | which posts people read and stayed on | `google-analytics` |
| Search Console | which posts pull search clicks | `google-search-console` |
| Klaviyo or Mailchimp | what past issues got clicked, and where to save the draft | `klaviyo`, `mailchimp` |
| SEO crawler | reads the blog index and the posts | `crawler` (built in) |
| DataForSEO (added to the MCP; bills per call) | public search estimates for a site you don't own, partner discovery, a backup page reader | `dataforseo` |
1. Call `query_contexts` with `request="accounts"` for each platform above. Note `workspace_id`, `brand_id`, the GA4 `property_id`, the Search Console `site_url`, and which email platform is connected. If there are several properties or sites, ask which one belongs to the blog.
2. Call `query_contexts` with `request="actions_details"` for every action you will use (listed in each step) and follow the body shapes it returns.
3. Ask for what the data can't tell you. Use the defaults when the user doesn't know:
- **Newsletter name and audience.** Default: the blog's name; audience = people who read the blog.
- **Goal.** What should a reader do: click to a post, reply, buy, share, or learn something. Default: click to the lead post.
- **Cadence and window.** Default: monthly, window = the last full calendar month. Weekly: the last 7 complete days.
- **Blog URL** (the index page that lists posts) and **voice** (two or three past issues or posts they like). Default voice: the blog's own.
- **Topics that are off-audience** (for example hiring or engineering posts in a customer newsletter). Default: none; Claude flags likely ones and asks.
4. Pick the mode from the request: **issue** (default), **ideas**, **review**, **cross-promotion**, **email course** or **launch and sponsorship** (start a newsletter, or make money from one). One request can combine them.
## How to run the calls
Every read goes through `query_data` with the `platform` named in the step. Rules the APIs enforce:
- **Rate limits are shared.** On `rate_limit_exceeded`, wait `retry_after` seconds and retry. Don't fire calls in parallel.
- **An empty answer is not an error.** A Klaviyo account with no sends returns `success` with an empty list. Say "no history" and move on.
- **GA4 needs `properties/` before the id**, and filters use `dimensionFilter`. Drop rows whose title says "Not Found" or "404" and paths with stray characters: in testing, broken links to posts showed up as their own rows.
- **Search Console pages are full URLs**; GA4 paths are not. Join on the path.
- **Klaviyo campaigns need a channel filter** (`equals(messages.channel,'email')`), and status values are Title Case (`'Sent'`). Klaviyo reports carry `campaign_message_name`, not the subject line; ask the user for subjects if you need them.
- **Mailchimp calls in this skill are untested until a Mailchimp account is connected.** Their shapes come from the helper. Run `actions_details` first and adjust if a field name differs.
- **The crawler can fail.** On 2026-10-06 it returned `Error fetching URL` for every page during testing. When it does, read the pages with DataForSEO `onpage_content_parsing`, or read them directly, and say which you used.
- **More than one DataForSEO connection on the brand?** Add `"account_id"` (from `accounts`) to every DataForSEO body; without it the call is refused. `Payment Required` means that login has no balance: use another connection or mark the signal unknown.
- **DataForSEO costs money.** Use `location_code` 2840 and `language_code` `en` unless the audience is elsewhere. Keep a run to about 12 calls: one or two `labs_ranked_keywords` pages, and content parsing only for the posts you feature or put in a course.
If a call fails, keep going. Mark that signal **unknown**, say which call failed, and never fill the gap with a guess.
## Step 1: what was published in the window
**List the posts.** Run `link-extractor` on the blog index (and page 2 if the index pages):
```json
{"platform": "crawler", "workspace_id": "<WORKSPACE_ID>", "action": "link-extractor", "url": "<BLOG_INDEX_URL>"}
```
Keep internal links whose path looks like a post (not tags, authors, hubs or pagination). The publish date comes from the blog's feed or sitemap when it has one (Claude can read those directly), from the page itself, or from the GA4 rule below. If none works, ask the user which posts are new.
**Titles and outlines.** For each candidate post:
```json
{"platform": "crawler", "workspace_id": "<WORKSPACE_ID>", "action": "meta-tags-checker", "url": "<POST_URL>"}
```
```json
{"platform": "crawler", "workspace_id": "<WORKSPACE_ID>", "action": "headings-checker", "url": "<POST_URL>"}
```
`content-quality-checker` (same body) adds word count and readability when you need a reading-time line.
**Backup page reader** (the crawler is down, or the site blocks it):
```json
{"platform": "dataforseo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "onpage_content_parsing", "url": "<POST_URL>"}
```
The text sits in `page_content.main_topic`: each block has `h_title`, `level` and `primary_content[].text`.
## Step 2: what got attention
Use the first source that applies.
**A. Your own site, GA4 connected.** Posts read in the window:
```json
{"platform": "google-analytics", "action": "get_report", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "property_id": "properties/<PROPERTY_ID>", "dimensions": ["pagePath", "pageTitle"], "metrics": ["screenPageViews", "engagedSessions", "userEngagementDuration"], "start_date": "<START>", "end_date": "<END>", "dimensionFilter": {"filter": {"fieldName": "pagePath", "stringFilter": {"matchType": "BEGINS_WITH", "value": "<BLOG_PATH_PREFIX>"}}}, "limit": 500}
```
The same body for the 90 days before `<START>`, with `"dimensions": ["pagePath"]` and `"metrics": ["screenPageViews"]`: a post with views in the window and none in those 90 days is **new this window**. Use this when the blog has no dates.
**B. Search Console connected.** Search clicks per post:
```json
{"platform": "google-search-console", "action": "search_analytics", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "site_url": "<SITE_URL>", "dimensions": ["page"], "start_date": "<START>", "end_date": "<END>", "row_limit": 1000, "dimension_filter_groups": [{"filters": [{"dimension": "page", "operator": "contains", "expression": "<BLOG_PATH_PREFIX>"}]}]}
```
**C. A site you don't own or haven't connected.** Public search estimates for the window's posts:
```json
{"platform": "dataforseo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "labs_ranked_keywords", "target": "<BLOG_HOST>", "location_code": 2840, "language_code": "en", "limit": 1000, "filters": [["ranked_serp_element.serp_item.url", "in", ["<POST_URL_1>", "<POST_URL_2>"]]], "order_by": ["ranked_serp_element.serp_item.etv,desc"]}
```
If `total_count` is over 1,000, run it again with `"offset": 1000`. Sum `ranked_serp_element.serp_item.etv` per URL: that is the page's estimated monthly US search visits. It is the current estimate, not traffic inside the window, so say so. Use the blog's own host as `target` (a subdomain blog needs the subdomain); `labs_relevant_pages` returned nothing for a subdomain blog in testing. A post the feed dates to the window can still be an older page that was updated (in testing, one "September" post already ranked for nearly 800 phrases), so call them "dated in the window", not "new".
**Score.** Per post: GA4 engaged sessions (A); if there is no GA4, Search Console clicks (B); if neither, the estimated search visits (C). Posts with no row score 0. Say which source scored the posts.
## Step 3: what past issues taught (email platform)
**Klaviyo.** Sent email campaigns, then their results over the last 12 months:
```json
{"platform": "klaviyo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "get_campaigns", "filter": "and(equals(messages.channel,'email'),any(status,['Sent','Variations Sent']))", "fields[campaign]": "name,status,send_time,audiences", "sort": "-created_at", "auto_paginate": true}
```
```json
{"platform": "klaviyo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "get_campaign_report", "body": {"data": {"type": "campaign-values-report", "attributes": {"timeframe": {"key": "last_12_months"}, "group_by": ["campaign_id", "campaign_message_id", "campaign_message_name", "send_channel"], "statistics": ["recipients", "delivered", "opens_unique", "clicks_unique", "click_rate", "unsubscribe_rate", "spam_complaint_rate", "conversion_value"]}}}}
```
Rates come back as fractions (0.021 = 2.1%).
**Mailchimp** (untested until connected). Sent campaigns with subject lines and results, then the links clicked in each recent issue:
```json
{"platform": "mailchimp", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "list_campaigns", "status": "sent", "since_send_time": "<12_MONTHS_AGO_ISO>", "fields": "id,send_time,archive_url,settings.subject_line,settings.preview_text,recipients.list_id", "auto_paginate": true}
```
```json
{"platform": "mailchimp", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "list_reports", "since_send_time": "<12_MONTHS_AGO_ISO>", "auto_paginate": true}
```
```json
{"platform": "mailchimp", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "get_report_click_details", "campaign_id": "<CAMPAIGN_ID>", "auto_paginate": true}
```
**What to take from the history** (only with at least 3 sent issues and 1,000 delivered in total; below that, say "not graded" and use the defaults):
- **Topics that get clicks.** Share of clicks by the topic of the linked post (Mailchimp click details). Topics that won twice get the lead slot more readily.
- **Subject styles.** Click rate by style (specific, curiosity, direct value, personal; see Step 5). Judge on clicks, not opens: privacy features inflate opens.
- **Fatigue.** An issue with an unsubscribe rate over twice the median, or any spam rate over 0.1%, is a warning. Name what was different about it (length, topic, frequency).
- **Send slot.** The weekday and hour with the best median click rate, only if each slot has 3 or more sends. Otherwise keep the current slot.
## Step 4: rank and pick
Apply these in order and show the result as a table (post, topic, score, role, reason):
1. **Window.** Keep posts dated in the window. A post dated after it waits for the next issue.
2. **Audience.** Drop posts off-audience for this newsletter (hiring, engineering, investor news in a customer newsletter) and list them with the reason. Ask when unsure.
3. **Topics.** Group posts on the same subject into one topic. A topic's score is the sum of its posts.
4. **Lead.** The highest-scoring topic leads. Its best post is the lead link. Past-issue history can move a topic up one place when it won clicks twice; say so when it does.
5. **Supporting.** The next 3 topics by score, one post each (the topic's best).
6. **Fresh pick.** One on-audience post with score 0, newest first, so new work gets a chance before it has data.
7. **Quick links.** Up to 2 more on-audience posts as one-line links. The rest are listed as "also published", not in the issue.
8. **Course check.** A topic with 3 or more posts in the window is an email-course candidate: offer it in the issue and outline it (see Email course).
## Step 5: pick a format and write
**Nine formats.** Pick one per issue and say why. Keep it the same across issues unless the user wants a change; readers learn the shape.
| Format | When it fits | Shape |
|---|---|---|
| Curator | a month of posts, busy readers | short intro, 3 to 7 picks each with a one-line "why it matters", sign-off |
| Teacher | one skill worth learning | promise, why now, the steps with an example each, one thing to do today |
| Storyteller | one strong story | open mid-scene, the problem, the turn, the lesson, a light bridge to the link |
| Roundup | a recurring, easy-to-make issue | fixed sections (news, tool, stat, tip, read), same order every time |
| Analyst | a data-minded audience | the finding first, how you know, what it means, the limits |
| Behind the scenes | building trust | something normally hidden, why you're sharing it, the details, the lesson |
| Interview or Q&A | outside expertise | who and why, 3 to 5 sharp questions, a takeaway, where to find them |
| Contrarian | cutting through noise | the common belief, where it breaks, the alternative, the evidence, an invitation to disagree |
| Product update | adoption of something new | what changed, the problem it solves, how to try it in one step |
Default, first match wins: **Product update** when the lead is a launch; **Teacher** when the issue covers one topic (only one on-audience topic has a score, or the user asks for a single-topic issue); otherwise **Curator** for a monthly or weekly digest, even when one topic holds most of the score, because the lead slot and the email course carry that topic.
**Write these parts:**
1. **Three subject lines,** one each of: *specific* (numbers or names from the posts), *curiosity* (a question or an odd detail), *direct value* (what the reader gets). A *personal* one ("quick question") suits reply goals. Each 50 characters or fewer.
2. **Preview text** of 40 to 110 characters that adds something the subject doesn't say.
3. **The body** in the chosen format: value in the first two sentences, the lead, the supporting items, the fresh pick, quick links, one clear call to action, a sign-off with a reply prompt.
4. **Links** tagged `utm_source=newsletter&utm_medium=email&utm_campaign=<yyyy-mm>-<newsletter-slug>` so GA4 can show what each issue drove. At most 7 links in the body.
5. **What's needed to finish:** images (one per lead and supporting item, with alt text), personalisation fields, the course signup link if there is one.
6. **Send timing** from the history (Step 3), or "keep your current slot" with the reason.
7. **One A/B test,** usually subject A against subject B, judged on click rate.
**Repurposing inside an issue:** a long guide becomes its 3 most useful points plus the link; a list post becomes its best item plus a teaser of the rest; a case study becomes the story with the result as the hook; a social thread becomes the expanded version; a post that did unusually well becomes a Behind the scenes issue on why; poll results become an Analyst issue; common customer questions become a Teacher issue, a customer success story a Storyteller issue, and a common objection a Contrarian issue.
## Step 6: checks before handing it over
| Check | Pass when |
|---|---|
| Subjects | 3 options, each 50 characters or fewer, three different styles |
| Preview | 40 to 110 characters and doesn't repeat the subject |
| Facts | every factual line traces to a post read in this run (keep a fact ledger: line, post, the sentence it came from) |
| No invented numbers | no stats, results or promises that aren't in the posts or the data |
| Links | 7 or fewer in the body, every one tagged, one primary call to action |
| Length | Curator, Roundup, Product update: 150 to 450 words. Teacher, Storyteller, Analyst, Behind the scenes, Interview, Contrarian: 300 to 800 |
| Voice | matches the samples the user gave, or the blog's own tone |
| Mobile | paragraphs of 60 words or fewer, no layout that relies on side-by-side columns |
Report each check as pass or fail. Fix a fail before handing over, and say what you changed.
## Other modes
**Ideas.** Ten (or the number asked) issue ideas, each tied to evidence: a topic whose posts led on engaged sessions or clicks, a search phrase with real demand where the site ranks in the top 20 (GSC query rows, or DataForSEO keyword rows for a public site), a topic that won clicks in past issues, or a question readers asked. Rule: among topics that didn't lead this issue and aren't the course, take each topic's highest-volume search phrase where the site ranks 20 or better, and rank the topics by that volume. Each idea gets a working subject line, a format and the evidence row. Don't invent demand: an idea with no evidence is labelled "editorial".
**Review a sent issue.** Pull the issue and its numbers, then grade it with the Step 6 checks plus results:
- Klaviyo: the campaign row from Step 3, and its template HTML:
```json
{"platform": "klaviyo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "get_email_templates", "fields[template]": "name,editor_type,created,updated", "sort": "-updated", "auto_paginate": true}
```
```json
{"platform": "klaviyo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "get_email_template", "template_id": "<TEMPLATE_ID>", "fields[template]": "name,editor_type,html,text"}
```
- Mailchimp (untested until connected): the `archive_url` from `list_campaigns` is the issue's web version. Run the crawler's `link-extractor`, `headings-checker` and `image-optimization-checker` on it, and `get_report_click_details` for which links earned the clicks.
- Grade: click rate against the newsletter's own median (not an industry figure), unsubscribe and spam against Step 3's fatigue rule, links that got no clicks, images without alt text, a missing plain-text part, more than one competing call to action, and a subject that promised something the body didn't deliver. End with the 3 changes for the next issue.
**Cross-promotion.** Grow the list from what already gets traffic and from partners:
- Own pages: the GA4 landing pages with the most sessions in the last 30 days are where a signup form or a "get this in your inbox" line pays most:
```json
{"platform": "google-analytics", "action": "get_report", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "property_id": "properties/<PROPERTY_ID>", "dimensions": ["landingPage"], "metrics": ["sessions", "engagedSessions"], "start_date": "<START>", "end_date": "<END>", "limit": 50}
```
- The list to grow: Klaviyo `get_lists` (`{"platform": "klaviyo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "get_lists", "auto_paginate": true}`) or Mailchimp `list_lists` (`"fields": "id,name,stats.member_count,stats.avg_sub_rate"`, untested until connected).
- Partners: newsletters in the same niche that rank for "<topic> newsletter" (one call):
```json
{"platform": "dataforseo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "serp_google_organic", "keyword": "<TOPIC> newsletter", "location_code": 2840, "language_code": "en", "depth": 10}
```
Keep organic results that are a business's newsletter; skip personal pages. For each, propose the swap: a one-line recommendation in each other's issue, a guest section, or a shared resource, with its own UTM campaign so both sides can see what it drove.
- Plus the placements you already own: the social profiles' bio links, a line in every blog post's footer, the email signature, and the thank-you page after a purchase or signup.
**Email course.** From a topic with 3 or more posts: 3 to 7 lessons, one a day, ordered from the overview post to the specific ones. Each lesson: a subject of 50 characters or fewer, one idea in 200 words or fewer drawn from its post, one small practice task, one tagged link (`utm_campaign=<course-slug>`). Lesson 1 says what the course covers; the last lesson points to the next step (the newsletter, a product, a reply). Build it as an automation in the email platform; this skill writes it, it doesn't build the automation.
## Launch and sponsorship
For a newsletter that doesn't exist yet, or one that should start paying for itself. It works from a description alone (topic, audience, the hours a week the user has, the money goal); every connected source replaces an assumption with a number, and each assumption is labelled in the plan.
**Ask first** (defaults in brackets): who it's for and what they should be able to do after reading; hours a week for the newsletter [ask, no default]; the money goal per month [none: plan the launch only]; the smallest sponsor deal worth selling and running [the user's hourly rate times 2 hours]; the platform they send from today [none]; for an existing newsletter on Substack, Beehiiv, Ghost or Kit (not connectors), paste per-issue delivered (or recipients) and unique clicks for the last 3 or more issues from the dashboard or an export.
### Part 1: the launch
1. **Topic angle from demand.** List 3 to 10 candidate angles (the user's, plus topics the blog already covers). If Search Console is connected, pull the queries that contain each angle's main word over the last 90 days:
```json
{"platform": "google-search-console", "action": "search_analytics", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "site_url": "<SITE_URL>", "dimensions": ["query"], "start_date": "<START>", "end_date": "<END>", "row_limit": 25000, "dimension_filter_groups": [{"filters": [{"dimension": "query", "operator": "contains", "expression": "<ANGLE_WORD>"}]}]}
```
Sum `impressions` per angle. Keep `row_limit` at 25000: in testing, one angle word matched 1,063 queries, and a limit of 1,000 would have cut the sum short.
With DataForSEO added, check public demand for the angles in one call (the same call also feeds the rate card in Part 2, so put the sponsor keywords in it too):
```json
{"platform": "dataforseo", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "action": "labs_keyword_overview", "account_id": "<DATAFORSEO_ACCOUNT_ID>", "keywords": ["<ANGLE_KEYWORD_1>", "<ANGLE_KEYWORD_2>", "<SPONSOR_KEYWORD_1>", "<SPONSOR_KEYWORD_2>"], "location_code": 2840, "language_code": "en"}
```
(Body checked with the helper. The live call is untested in this build: one DataForSEO login answered `Payment Required` and the other returned an empty provider answer, `Ok. (status 20000)` with no rows. An empty answer like that means unknown, not zero demand.) Each row has `keyword_info.search_volume`, `keyword_info.cpc`, `keyword_info.low_top_of_page_bid`, `keyword_info.high_top_of_page_bid` and `search_intent_info.main_intent`. Rule: pick the angle with the most Search Console impressions (the site already earns attention there); with no Search Console, the angle with the highest informational search volume. An angle the user insists on wins and is labelled "editorial".
2. **The promise,** one sentence the signup form can carry: who it's for, what they get, how often, and what they'll be able to do. Then 3 subject lines for issue 1 (Step 5 rules).
3. **Format** from the Step 5 table, by what the user can feed it: Curator or Roundup when they publish or collect at least 3 items per issue; Teacher when one subject runs deep; Analyst when they have their own data; Storyteller or Behind the scenes when the value is their experience.
4. **Cadence the user can keep for 12 issues.** Take the most frequent of weekly, every two weeks and monthly where both hold:
- hours per issue (the user's estimate for the chosen format) times issues a month is no more than 80% of the hours they have a month, leaving room for a bad week;
- for Curator and Roundup, posts published a month (Step 1's post list, or the user's count) cover at least 3 items per issue.
Show the arithmetic. If no cadence passes, say which input to change.
5. **Platform by need,** not by ranking:
- Already emailing this audience from Klaviyo or Mailchimp: start there. One list, one unsubscribe, and through InsightfulPipe this skill reads its results and saves drafts.
- A paid tier from day one: a platform with paid subscriptions built in, for example Substack, Beehiiv, Ghost or Kit. Fees and features change; tell the user to check each pricing page, and never quote a fee.
- A sponsor-led newsletter on Mailchimp or Klaviyo works too; sponsors are sold directly, as in Part 2.
Say plainly that Substack, Beehiiv, Ghost and Kit aren't InsightfulPipe connectors: for them the skill works from pasted stats.
6. **Subscriber targets.** The milestones are the audiences the chosen revenue options need (Part 2), in delivered emails per issue. Monthly signups needed = (target minus current delivered) / months to the target date. Compare it with what signups run at today: Mailchimp `list_lists` with `"fields": "id,name,stats.member_count,stats.avg_sub_rate"` (`avg_sub_rate` is the average number of new subscribers a month, not a percentage; untested until connected), or the user's number. The gap goes to the cross-promotion mode, which names where the signups come from.
7. **First 90 days,** dated from the launch day: authenticate the sending domain (SPF, DKIM and DMARC; Gmail and Yahoo require them for bulk senders), a welcome email that restates the promise, signup placements from cross-promotion, a backlog of 3 issues from the ideas mode before issue 1 goes out, then issues on the cadence. After issue 3 (and 1,000 delivered in total), Step 3's history opens and the rate card can be priced on real numbers.
### Part 2: revenue options and the audience each needs
**Baseline,** from Step 3's history (the same gate: 3 or more sent issues and 1,000 delivered in total; Klaviyo `get_campaign_report`, Mailchimp `list_reports` (the Step 3 body), or the pasted export):
- **D**, median delivered per issue (Klaviyo `delivered`; Mailchimp `emails_sent` minus bounces, or `emails_sent` when bounces aren't pulled, and say so).
- **U**, median unique clickers per issue (Klaviyo `clicks_unique`, Mailchimp `clicks.unique_subscriber_clicks`), and **CR** = U / D.
- Below the gate, nothing is priced: the plan shows the formulas, the audience each option needs at a click rate the user supplies (labelled assumption), and the date the gate should open on the planned cadence.
**Slot share (s),** the part of an issue's unique clickers one placement can expect:
- Mailchimp (untested until connected): for each of the last issues, `get_report_click_details` gives unique clicks per link, and the crawler's `link-extractor` on the issue's `archive_url` gives the link order. Primary slot (top, after the intro) = the median share the first featured link got; secondary (mid-issue) = the median share of the links in places 2 to 4; classified (one line near the end) = the median share of the last two links.
- Pasted link reports: Substack, Beehiiv, Ghost and Kit dashboards usually list clicks for each link in a sent issue. Ask for that list for each of the last issues, top to bottom as the links appear, and apply the same three medians. When the counts are total clicks rather than unique clickers, divide each link by the issue's total link clicks instead of by U, and say which count was used.
- No per-link numbers at all (Klaviyo through the connector, or an export with only issue totals): use 1 / the typical link count per issue for the primary slot (1/7 at this skill's link cap), half of that for secondary and classified, and label it an estimate to replace after the first 3 placements.
**Value per click (V).** What advertisers already pay to reach this audience by search: the median `low_top_of_page_bid` (floor) and median `cpc` (ceiling) across 3 to 10 commercial or transactional keywords the likely sponsors buy, from the same `labs_keyword_overview` call. If a sponsor shares what a click is worth to them, use that. Without DataForSEO, ask the user for a floor and label it.
**Rate card.**
| Placement | Expected clicks | List price | Ceiling | Implied CPM |
|---|---|---|---|---|
| Primary | U × s(primary) | clicks × floor V, rounded down to $5 | clicks × ceiling V | list price / D × 1,000 |
| Secondary | U × s(secondary) | same | same | same |
| Classified | U × s(classified) | same | same | same |
| Dedicated issue (one sponsor, whole issue) | median U of the newsletter's own single-topic issues (Teacher, Product update) when 3 or more exist; otherwise U, labelled an upper bound | same | same | same |
The CPM column is there for buyers who compare that way; it never sets the price. Booking 4 issues gets the same placement each time at the same per-issue price; offer a discount only if the user wants one. Re-price after every 3 placements from what they actually earned.
**The audience each option needs,** in delivered emails per issue, with "met" or the gap:
- **Sponsor slots:** D needed = minimum deal / (CR × s(primary) × floor V).
- **Paid tier:** paid subscribers needed = monthly goal / (monthly price × (1 minus the platform's fee share)). List needed = paid subscribers / the paid conversion rate, measured by a founding-member test (one line in 2 issues linking to a waitlist; waitlist signups / D is the planning rate, an upper bound). No test yet: show the paid subscribers needed and "list needed: unknown until the test runs". Paid content: the topics with the best click rate over 3 or more issues are the candidates for paid extras; the free issue keeps its promise.
- **Affiliate placements:** revenue per issue = U × s × the program's conversion rate × commission per sale (from the program's terms or the user's affiliate dashboard; GA4 can't see the sale on the merchant's site). D needed = minimum deal / (CR × s × conversion × commission).
Recommend the options already met; the next one is the one with the smallest gap.
**Media kit,** written from the numbers above, never rounded up:
- Who reads it: the audience in the user's words, plus where newsletter readers come from when GA4 is connected and links carry this skill's tags (`utm_medium=email`):
```json
{"platform": "google-analytics", "action": "get_report", "workspace_id": "<WORKSPACE_ID>", "brand_id": "<BRAND_ID>", "property_id": "properties/<PROPERTY_ID>", "dimensions": ["country", "deviceCategory"], "metrics": ["sessions", "engagedSessions"], "start_date": "<START>", "end_date": "<END>", "dimensionFilter": {"filter": {"fieldName": "sessionMedium", "stringFilter": {"matchType": "EXACT", "value": "email"}}}, "limit": 50}
```
This counts clickers who reached the site, not every subscriber; say so.
- Reach and engagement: D, U and CR, with the number of issues and the date range behind them. Opens only if a sponsor asks, with the note that privacy features inflate them.
- What readers click: the topics with the most clicks from Step 3, when the history has them.
- Placements: where each sits, its length (a headline and up to 60 words for primary and secondary, one line for classified), one link each, an image only in primary.
- Rates and terms: the rate card, copy due a set number of working days before the send (the user's choice), the newsletter's right to refuse an off-audience sponsor (the Step 4 audience rule applies to sponsors too), and a report after each send of delivered and unique clicks on the sponsor's link (Mailchimp click details; with Klaviyo, the sponsor reads its own tagged link in its analytics).
- Past sponsors and testimonials only when the user supplies them; never invented.
**Disclosure.** Every paid placement carries a visible "Sponsored" label and every affiliate link a short disclosure, because the FTC expects a material connection to be clear to the reader.
## Report format
1. **Header:** newsletter, issue, window, mode, format and why, goal, which sources scored the posts.
2. **What was published:** the ranking table from Step 4, including the posts left out and why.
3. **What the history says:** Step 3's findings, or "not graded" with the reason.
4. **The issue:** subjects, preview, body, links, what's needed, send timing, the A/B test.
5. **Checks:** the Step 6 table.
6. **Extras the request asked for:** course outline, ideas, review grades, the cross-promotion plan, or the launch and sponsorship plan (angle with its evidence, promise, format, cadence arithmetic, platform, targets, 90-day dates, rate card with its inputs, the audience each revenue option needs, media kit, and every assumption labelled).
7. **What couldn't be checked,** and why.
## Drafts this skill can create
Only after the user approves the final copy and says which list to use. Each is a write through `execute_action` and needs a Read & Write connection; an owner, admin or operator can switch writes off. These create a **draft**. The skill never sends, schedules or sends a test.
| Platform | Steps | Body (key parts) |
|---|---|---|
| Klaviyo | 1. `create_email_template` | `{"data": {"type": "template", "attributes": {"name": "<ISSUE_NAME>", "editor_type": "CODE", "html": "<HTML>"}}}` |
| | 2. `create_campaign` (created as Draft) | `{"data": {"type": "campaign", "attributes": {"name": "<ISSUE_NAME>", "audiences": {"included": ["<LIST_ID>"]}, "campaign-messages": {"data": [{"type": "campaign-message", "attributes": {"definition": {"channel": "email", "label": "Main", "content": {"subject": "<SUBJECT>", "preview_text": "<PREVIEW>", "from_email": "<FROM_EMAIL>", "from_label": "<FROM_NAME>"}}}}]}}}}` |
| | 3. `assign_template_to_campaign_message` | `{"data": {"type": "campaign-message", "id": "<CAMPAIGN_MESSAGE_ID>", "relationships": {"template": {"data": {"type": "template", "id": "<TEMPLATE_ID>"}}}}}` |
| Mailchimp (untested until connected) | 1. `create_campaign` | `{"type": "regular", "recipients": {"list_id": "<LIST_ID>"}, "settings": {"subject_line": "<SUBJECT>", "preview_text": "<PREVIEW>", "title": "<ISSUE_NAME>", "from_name": "<FROM_NAME>", "reply_to": "<REPLY_TO>"}}` |
| | 2. `set_campaign_content` | `campaign_id` from step 1, `{"html": "<HTML>", "plain_text": "<TEXT>"}` |
Show the exact payloads, with the real list id and subject, before asking. After a write, read it back (`get_campaigns` with the Draft status, or `list_campaigns` with `"status": "save"`) and confirm it is a draft.
## Rules
- Pull before asking. Ask only for what no connected source holds.
- Every featured post has a role and a reason from Step 4. Every fact in the copy comes from a post read in this run.
- No invented numbers, results or testimonials. A story or example the user didn't give is labelled as a placeholder for them to fill.
- Opens are not a success measure; clicks, replies and unsubscribes are.
- History needs at least 3 sent issues and 1,000 delivered before it changes a pick, a subject style or the send slot.
- One format per issue, one primary call to action, 7 links or fewer.
- Name businesses, never private people: drop author bylines and personal names from posts unless the user is the author.
- Keep DataForSEO to about 12 calls a run.
- Sponsor prices come from the newsletter's own delivered and unique clicks and a stated value per click, never from an industry CPM. No price until the history gate is met; no media kit number rounded up; no invented sponsors or testimonials.
- Every sponsored placement is labelled "Sponsored" and every affiliate link disclosed.
- Never send, schedule or send a test. Drafts only, after a yes on the exact payload.
- If a call fails or a source isn't connected, say so in the report and keep going.
## Go deeper
- **email-campaign-analyst** (if installed) for a full campaign performance report.
- **email-sequence-builder** for welcome and nurture sequences.
- **content-repurposer** (if installed) to turn the lead post into social posts that point to the issue.
- **brand-voice** to pin down the voice before the first issue.
- **referral-program** to add a subscriber referral scheme once the launch plan is running.
- **pricing-strategy** to set the paid tier's price before the founding-member test.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# How to use: Newsletter
Hey Claude, I just added the "newsletter" skill. Write this month's newsletter from what we published last month, and tell me why you picked each post.
## What it needs
The InsightfulPipe MCP. It works with whatever is connected and says what it couldn't check:
- **GA4 and Search Console** to rank your posts by what people read and searched for.
- **Klaviyo or Mailchimp** to learn from past issues (clicks, subject styles, unsubscribes, send slot) and to save the finished issue as a draft.
- **No analytics connected?** With DataForSEO added, it works on any public blog: it reads the posts and ranks them on public search estimates (DataForSEO bills per call; a run uses up to about 12 calls). Or paste your post list and any numbers you have.
It asks only for what the data can't tell it: the newsletter's name, who reads it, what a reader should do next, and how often you send. If you don't know, it uses sensible defaults and says so.
## Example prompts
**This month's issue**
Hey Claude, I just added the "newsletter" skill. Write October's issue from our September blog posts. Our readers are small business owners, and the goal is clicks to the blog.
**Pick a format**
Hey Claude, I just added the "newsletter" skill. We're starting a weekly newsletter. Look at what we publish and what gets read, and recommend a format we can keep up.
**Ideas**
Hey Claude, I just added the "newsletter" skill. Give me 10 newsletter ideas backed by what our readers search for and click.
**Review a sent issue**
Hey Claude, I just added the "newsletter" skill. Review last week's newsletter in Klaviyo: what worked, what didn't, and three changes for the next one.
**Grow the list**
Hey Claude, I just added the "newsletter" skill. Plan cross-promotion for our newsletter: where on our site to ask for signups, and which newsletters in our niche we could swap mentions with.
**Email course**
Hey Claude, I just added the "newsletter" skill. Turn our posts on one topic into a 5-day email course.
**Start and monetize a newsletter**
Hey Claude, I just added the "newsletter" skill. Help me start a newsletter for our blog readers: the promise, format, cadence and platform, and when we could sell sponsor slots. Price a rate card from our last issues' clicks in Mailchimp and write the media kit.
## What you get
1. **A ranking of the month's posts:** each with its score, its role in the issue (lead, supporting, fresh pick, quick link, course, left out) and the reason.
2. **The issue:** three subject lines in different styles, preview text, the body in one of nine formats (curator, teacher, storyteller, roundup, analyst, behind the scenes, interview, contrarian, product update), tagged links, the images and fields still needed, send timing and one A/B test.
3. **Checks:** subject and preview length, facts traced to your posts, no invented numbers, link count and tagging, length, voice and mobile.
4. **Extras when you ask:** an email course outline, issue ideas with the evidence behind each, a review of a sent issue, a cross-promotion plan, or a launch and sponsorship plan: the topic angle from search demand, a cadence you can keep, a sponsor rate card priced from your own delivered and unique clicks, a media kit, and the audience a sponsor slot, a paid tier or affiliate links each need.
5. **What it couldn't check,** and why.
## What it can do for you
With your yes on the final copy and the list, it can save the issue as a **draft** campaign in Klaviyo or Mailchimp. It never sends, schedules or sends a test; you do that in your email platform.
## Tips
- Keep one format across issues; readers learn the shape.
- Give it two past issues you like. Voice matches much better.
- Judge issues on clicks and replies, not opens.
- Run it the first working day of each month, so the window is a full month.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
{
"note": "Real run on public data on 2026-10-06 through the InsightfulPipe MCP, on a neutral public topic: the September 2026 posts of a public company blog (blog.duolingo.com). The post list and dates come from the blog's public feed. Posts were scored with DataForSEO public search estimates and read with DataForSEO content parsing. No analytics or email platform for that blog is connected, so past-issue history is not graded. Author names are left out.",
"request": "Hey Claude, I just added the \"newsletter\" skill. Write October's newsletter for blog.duolingo.com readers from September's posts. The audience is people learning English and other languages. If a topic fits, outline an email course, and give me 3 ideas for the next issues.",
"newsletter": {
"name": "Monthly blog digest (sample)",
"audience": "people learning English and other languages",
"goal": "click to the lead post",
"cadence": "monthly",
"voice": "the blog's own"
},
"window": "2026-09-01 to 2026-09-30",
"sources": {
"post_list": "the blog's public RSS feed (15 items: 14 dated September, 1 dated October 1)",
"scores": "DataForSEO labs_ranked_keywords (estimated monthly US search visits per post)",
"page_reader": "DataForSEO onpage_content_parsing (crawler link-extractor, meta-tags-checker and headings-checker returned 'Error fetching URL')",
"google_analytics": "not connected for this blog",
"search_console": "not connected for this blog",
"email_platform": "none connected for this blog"
},
"data_pulled": [
"labs_ranked_keywords: 2 pages, 1,738 rows covering 11 of the 14 September posts (the other 3 have no ranking rows and score 0)",
"onpage_content_parsing: 10 posts (the lead, 3 supporting, the fresh pick and the 5 other course posts)",
"crawler link-extractor / meta-tags-checker / headings-checker: provider error on every URL"
],
"paid_calls": {
"dataforseo": 12,
"by_action": {
"labs_ranked_keywords": 2,
"onpage_content_parsing": 10
}
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
{
"header": {
"newsletter": "Monthly blog digest (sample)",
"issue": "October 2026",
"window": "2026-09-01 to 2026-09-30",
"mode": "issue + email course + ideas",
"format": "Curator",
"format_why": "Step 5 defaults, first match wins: the lead isn't a launch, and 5 on-audience topics have a score, so this is a digest. Curator applies even though English adjectives holds 85% of the score: the lead slot and the email course carry that topic, and the other 4 scored topics each get a line",
"goal": "click to the lead post",
"scored_by": "DataForSEO estimated monthly US search visits (current estimates, not September traffic): no GA4 or Search Console for this blog"
},
"what_was_published": {
"posts_dated_in_window": 14,
"on_audience": 11,
"left_out_off_audience": 3,
"dated_after_window": [
{
"date": "2026-10-01",
"title": "Practice hack: how to review previous lessons on Duolingo",
"note": "waits for the next issue"
}
],
"topic_scores": [
{
"topic": "English adjectives",
"posts": 6,
"est_monthly_search_visits": 3057.3
},
{
"topic": "Countries and nationalities in English",
"posts": 1,
"est_monthly_search_visits": 528.8
},
{
"topic": "English spelling",
"posts": 1,
"est_monthly_search_visits": 21.1
},
{
"topic": "Spanish for travel",
"posts": 1,
"est_monthly_search_visits": 3.9
},
{
"topic": "Italian",
"posts": 1,
"est_monthly_search_visits": 3.5
},
{
"topic": "Practising as an introvert",
"posts": 1,
"est_monthly_search_visits": 0
}
],
"ranking": [
{
"date": "2026-09-29",
"title": "120+ countries and nationalities in English",
"url": "https://blog.duolingo.com/where-are-you-from-in-english/",
"topic": "Countries and nationalities in English",
"est_monthly_search_visits": 528.8,
"ranking_phrases": 451,
"on_audience": true,
"role": "supporting",
"reason": "#2 topic by score"
},
{
"date": "2026-09-24",
"title": "Why is English spelling so tricky?",
"url": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/",
"topic": "English spelling",
"est_monthly_search_visits": 21.1,
"ranking_phrases": 34,
"on_audience": true,
"role": "supporting",
"reason": "#3 topic by score"
},
{
"date": "2026-09-22",
"title": "What is stalemate in chess?",
"url": "https://blog.duolingo.com/stalemate-in-chess/",
"topic": "Chess",
"est_monthly_search_visits": 0.1,
"ranking_phrases": 1,
"on_audience": false,
"role": "left out",
"reason": "a chess post; the newsletter is for language learners"
},
{
"date": "2026-09-17",
"title": "How much do you know about Italian?",
"url": "https://blog.duolingo.com/italian-fun-facts/",
"topic": "Italian",
"est_monthly_search_visits": 3.5,
"ranking_phrases": 8,
"on_audience": true,
"role": "quick link",
"reason": "#5 topic by score, after the 3 supporting slots"
},
{
"date": "2026-09-16",
"title": "5 things nobody told me about becoming an engineering leader",
"url": "https://blog.duolingo.com/engineering-leadership-lessons/",
"topic": "Engineering careers",
"est_monthly_search_visits": 0,
"ranking_phrases": 0,
"on_audience": false,
"role": "left out",
"reason": "a post about the company's engineering team, not for learners"
},
{
"date": "2026-09-15",
"title": "Dear Duolingo: How do I practice my language as an introvert?",
"url": "https://blog.duolingo.com/introvert-language-learning-tips/",
"topic": "Practising as an introvert",
"est_monthly_search_visits": 0,
"ranking_phrases": 0,
"on_audience": true,
"role": "fresh pick",
"reason": "on-audience, no search data yet, newest such post"
},
{
"date": "2026-09-10",
"title": "80+ most common adjectives in English",
"url": "https://blog.duolingo.com/adjectives-list/",
"topic": "English adjectives",
"est_monthly_search_visits": 2420.3,
"ranking_phrases": 797,
"on_audience": true,
"role": "lead",
"reason": "top topic (6 posts, 3,057.3 est. visits together); this is its best post"
},
{
"date": "2026-09-10",
"title": "What are gradable and non-gradable adjectives in English?",
"url": "https://blog.duolingo.com/gradable-adjectives/",
"topic": "English adjectives",
"est_monthly_search_visits": 10,
"ranking_phrases": 18,
"on_audience": true,
"role": "email course",
"reason": "same topic as the lead; becomes a lesson in the course the issue offers"
},
{
"date": "2026-09-10",
"title": "The hidden word order rules for English adjectives",
"url": "https://blog.duolingo.com/adjective-order/",
"topic": "English adjectives",
"est_monthly_search_visits": 74.4,
"ranking_phrases": 170,
"on_audience": true,
"role": "email course",
"reason": "same topic as the lead; becomes a lesson in the course the issue offers"
},
{
"date": "2026-09-10",
"title": "70+ descriptive adjectives in English",
"url": "https://blog.duolingo.com/types-of-descriptive-adjectives/",
"topic": "English adjectives",
"est_monthly_search_visits": 270.1,
"ranking_phrases": 135,
"on_audience": true,
"role": "email course",
"reason": "same topic as the lead; becomes a lesson in the course the issue offers"
},
{
"date": "2026-09-10",
"title": "“This,” “that,” “these,” and “those”: how to use English demonstrative adjectives",
"url": "https://blog.duolingo.com/what-are-demonstratives/",
"topic": "English adjectives",
"est_monthly_search_visits": 248.6,
"ranking_phrases": 74,
"on_audience": true,
"role": "email course",
"reason": "same topic as the lead; becomes a lesson in the course the issue offers"
},
{
"date": "2026-09-10",
"title": "English adjectives: how to use them and most common types",
"url": "https://blog.duolingo.com/kinds-of-adjectives/",
"topic": "English adjectives",
"est_monthly_search_visits": 33.8,
"ranking_phrases": 31,
"on_audience": true,
"role": "email course",
"reason": "same topic as the lead; becomes a lesson in the course the issue offers"
},
{
"date": "2026-09-08",
"title": "How we created Chess Game Review: What’s a key moment?",
"url": "https://blog.duolingo.com/engineering-game-review/",
"topic": "Chess",
"est_monthly_search_visits": 0,
"ranking_phrases": 0,
"on_audience": false,
"role": "left out",
"reason": "a chess post; the newsletter is for language learners"
},
{
"date": "2026-09-03",
"title": "30+ common Spanish phrases for your trip to Mexico",
"url": "https://blog.duolingo.com/spanish-phrases-for-travel/",
"topic": "Spanish for travel",
"est_monthly_search_visits": 3.9,
"ranking_phrases": 19,
"on_audience": true,
"role": "supporting",
"reason": "#4 topic by score"
}
],
"caution": "Several posts dated September already rank for many phrases (the lead for 797), so they are likely updated older guides. The feed date is used as published; scores are each page's current search estimate."
},
"history": {
"result": "not graded",
"why": "no Klaviyo or Mailchimp account is connected for this newsletter, so subject styles, topic clicks, fatigue and send slot use the defaults"
},
"issue": {
"subject_lines": [
{
"style": "specific",
"text": "80+ adjectives, 120+ countries, one silent k"
},
{
"style": "curiosity",
"text": "Why does “knight” spell a sound nobody says?"
},
{
"style": "direct value",
"text": "Describe anything in English this month"
}
],
"preview_text": "Plus a 6-day adjectives course, 30+ phrases for Mexico and practice tips for quiet learners.",
"body": [
{
"section": "Opening",
"text": "Hi [First name], September on the blog was all about describing things. Six guides took English adjectives apart from every angle, so we turned them into a short email course. Here are the reads worth your time."
},
{
"section": "Lead: 80+ most common adjectives in English",
"text": "The adjectives you’ll reach for most, grouped so they’re easy to learn. It also shows which adjectives count as “short” (one syllable, or two syllables ending in -y) and which count as “long”, which decides how you compare things.",
"link": "https://blog.duolingo.com/adjectives-list/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
},
{
"section": "Course offer: Adjectives in 6 days",
"text": "Prefer one small step a day? Join the 6-day adjectives course: one lesson and one practice task each morning.",
"link": "[course signup link]"
},
{
"section": "Also worth your time: 120+ countries and nationalities in English",
"text": "For most countries you can guess the nationality by adding -an or -ian (Italy, Italian). And nationalities always take a capital letter.",
"link": "https://blog.duolingo.com/where-are-you-from-in-english/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
},
{
"section": "Also worth your time: Why is English spelling so tricky?",
"text": "English spelling was set down in layers, and then the sounds kept moving. The Great Vowel Shift (15th to 18th centuries) changed how vowels sounded but not how they were written, and the k and gh in “knight” were once pronounced too.",
"link": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
},
{
"section": "Also worth your time: 30+ common Spanish phrases for your trip to Mexico",
"text": "Greet people with buenos días when you walk into a shop, and ask “¿Pica mucho?” before you order something spicy.",
"link": "https://blog.duolingo.com/spanish-phrases-for-travel/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
},
{
"section": "New and worth a look: Dear Duolingo on practising as an introvert",
"text": "Six tips (plus a bonus) for building your skills at your own pace, from writing first to talking to yourself and shadowing audio.",
"link": "https://blog.duolingo.com/introvert-language-learning-tips/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
},
{
"section": "Quick link",
"text": "How much do you know about Italian?",
"link": "https://blog.duolingo.com/italian-fun-facts/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
},
{
"section": "Sign-off",
"text": "Hit reply and tell us the English word you always misspell. [Name]"
}
],
"word_count": 221,
"links": [
"https://blog.duolingo.com/adjectives-list/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest",
"[course signup link]",
"https://blog.duolingo.com/where-are-you-from-in-english/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest",
"https://blog.duolingo.com/why-is-english-spelling-so-tricky/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest",
"https://blog.duolingo.com/spanish-phrases-for-travel/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest",
"https://blog.duolingo.com/introvert-language-learning-tips/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest",
"https://blog.duolingo.com/italian-fun-facts/?utm_source=newsletter&utm_medium=email&utm_campaign=2026-10-blog-digest"
],
"needed_to_finish": [
"images: one for the lead (alt text: 'A list of common English adjectives') and one per supporting item (alt text describing each)",
"personalisation: [First name], with 'there' as the fallback",
"the course signup link, once the course automation exists",
"the sender name in place of [Name]"
],
"send_timing": "keep your current day and hour: no send history was read",
"ab_test": {
"test": "subject A (specific) against subject B (curiosity), 50/50 on a test share of the list",
"judge_on": "click rate, not opens",
"keep": "the winner's style for next month's specific-vs-curiosity choice"
}
},
"checks": [
{
"check": "Subjects",
"result": "pass",
"detail": "3 styles; 44, 44, 39 characters"
},
{
"check": "Preview",
"result": "pass",
"detail": "92 characters; adds the course, the Mexico phrases and the introvert tips"
},
{
"check": "Facts",
"result": "pass",
"detail": "39 fact lines in the ledger (25 in the subjects, preview and issue body, 14 in the course), each matched to the post's text or feed title read in this run; the course offer and sign-off carry no post facts"
},
{
"check": "No invented numbers",
"result": "pass",
"detail": "every number in the copy (80+, 120+, 30+, 6 tips, 15th to 18th centuries) is in the posts; the 6-day course length is this skill's own outline"
},
{
"check": "Links",
"result": "pass",
"detail": "7 links; all post links tagged; primary call to action: read the lead post; the course is the one secondary offer, and its link is a placeholder you fill"
},
{
"check": "Length",
"result": "pass",
"detail": "221 words (Curator: 150 to 450)"
},
{
"check": "Voice",
"result": "pass",
"detail": "plain, friendly, second person, light on exclamation marks, like the posts"
},
{
"check": "Mobile",
"result": "pass",
"detail": "longest paragraph 42 words; single column"
}
],
"fact_ledger": [
{
"part": "subjects",
"line": "80+ adjectives",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post title in the feed",
"source_sentence": "80+ most common adjectives in English"
},
{
"part": "subjects",
"line": "120+ countries",
"post": "https://blog.duolingo.com/where-are-you-from-in-english/",
"source": "post title in the feed",
"source_sentence": "120+ countries and nationalities in English"
},
{
"part": "subjects",
"line": "one silent k / “knight” spells a sound nobody says",
"post": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/",
"source": "post text",
"source_sentence": "That’s because the “k” sound was not silent in Old English"
},
{
"part": "preview",
"line": "30+ phrases for Mexico",
"post": "https://blog.duolingo.com/spanish-phrases-for-travel/",
"source": "post title in the feed",
"source_sentence": "30+ common Spanish phrases for your trip to Mexico"
},
{
"part": "preview",
"line": "practice tips for quiet learners",
"post": "https://blog.duolingo.com/introvert-language-learning-tips/",
"source": "post title in the feed",
"source_sentence": "Dear Duolingo: How do I practice my language as an introvert?"
},
{
"part": "Opening",
"line": "Six guides took English adjectives apart from every angle",
"post": null,
"source": "this run's ranking",
"source_sentence": "6 posts dated September in the English adjectives topic (ranking table)"
},
{
"part": "Lead",
"line": "The adjectives you’ll reach for most, grouped so they’re easy to learn",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "Here are some of the most common ones, grouped into useful categories:"
},
{
"part": "Lead",
"line": "“short” (one syllable, or two syllables ending in -y)",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "Short adjectives are one-syllable words or two-syllable words that end in -y."
},
{
"part": "Lead",
"line": "and which count as “long”",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "Long adjectives are most other adjectives with two or more syllables."
},
{
"part": "Lead",
"line": "which decides how you compare things",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "How they are formed depends on the length of the adjective:"
},
{
"part": "Supporting 1",
"line": "you can guess the nationality by adding -an or -ian",
"post": "https://blog.duolingo.com/where-are-you-from-in-english/",
"source": "post text",
"source_sentence": "you can predict the word for their respective nationalities by adding"
},
{
"part": "Supporting 1",
"line": "(Italy, Italian)",
"post": "https://blog.duolingo.com/where-are-you-from-in-english/",
"source": "post text",
"source_sentence": "For example, the country Italy is associated with the nationality"
},
{
"part": "Supporting 1",
"line": "nationalities always take a capital letter",
"post": "https://blog.duolingo.com/where-are-you-from-in-english/",
"source": "post text",
"source_sentence": "Nationalities are always capitalized in English."
},
{
"part": "Supporting 2",
"line": "English spelling was set down in layers",
"post": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/",
"source": "post text",
"source_sentence": "the spelling conventions weren’t established all at once, but added on in layers."
},
{
"part": "Supporting 2",
"line": "the Great Vowel Shift (15th to 18th centuries)",
"post": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/",
"source": "post text",
"source_sentence": "the Great Vowel Shift that took place over the 15th-18th centuries"
},
{
"part": "Supporting 2",
"line": "changed how vowels sounded but not how they were written",
"post": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/",
"source": "post text",
"source_sentence": "During this period, the pronunciation of English vowels changed, but the way they were written down typically didn’t"
},
{
"part": "Supporting 2",
"line": "the k and gh in “knight” were once pronounced",
"post": "https://blog.duolingo.com/why-is-english-spelling-so-tricky/",
"source": "post text",
"source_sentence": "That’s because the “k” sound was not silent in Old English, and the letters “gh” used to represent a sound"
},
{
"part": "Supporting 3",
"line": "Greet people with buenos días when you walk into a shop",
"post": "https://blog.duolingo.com/spanish-phrases-for-travel/",
"source": "post text",
"source_sentence": "It’s considered polite to greet people with buenos días (good morning) or buenas tardes (good afternoon/good evening) when you enter stores, cafés, or souvenir shops."
},
{
"part": "Supporting 3",
"line": "ask “¿Pica mucho?” before you order something spicy",
"post": "https://blog.duolingo.com/spanish-phrases-for-travel/",
"source": "post text",
"source_sentence": "Remember to ask ¿Pica mucho? if you want to know if a dish is spicy."
},
{
"part": "Fresh pick",
"line": "Six tips (plus a bonus)",
"post": "https://blog.duolingo.com/introvert-language-learning-tips/",
"source": "post text",
"source_sentence": "6 language learning tips for introverts (plus a bonus tip!)"
},
{
"part": "Fresh pick",
"line": "for building your skills at your own pace",
"post": "https://blog.duolingo.com/introvert-language-learning-tips/",
"source": "post text",
"source_sentence": "Here are 6 tips for building your language skills at your own pace!"
},
{
"part": "Fresh pick",
"line": "writing first",
"post": "https://blog.duolingo.com/introvert-language-learning-tips/",
"source": "post text",
"source_sentence": "You might want to set speaking aside for the time being and focus on the other productive skill: writing."
},
{
"part": "Fresh pick",
"line": "talking to yourself",
"post": "https://blog.duolingo.com/introvert-language-learning-tips/",
"source": "post text",
"source_sentence": "Talk to yourself"
},
{
"part": "Fresh pick",
"line": "shadowing audio",
"post": "https://blog.duolingo.com/introvert-language-learning-tips/",
"source": "post text",
"source_sentence": "This technique involves listening to audio in your target language and repeating what you hear."
},
{
"part": "Quick link",
"line": "How much do you know about Italian?",
"post": "https://blog.duolingo.com/italian-fun-facts/",
"source": "post title in the feed",
"source_sentence": "How much do you know about Italian?"
},
{
"part": "Course day 1",
"line": "Some point (this, that)",
"post": "https://blog.duolingo.com/kinds-of-adjectives/",
"source": "post text",
"source_sentence": "English has four demonstrative adjectives: this, that, these, and those."
},
{
"part": "Course day 1",
"line": "some show ownership (my, your, his, her, its, our, their)",
"post": "https://blog.duolingo.com/kinds-of-adjectives/",
"source": "post text",
"source_sentence": "The possessive adjectives in English are: my, your, his, her, its, our, and their."
},
{
"part": "Course day 1",
"line": "some ask questions (which, what, whose)",
"post": "https://blog.duolingo.com/kinds-of-adjectives/",
"source": "post text",
"source_sentence": "In English, there are three interrogative adjectives: which, what, and whose."
},
{
"part": "Course day 2",
"line": "Learn the common adjectives in groups",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "Here are some of the most common ones, grouped into useful categories:"
},
{
"part": "Course day 2",
"line": "short (one syllable, or two ending in -y) and long",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "Short adjectives are one-syllable words or two-syllable words that end in -y."
},
{
"part": "Course day 2",
"line": "that decides how you compare them",
"post": "https://blog.duolingo.com/adjectives-list/",
"source": "post text",
"source_sentence": "How they are formed depends on the length of the adjective:"
},
{
"part": "Course day 3",
"line": "a descriptive adjective keeps the same form for one thing or many",
"post": "https://blog.duolingo.com/types-of-descriptive-adjectives/",
"source": "post text",
"source_sentence": "Unlike in some languages, descriptive adjectives generally do not change form in English."
},
{
"part": "Course day 3",
"line": "and for any gender",
"post": "https://blog.duolingo.com/types-of-descriptive-adjectives/",
"source": "post text",
"source_sentence": "They also do not change based on gender:"
},
{
"part": "Course day 4",
"line": "opinion, size, age, shape, color, origin, material, purpose",
"post": "https://blog.duolingo.com/kinds-of-adjectives/",
"source": "post text",
"source_sentence": "The typical order is: opinion, size, age, shape, color, origin, material, and purpose."
},
{
"part": "Course day 4",
"line": "“a delicious square cake”",
"post": "https://blog.duolingo.com/adjective-order/",
"source": "post text",
"source_sentence": "He made a delicious square cake."
},
{
"part": "Course day 5",
"line": "water can be a little cold or very cold",
"post": "https://blog.duolingo.com/gradable-adjectives/",
"source": "post text",
"source_sentence": "the water might be a little cold or very cold."
},
{
"part": "Course day 5",
"line": "you can’t be a little married",
"post": "https://blog.duolingo.com/gradable-adjectives/",
"source": "post text",
"source_sentence": "For example, a person cannot be a little married or very married."
},
{
"part": "Course day 6",
"line": "Four small words point at things",
"post": "https://blog.duolingo.com/what-are-demonstratives/",
"source": "post text",
"source_sentence": "In English, there are four demonstrative adjectives:"
},
{
"part": "Course day 6",
"line": "near or far, one or many",
"post": "https://blog.duolingo.com/what-are-demonstratives/",
"source": "post text",
"source_sentence": "the noun’s distance and whether it’s a singular or plural noun"
}
],
"email_course": {
"name": "Adjectives in 6 days",
"built_from": "the 6 posts on English adjectives dated September 2026",
"lessons": [
{
"day": 1,
"subject": "Day 1: the adjective families",
"post": "https://blog.duolingo.com/kinds-of-adjectives/",
"idea": "Adjectives do more than describe. Some point (this, that), some show ownership (my, your, his, her, its, our, their), some ask questions (which, what, whose). Today: meet the families so the rest of the week has a map. This course covers the most common adjectives, descriptive ones, word order, how strong an adjective can get, and this/that/these/those.",
"task": "Write one sentence that uses a describing adjective, a possessive one and a pointing one.",
"link": "https://blog.duolingo.com/kinds-of-adjectives/?utm_source=newsletter&utm_medium=email&utm_campaign=adjectives-course"
},
{
"day": 2,
"subject": "Day 2: the 80 you’ll use most",
"post": "https://blog.duolingo.com/adjectives-list/",
"idea": "A short list does most of the work. Learn the common adjectives in groups, and notice which are short (one syllable, or two ending in -y) and which are long: that decides how you compare them.",
"task": "Pick five adjectives from the list and sort them into short and long.",
"link": "https://blog.duolingo.com/adjectives-list/?utm_source=newsletter&utm_medium=email&utm_campaign=adjectives-course"
},
{
"day": 3,
"subject": "Day 3: adjectives that never change",
"post": "https://blog.duolingo.com/types-of-descriptive-adjectives/",
"idea": "In English, a descriptive adjective keeps the same form for one thing or many, and for any gender. One cold drink, two cold drinks.",
"task": "Describe three things in your room, then the same things in the plural, and check that the adjective stayed the same.",
"link": "https://blog.duolingo.com/types-of-descriptive-adjectives/?utm_source=newsletter&utm_medium=email&utm_campaign=adjectives-course"
},
{
"day": 4,
"subject": "Day 4: which adjective goes first?",
"post": "https://blog.duolingo.com/adjective-order/",
"idea": "Stacked adjectives follow an order: opinion, size, age, shape, color, origin, material, purpose. That’s why it’s “a delicious square cake”, not “a square delicious cake”.",
"task": "Describe your favourite mug with three adjectives in the right order.",
"link": "https://blog.duolingo.com/adjective-order/?utm_source=newsletter&utm_medium=email&utm_campaign=adjectives-course"
},
{
"day": 5,
"subject": "Day 5: a little cold or very married?",
"post": "https://blog.duolingo.com/gradable-adjectives/",
"idea": "Most adjectives come in degrees: water can be a little cold or very cold. Some don’t: you can’t be a little married. Knowing which is which keeps “very” where it belongs.",
"task": "Write two sentences with “very” that work, and one that doesn’t, and explain why.",
"link": "https://blog.duolingo.com/gradable-adjectives/?utm_source=newsletter&utm_medium=email&utm_campaign=adjectives-course"
},
{
"day": 6,
"subject": "Day 6: this, that, these, those",
"post": "https://blog.duolingo.com/what-are-demonstratives/",
"idea": "Four small words point at things: near or far, one or many. Use them to say exactly which thing you mean. That’s the course: reply and tell us which day helped most.",
"task": "Point at four objects around you and name each with the right word.",
"link": "https://blog.duolingo.com/what-are-demonstratives/?utm_source=newsletter&utm_medium=email&utm_campaign=adjectives-course"
}
]
},
"next_issue_ideas": {
"rule": "topics that didn't lead and aren't the course, ranked by each topic's highest-volume phrase where the blog ranks in the top 20",
"ideas": [
{
"topic": "Countries and nationalities in English",
"format": "Teacher",
"working_subject": "Where are you from? Say it right in English",
"angle": "a short lesson on nationality words, with the capital-letter rule and the -an / -ian pattern, ending in a 5-question quiz",
"evidence": {
"phrase": "nationalities",
"us_monthly_searches": 60500,
"blog_rank": 4,
"source": "DataForSEO labs_ranked_keywords"
}
},
{
"topic": "Italian",
"format": "Curator",
"working_subject": "5 things you didn’t know about Italian",
"angle": "a fun-facts issue built on the Italian post, ending with a short quiz",
"evidence": {
"phrase": "facts in italian",
"us_monthly_searches": 4400,
"blog_rank": 12,
"source": "DataForSEO labs_ranked_keywords"
}
},
{
"topic": "English spelling",
"format": "Storyteller",
"working_subject": "The silent letters English forgot to drop",
"angle": "the story of one word’s spelling, told through the layers the spelling post describes",
"evidence": {
"phrase": "how do you spell english",
"us_monthly_searches": 3600,
"blog_rank": 4,
"source": "DataForSEO labs_ranked_keywords"
}
}
]
},
"could_not_check": [
"Engaged sessions and search clicks per post: the blog's GA4 and Search Console aren't connected, so public estimates scored the posts.",
"Past-issue clicks, subject styles, fatigue and send slot: no email platform connected.",
"The crawler returned 'Error fetching URL' for every page; posts were read with DataForSEO content parsing instead.",
"3 of the 14 posts have no search data yet, so they score 0: 5 things nobody told me about becoming an engineering leader (left out); Dear Duolingo: How do I practice my language as an introvert? (fresh pick); How we created Chess Game Review: What’s a key moment? (left out)."
],
"drafts": "Not offered: no Klaviyo or Mailchimp account is connected for this newsletter. With one connected, the skill shows the draft payloads and saves a draft campaign only after a yes. It never sends."
}
ReadyNewsletter
MarkdownUTF-8