+214 subscribers, Tuesday's issue opened by 52%
12,486 active subscribers, up 214 (1.7%) after unsubscribes. Tuesday's issue beat your average open rate by 3 points and click rate by 2.
Every Monday: beehiiv subscriber growth for last week, open and click rates for each issue you sent, the top post and where new readers came from.
Reads
You get
The card on the right is a sample. Yours shows your own numbers and updates in place every run.
What lands on your board
12,486 active subscribers, up 214 (1.7%) after unsubscribes. Tuesday's issue beat your average open rate by 3 points and click rate by 2.
The beehiiv dashboard is good at the publication view and at one post at a time. The weekly question a writer has, did the list grow and did this week's issues land better than usual, takes a few screens and some mental math.
The agent reads the publication's stats, the posts sent last week with their open and click rates, and the subscribers who joined, grouped by where they came from. It compares each issue with your average, so a 52% open rate reads as good or bad for your list, not in general.
GET https://api.beehiiv.com/v2/publications/{publicationId}?expand[]=stats returns active_subscriptions, average_open_rate and average_click_rate. Keep this week's active count to compare with next week's.
GET /v2/publications/{publicationId}/subscriptions?order_by=created&direction=desc&limit=100, following next_cursor until created is older than last Monday. Group the new ones by utm_source (or referring_site when it is empty).
GET /v2/publications/{publicationId}/posts?status=confirmed&order_by=publish_date&direction=desc&expand[]=stats&limit=10 and keep posts with publish_date in last week. From stats.email take recipients, open_rate, click_rate, unique_clicks and unsubscribes.
Net change in active subscribers, new subscribers by source, each post's open and click rate against the publication average, and the top post by click rate with its most clicked link from stats.clicks.
With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.
Pick your agent, where the data comes from and how to schedule it; the commands below follow.
One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.
shellcurl -fsSL https://briefkin.dev/skills/beehiiv-weekly-newsletter-stats/install | shAsk Claude Code:
promptRun the beehiiv-weekly-newsletter-stats skillOr paste the prompt instead of installing:
promptUsing the beehiiv API v2 with my key (read only), for publication <pub_id>: read the publication with expand[]=stats for active subscriptions and average open and click rates. Page through subscriptions ordered by created, newest first, and count those created since last Monday, grouped by utm_source (or referring_site). Read posts with status confirmed, ordered by publish_date descending, expand[]=stats, and keep those published last week; for each give recipients, open rate, click rate and unsubscribes. Report active subscribers and the change (if I give last week's count), new subscribers by source, each post against my average rates, and the top post by click rate, with one line on what to repeat.Mondays at 9:00, from cron on any machine where Claude Code is signed in:
crontab0 9 * * 1 claude -p "Run the beehiiv-weekly-newsletter-stats skill"Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.
Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works
SKILL.md---
name: beehiiv-weekly-newsletter-stats
description: "Every Monday: beehiiv subscriber growth for last week, open and click rates for each issue you sent, the top post and where new readers came from. Use when the user asks for this, or when it runs on a schedule."
---
# Beehiiv weekly newsletter stats
Every Monday: beehiiv subscriber growth for last week, open and click rates for each issue you sent, the top post and where new readers came from.
The beehiiv dashboard is good at the publication view and at one post at a time. The weekly question a writer has, did the list grow and did this week's issues land better than usual, takes a few screens and some mental math.
The agent reads the publication's stats, the posts sent last week with their open and click rates, and the subscribers who joined, grouped by where they came from. It compares each issue with your average, so a 52% open rate reads as good or bad for your list, not in general.
## Two ways to get the data
Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.
## Route A: API or MCP server
### What you need
- A beehiiv API key with read access to publications, posts and subscriptions in `BEEHIIV_API_KEY`, and the publication ID (it starts with `pub_`).
- A small file to keep last week's active subscriber count, for the net change.
If something is missing, say what and stop; do not invent numbers.
### Steps
1. **Read publication stats** (beehiiv): `GET https://api.beehiiv.com/v2/publications/{publicationId}?expand[]=stats` returns `active_subscriptions`, `average_open_rate` and `average_click_rate`. Keep this week's active count to compare with next week's.
2. **Count new subscribers** (beehiiv): `GET /v2/publications/{publicationId}/subscriptions?order_by=created&direction=desc&limit=100`, following `next_cursor` until `created` is older than last Monday. Group the new ones by `utm_source` (or `referring_site` when it is empty).
3. **Read last week's posts** (beehiiv): `GET /v2/publications/{publicationId}/posts?status=confirmed&order_by=publish_date&direction=desc&expand[]=stats&limit=10` and keep posts with `publish_date` in last week. From `stats.email` take `recipients`, `open_rate`, `click_rate`, `unique_clicks` and `unsubscribes`.
4. **Compare and report**: Net change in active subscribers, new subscribers by source, each post's open and click rate against the publication average, and the top post by click rate with its most clicked link from `stats.clicks`.
## Route B: the browser
### What you need
- Signed in to beehiiv as the publication owner or a workspace member with analytics access (Admin or Contributor with analytics permission). The person picks the publication first.
If something is missing, say what and stop; do not invent numbers.
### Steps
Start at https://app.beehiiv.com/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.
1. **Read the subscriber numbers**: Pick the publication in the top-left switcher. Open **Analytics** in the sidebar and the **Subscribers** report with the date range set to the last 7 days: active subscribers today, new subscribers and unsubscribes for the week, and the **Acquisition sources** breakdown of where new readers came from.
2. **Read last week's posts**: Open **Posts** and filter to **Published**. For each post sent last week open its **Analytics** tab and read recipients, open rate, click rate and unsubscribes, plus the **Clicks** table for the most clicked link.
3. **Get your averages**: On **Analytics** > **Posts** (or the publication dashboard), read the average open rate and click rate across all sends so each issue can be compared with your own list rather than a general benchmark.
4. **Report**: Active subscribers and the net change, new subscribers by source, each post against your average rates, the top post by click rate with its top link, and one line on what to repeat.
Note: Report names and tabs in the beehiiv dashboard change a few times a year; look for the Subscribers and Posts reports under Analytics if a label differs. The acquisition breakdown groups small sources into Other.
## The report
- **Active subscribers** and the net change.
- **New subscribers** by source.
- **Each issue sent** last week: recipients, open rate, click rate, unsubscribes, against your average.
- **Top post** by click rate.
- One line on what to repeat.
## Post it to Briefkin
When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.
```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
-H "authorization: Bearer $BRIEFKIN_TOKEN" \
-H "content-type: application/json" \
-d @- <<'JSON'
{
"v": 1,
"event_id": "beehiiv-weekly-newsletter-stats/<date of this run, e.g. 2026-10-16>",
"item_key": "beehiiv-weekly-newsletter-stats",
"project": "Acme Weekly",
"source": "Beehiiv weekly newsletter stats skill",
"kind": "update",
"title": "+214 subscribers, Tuesday's issue opened by 52%",
"summary": "**12,486** active subscribers, up **214** (1.7%) after unsubscribes. Tuesday's issue beat your average open rate by 3 points and click rate by 2.",
"widget": [
{
"type": "Grid",
"props": {
"columns": 3
},
"children": [
{
"type": "Stat",
"props": {
"label": "Active subscribers",
"value": 12486,
"delta": 1.7
}
},
{
"type": "Stat",
"props": {
"label": "Average open rate",
"value": 49,
"unit": "%"
}
},
{
"type": "Stat",
"props": {
"label": "Average click rate",
"value": 6.2,
"unit": "%"
}
}
]
},
{
"type": "Table",
"props": {
"columns": [
"Post",
"Recipients",
"Opens",
"Clicks",
"Unsubs"
],
"align": [
"left",
"right",
"right",
"right",
"right"
],
"rows": [
[
"Tuesday: The pricing page teardown",
"12,301",
"52%",
"8.2%",
14
],
[
"Friday: Five tools I stopped paying for",
"12,388",
"47%",
"5.1%",
21
]
]
}
},
{
"type": "Bars",
"props": {
"unit": "new subscribers",
"items": [
{
"label": "Recommendations",
"value": 118
},
{
"label": "twitter",
"value": 71
},
{
"label": "Website form",
"value": 49
},
{
"label": "Referral program",
"value": 11
}
]
}
}
]
}
JSON
```
Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.
## Run it on a schedule
Suggested: Mondays at 9:00 (`0 9 * * 1`). From cron, with the agent signed in on that machine:
```bash
0 9 * * 1 claude -p "Run the beehiiv-weekly-newsletter-stats skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```
Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/beehiiv-weekly-newsletter-stats#schedule
Source: https://briefkin.dev/skills/beehiiv-weekly-newsletter-stats
A beehiiv API key with read access to publications, posts and subscriptions in BEEHIIV_API_KEY, and the publication ID (it starts with pub_).
A small file to keep last week's active subscriber count, for the net change.
https://mcp.beehiiv.com/mcp. In beehiiv, open Settings > MCP, pick your client (beehiiv has guides for Claude, Claude Code, Cursor and Codex) and grant access when asked. It is available on every plan: free plans are read-only, and paid plans add write tools for content, segments and automations, though it can't publish, schedule or send posts. To connect a second workspace, add a parameter such as ?account=2 to the URL (docs).BEEHIIV_API_KEY with BEEHIIV_PUBLICATION_ID (it starts with pub_), and send it as a Bearer token.The endpoints this report reads need only posts:read, subscriptions:read and publications:read. On a paid plan the MCP connection can edit drafts and segments, so keep it for interactive work and use a read-only key for scheduled runs.
Less than they were: Apple Mail Privacy Protection opens every email it downloads, which inflates opens. Compare open rates with your own average rather than other newsletters, and lean on click rate, which privacy features do not inflate in the same way, for what actually worked.
The publication stats give today's active count, not a history. Saving it each Monday gives the exact net change; without the file, the agent counts new subscribers from the subscriptions list and subtracts the unsubscribes reported on last week's posts, which is close but misses unsubscribes from older posts.
No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.
Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.
Yes. Switch the data source to "Your browser" and the steps change to the beehiiv pages themselves: the agent opens app.beehiiv.com in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.
Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.
Free during the open beta. No card.