Newsletter to Markdown (Substack, Ghost, beehiiv)
Pricing
from $3.00 / 1,000 full-text posts
Newsletter to Markdown (Substack, Ghost, beehiiv)
Export Substack, Ghost and beehiiv newsletter archives as clean Markdown with YAML front matter: title, authors, date, tags, paywall flag, word count. Built for LLM wikis, RAG and research. Only public content; paywalled posts return the free preview. Pay per post.
Pricing
from $3.00 / 1,000 full-text posts
Rating
0.0
(0)
Developer
Vellum Kasane
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
2 days ago
Last modified
Categories
Share
Export a Substack, Ghost or beehiiv newsletter archive as clean, LLM-ready Markdown. Give the Actor a newsletter URL (custom domains work) and it returns one record per post: title, subtitle, authors, publish date, tags, paywall flag, word count, and the post body as GitHub-flavoured Markdown, plus a ready-to-save .md file with YAML front matter. Useful for RAG, LLM wikis, Obsidian vaults, research and competitive monitoring.
Price: $0.002 per full-text post, $0.0005 per metadata-only / paywalled post, $0.005 per run. 1,000 free posts cost about $2.
Example output (one item, shortened):
{"platform": "substack","publication_name": "Simon Willison’s Newsletter","url": "https://simonw.substack.com/p/conceptual-integrity-and-counting","title": "Conceptual integrity and counting lines of code","subtitle": "Plus Bun 1.4 and the latest on Anthropic’s revenue","authors": ["Simon Willison"],"published": "2026-08-23T20:57:32.675Z","tags": ["anthropic", "llms", "ai"],"audience": "free","paywalled": false,"word_count": 3116,"content_markdown": "In this newsletter:\n\n- Conceptual integrity and counting lines of code\n...","markdown_file": "---\ntitle: \"Conceptual integrity and counting lines of code\"\n...\n---\n\n# Conceptual integrity ...","full_text": true}
What does Newsletter to Markdown do?
- One Actor, three platforms. The platform is detected from the home page (Substack, Ghost, beehiiv), including publications on their own domain. Anything else falls back to the site's
sitemap.xmlor RSS feed. - The whole archive, not just the feed. RSS feeds usually hold the last 10–20 posts. This Actor lists posts from the Substack archive API and from sitemaps on Ghost and beehiiv, newest first, so you can export hundreds of posts in one run.
- Clean Markdown. Post bodies are converted with headings, lists, links, images, code blocks and tables kept; subscribe boxes, share bars and footers are removed.
- Front matter included.
markdown_fileis a complete Markdown document (title, publication, authors, dates, tags, paywall flag, content hash) you can save straight into an Obsidian vault, a Claude Code / LLM wikiraw/folder or a vector index. - Honest about paywalls. Only public content is exported. Paid posts are flagged
paywalled: trueand contain the free preview, billed at the cheaper metadata price. - New posts only, on a schedule. Set a State key and scheduled runs return only posts not exported before.
Who is it for
- RAG and LLM pipelines that need newsletter posts as clean text with reliable metadata.
- Researchers and analysts following industry newsletters (AI, product, finance, policy) who want a searchable local archive.
- Knowledge-base builders pushing new posts into Obsidian, Notion or a Claude Code wiki every week (n8n, Make, Zapier via Apify integrations).
- AI agents using the Apify MCP server: call the Actor with a newsletter URL and read the Markdown from the dataset.
How to export a newsletter to Markdown
- Paste one or more newsletter URLs into Newsletter URLs (e.g.
https://simonw.substack.com,https://www.platformer.news,https://www.superhuman.ai). - Set Max posts per newsletter (5 for a quick test, 500+ for a full archive).
- Optional: Only posts from the last N days, and a State key for scheduled runs.
- Click Start. Download the dataset as JSON, CSV, Excel or HTML, or use the Markdown files view.
Input
| Field | Type | Default | Notes |
|---|---|---|---|
publications | string[] | required | Newsletter home page URLs. Custom domains and bare hosts are accepted. |
maxPostsPerPublication | integer | 50 | Newest posts kept per newsletter after filtering and dedupe. Caps cost. |
fetchContent | boolean | true | Convert post bodies to Markdown. Off = metadata only (cheaper event). |
sinceDays | integer | 0 | 0 = no date filter. |
platform | string | auto | Force substack, ghost, beehiiv or other if auto-detection is wrong. |
stateKey | string | "" | Named key-value store that remembers exported posts between runs. |
respectRobotsTxt | boolean | true | Skip URLs disallowed by the newsletter's robots.txt. |
maxConcurrency | integer | 3 | Parallel page requests (Substack API calls are limited to 2 in parallel). |
proxyConfiguration | object | no proxy | Enable Apify Proxy only if a site blocks you. |
Example input:
{"publications": ["https://simonw.substack.com", "https://www.platformer.news", "https://www.superhuman.ai"],"maxPostsPerPublication": 5}
Output
One dataset item per post. Main fields:
| Field | Description |
|---|---|
platform | substack, ghost, beehiiv or other |
publication_name, publication_url | Newsletter name and origin |
url, slug, title, subtitle | Post identity |
authors, published, updated, tags | Metadata (Substack: bylines and post tags; Ghost/beehiiv: page meta tags) |
audience, paywalled | free / paid / unknown, and whether only the preview was available |
content_markdown, word_count | Post body as Markdown |
markdown_file | Front matter + title + body, ready to save as <slug>.md |
content_hash, url_hash | SHA-256 for change detection and dedupe |
likes, comments | Substack reaction and comment counts |
full_text | True when the full public body was exported (billed as post-full-text) |
extraction_error | Why the body could not be exported, if anything went wrong |
A run summary (posts per newsletter, detected platform, source used, skipped posts) is saved as SUMMARY.json in the key-value store.
How much does it cost to export a newsletter?
Pay per event, no subscription:
| Event | Price | When |
|---|---|---|
| Actor start | $0.005 | Once per run |
post-full-text | $0.002 | A free post exported with its full body as Markdown |
post-metadata | $0.0005 | Metadata only (fetchContent off), or a paywalled post's public preview |
Examples: 50 recent posts from one newsletter ≈ $0.105; a 1,000-post archive ≈ $2.005. Posts skipped by the date filter or the state key are never charged. Set a maximum cost per run in the run options and the Actor stops cleanly when it is reached.
Tips
- Weekly digest: schedule the Actor with
sinceDays: 8and astateKey, then send the dataset to Slack, Notion or your wiki with an Apify integration. - Full archive: set
maxPostsPerPublicationto the archive size. Substack is paged through its archive API; Ghost and beehiiv use the sitemap, sorted by last modification. - Only the metadata (for a list of posts and dates): turn off
fetchContent. - Save files: use the
markdown_filefield and theslugas the file name.
Limits and fair use
- Only public content is exported. The Actor does not log in and does not bypass paywalls; paid posts return the preview the publisher shows to everyone.
- robots.txt is respected by default and requests are rate-limited (Substack API: 2 in parallel with a short pause).
- Newsletter posts are copyrighted by their authors. Use the output for personal research, analysis and indexing, and check the publisher's terms before republishing.
- Substack custom domains that hide their platform markers can be forced with
platform: "substack".
Verified
Tested on 2026-09-23 with the example input: 15 posts (Substack 5, Ghost 5, beehiiv 5), 0 failures, about 10 seconds. Paywalled Ghost posts were flagged and billed as metadata.
Changelog
- 0.1 (2026-09-23): first release — Substack archive API, Ghost and beehiiv sitemaps, RSS fallback, paywall flag, front matter, dedupe across runs.
Support
Found a newsletter that does not export correctly? Open an issue in the Issues tab with the URL; we reply within one business day. Need a custom export (other platforms, scheduled delivery)? Mention it in the issue.