Buttondown Newsletter Scraper
Pricing
from $2.70 / 1,000 newsletter posts
Buttondown Newsletter Scraper
Read public Buttondown newsletter archives, posts, and profiles into structured dataset rows. Filter posts by date or keyword, fetch a public post by URL, and add HTML and readable content when available.
Pricing
from $2.70 / 1,000 newsletter posts
Rating
0.0
(0)
Developer
Maxime Dupré
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
10 days ago
Last modified
Categories
Share
📰 Turn Buttondown newsletters into usable rows
Researchers, newsletter teams, and developers can read one public Buttondown newsletter per run and get structured post or newsletterProfile rows in an Apify dataset. Use archive filters, a post URL, or a newsletter slug or URL to bring public content, dates, metadata, and source links into a dataset you can inspect or export.
- Read a public newsletter profile and its links with Buttondown Newsletter Profile.
- Fetch one public post from its URL with Buttondown Post Scraper.
- Collect public archive posts from one newsletter with Buttondown Newsletter Archive.
- Review post dates and metadata with Buttondown Newsletter Scraper.
- Save public source data as dataset rows with Buttondown Scraper.
🧾 Buttondown data for research
Post rows
Post rows include the public title, summary, publication time, language, and source URL. When the page provides them, rows also include source HTML, readable content, update time, access status, author, section, and social-card data.
Newsletter profile rows
Profile rows include the public newsletter name, description, language, icon, website, archive URL, and configured social links when available.
The Actor reads public Buttondown pages for one newsletter or one public post at a time. It does not send or edit newsletters, manage subscriptions, access private content, or combine several independent newsletter searches in one run.
▶️ Run a public Buttondown lookup
Choose one result type per run:
archivePostsreads public posts from the newsletter archive.postByUrlreads one public post frompostUrl.newsletterProfilereads public newsletter details fromnewsletter.
For archive posts, add date or keyword filters and an optional limit. Leaving the limit empty returns all available archive posts until the source is exhausted. Only content the source exposes publicly is included. Private, subscriber-only, and paid-only content that is not public is outside the Actor's scope.
⚙️ Input
Input fields
| Field | Type | What it does |
|---|---|---|
resultType | string | Required. Selects archivePosts, postByUrl, or newsletterProfile. |
startDate | date string | For archive posts, keeps posts published on or after this UTC date. |
endDate | date string | For archive posts, keeps posts published on or before this UTC date. |
keyword | string | For archive posts, keeps posts whose title or summary contains this keyword without case sensitivity. |
maxItems | integer | For archive posts, stops after this many posts. Leaving it empty returns all available archive posts until the source is exhausted. |
postUrl | URL string | The full public Buttondown post URL used with postByUrl. |
newsletter | string | The Buttondown newsletter slug or full public newsletter URL used with archivePosts or newsletterProfile. Leave it empty for postByUrl. |
Successful default input
This example is copied from the public input of a successful current-beta default-input run:
{"resultType": "archivePosts","maxItems": 17,"newsletter": "buttondown"}
🧾 Output
Output link
| Field | Type | What it does |
|---|---|---|
dataset | URL | Opens the Apify dataset with the post and newsletter profile rows. |
Every dataset row has a resultType value. Optional fields can be absent when the public source does not provide them.
Post rows
| Field | Type | What it does |
|---|---|---|
resultType | string | Always post for this shape. |
title | string | The title published for the post. |
summary | string | The summary published for the post. |
publishedAt | date-time string | The date and time when the post was published. |
language | string | The language reported for the post. |
url | URL | The public URL of the post. |
bodyHtml | string | The post body in the source HTML format, when available. |
readableContent | string | A readable version of the post content, when available. |
updatedAt | date-time string | The date and time when the post was last updated, when reported. |
accessStatus | string | The reported access status, free or paid, when available. |
author | string | The author name reported for the post, when available. |
section | string | The section reported for the post, when available. |
socialCard | object | Social-card information reported for the post, when available. |
socialCard.title | string | The title used by the post's social card, when available. |
socialCard.description | string | The description used by the post's social card, when available. |
socialCard.imageUrl | URL | The image URL used by the post's social card, when available. |
Genuine post row
This complete row came from the successful current-beta default-input run. It is not shortened.
{"resultType": "post","title": "commenting_mode replaces is_comments_disabled","summary": "Emails get a three-valued commenting mode instead of a boolean","publishedAt": "2024-12-30T00:00:00.000Z","language": "en-US","url": "https://buttondown.com/blog/api-commenting-mode","bodyHtml": "<p><strong>Breaking change</strong>: we've unshipped the <code>is_comments_disabled</code> field from <a href=\"https://docs.buttondown.com/api-emails-introduction\">emails</a>, and replaced it with a more flexible <a href=\"https://docs.buttondown.com/api-emails-commenting-mode\"><code>commenting_mode</code></a> field.</p><p>The <code>commenting_mode</code> field is now a string that can be one of the following values:</p><ul><li><code>\"enabled\"</code>: comments are enabled</li><li><code>\"disabled\"</code>: comments are disabled</li><li><code>\"enabled_for_paid_subscribers\"</code>: comments are enabled, but only for paid subscribers</li></ul>","readableContent": "Breaking change: we've unshipped the is_comments_disabled field from emails, and replaced it with a more flexible commenting_mode field. The commenting_mode field is now a string that can be one of the following values: \"enabled\": comments are enabled \"disabled\": comments are disabled \"enabled_for_paid_subscribers\": comments are enabled, but only for paid subscribers","updatedAt": "2024-12-30T00:00:00.000Z","author": "Buttondown Team","section": "Technology","socialCard": {"title": "commenting_mode replaces is_comments_disabled","description": "Emails get a three-valued commenting mode instead of a boolean","imageUrl": "https://marketing.buttondown.com/og/generic?title=commenting_mode+replaces+is_comments_disabled&date=December+30%2C+2024&category=changelog"}}
Newsletter profile rows
| Field | Type | What it does |
|---|---|---|
resultType | string | Always newsletterProfile for this shape. |
name | string | The public name of the newsletter. |
description | string | The public newsletter description, when available. |
language | string | The language reported for the newsletter. |
iconUrl | URL | The public URL of the newsletter icon, when available. |
websiteUrl | URL | The public website URL of the newsletter. |
archiveUrl | URL | The public archive URL of the newsletter. |
socialLinks | array of objects | Configured public social links for the newsletter, when available. |
socialLinks[].platform | string | The social platform named by the newsletter. |
socialLinks[].url | URL | The public URL for the social account. |
Genuine newsletter profile row
This complete row came from a successful current-beta newsletter profile run. It is not shortened.
{"resultType": "newsletterProfile","name": "Buttondown","description": "Monthly updates about new features, updates, and exciting stuff from the folks who run Buttondown. No spam, no ads, no nonsense. Well, maybe some nonsense. (But fun nonsense, like corgi photos.)","language": "en","iconUrl": "https://assets.buttondown.email/icons/ef795794-c837-4b31-99a9-97e0fd90bd6d.png","websiteUrl": "https://buttondown.com/buttondown","archiveUrl": "https://buttondown.com/buttondown/archive","socialLinks": [{"platform": "github","url": "https://github.com/buttondown"},{"platform": "bsky","url": "https://bsky.app/profile/buttondown.com"},{"platform": "threads","url": "https://threads.com/@buttondownemail"},{"platform": "x","url": "https://x.com/buttondown"},{"platform": "mastodon","url": "https://mastodon.social/@buttondown"},{"platform": "facebook","url": "https://facebook.com/buttondown.email"},{"platform": "linkedin","url": "https://www.linkedin.com/company/buttondown"}]}
💳 Pricing
Pricing is pay per event. A newsletter post charge covers one saved public newsletter post with available metadata and its source link. A newsletter profile charge covers one saved public newsletter profile with available identity and public-link information. Current tier prices are shown on the Store page.
🔌 Integrations
Dataset access
Open the dataset in Apify Console, read it through the Apify API, or export the rows in the formats supported by Apify.
❓ FAQ
Can I fetch one public post by URL?
Yes. Set resultType to postByUrl and enter one full public Buttondown post URL in postUrl.
Can I enter a newsletter slug or a full URL?
Yes. For archivePosts or newsletterProfile, enter the Buttondown slug or full public newsletter URL in newsletter.
Can I read the newsletter profile instead of posts?
Yes. Set resultType to newsletterProfile. The profile row can include the name, description, language, icon, website, archive URL, and configured social links.
Can I get source HTML and readable content?
Post rows include bodyHtml and readableContent when the public page provides them. The HTML preserves the source body, while readable content is a plain version when available.
How do the date and keyword filters work?
startDate keeps archive posts published on or after its UTC date, and endDate keeps posts published on or before its UTC date. keyword keeps archive posts whose title or summary contains the text without case sensitivity.
What does leaving Maximum posts empty do?
It returns all available archive posts until the source is exhausted. A nonempty value stops after that many posts, but the source may have fewer matching posts.
Does this include private or paid-only content?
The Actor reads only content the source exposes publicly. It does not bypass private, subscriber-only, or paid-only pages that are not public. A post can include the source's accessStatus when that value is reported.
Can I combine several newsletter searches in one run?
No. Use one newsletter archive or profile target per run, or one post URL for postByUrl. Start another run for a different target.
📝 Changelog
v0.0 (21-09-2026)
- Initial release.
🆘 Support
For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡
🔗 Related Actors
- Substack API Scraper: Posts, Authors & Newsletters reads public Substack posts, publications, and comments for cross-platform newsletter research.
- RSS Feed Reader parses public RSS, Atom, and JSON Feed URLs into feed-item rows for newsletter and blog feeds.
- Substack Notes Scraper collects public Substack Notes for topic and author context around newsletter research.
- Substack Recommendations maps public recommendation links between newsletters.
- Medium Articles Scraper collects public Medium article metadata and optional text when research extends beyond Buttondown.
Made with ❤️ by Maxime Dupré