Substack API Scraper: Posts, Authors & Newsletters avatar

Substack API Scraper: Posts, Authors & Newsletters

Pricing

from $0.50 / 1,000 posts

Go to Apify Store
Substack API Scraper: Posts, Authors & Newsletters

Substack API Scraper: Posts, Authors & Newsletters

Read public Substack posts, publications, and comments in structured rows. Browse archives, search posts, discover publications by topic or category, and read public recommendations. Get titles, authors, dates, engagement, public previews, and quality notes without a Substack login or API key.

Pricing

from $0.50 / 1,000 posts

Rating

0.0

(0)

Developer

Maxime Dupré

Maxime Dupré

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

🧭 Public Substack data for research and archives

This Actor is for researchers, newsletter teams, analysts, and developers who need public Substack data. It returns structured post, publication, and comment rows with links, authors, dates, access status, engagement, discovery context, and quality notes. Use it to build a research table, check a publication, or collect a public post thread without manual copying.

🧾 See the Substack data you can use

Post rows hold public post identity, editorial fields, access status, author details, publication context, engagement, media, audio, and content when requested. Publication rows hold public identity, branding, setup details, and the category, topic, or recommendation value that led to the row. Comment rows hold public comment text, author details, time, engagement, depth, parent information, and post context.

The Actor reads public Substack surfaces. It does not need a Substack login or API key. Restricted posts keep public metadata and previews, while subscriber-only body content is not promised.

▶️ Choose a Substack task

How a run works

  1. Choose one target in the input form.
  2. Add the matching publication, post URL, category, topic, or post query.
  3. Add filters when you need a narrower set of posts.
  4. Turn on public article content only when you need HTML and readable text.
  5. Start the run, then open the dataset or the source-availability report.

Use one shared target and filter setup for each run. A list of same-kind publication targets is supported. Handles, Substack subdomain URLs, and supported custom-domain URLs can be used for publication targets.

⚙️ Input

Input fields

FieldTypeWhat it does
targetstringRequired. Choose publicationArchive, post, publicationDetails, categoryDiscovery, topicDiscovery, publicationRecommendations, publicationSearch, or postComments.
categorystringRequired for categoryDiscovery. Enter the category used by Substack's public discovery view.
rankingstringRequired for categoryDiscovery. Enter the ranking view used with the category.
topicstringRequired for topicDiscovery. Enter free text for the public publication search.
publicationTargetsarray of stringsAdd public publication handles, Substack subdomain URLs, or supported custom-domain URLs. Used by archive, details, recommendations, and publication search targets. For recommendations, each publication is the source.
postUrlsarray of objectsAdd canonical public post URLs for post retrieval or comment threads.
postUrls[].urlstringThe full canonical public post URL.
postQuerystringOptional for publicationArchive and required for publicationSearch. Use text from a post title or subtitle. Other targets ignore it.
dateFromstringOptional lower date bound for post targets. Use a UTC date in YYYY-MM-DD form.
dateTostringOptional upper date bound for post targets. Use a UTC date in YYYY-MM-DD form.
audiencestringOptional post filter. Choose all, free, or paid. Discovery and publication-details targets ignore it.
languagesarray of stringsOptional language filter for discovered publications and post results. Add language names or codes. Other targets ignore it.
postTypesarray of stringsOptional post type filter. Choose newsletter, podcast, thread, or video. Non-post targets ignore it.
authorsarray of stringsOptional post filter. Add author names or public handles. Non-post targets ignore it.
tagsarray of stringsOptional post filter. Add publication tag names. Non-post targets ignore it.
minReactionsintegerOptional minimum reaction count for post results. Non-post targets ignore it.
minCommentsintegerOptional minimum comment count for post results. Non-post targets ignore it.
minWordsintegerOptional minimum word count for post results. Non-post targets ignore it.
sortBystringOptional post order. Choose newest, oldest, popularity, engagement, or length. Targets that do not return posts ignore it.
includeArticleContentbooleanWhen true, fetch complete public article HTML and readable text when available. It applies to archive, post, and publication-search targets. Restricted posts still return public previews only.
maxItemsintegerOptional positive limit on saved rows. It can stop archive, discovery, search, and comment work early. Leave it empty to return all available results until the source is exhausted.

Default input

This is the complete public input from a successful current-beta default run:

{
"target": "publicationArchive",
"publicationTargets": [
"arxivblog"
],
"includeArticleContent": false
}

🧾 Output

Output links

FieldTypeWhat it does
resultsURLOpens the default dataset with successful post, publication, and comment rows.
sourceAvailabilityURLOpens the run report for unavailable sources and fetch failures.

Every dataset row has a resultType value. The value is post, publication, or comment. The tables below cover each shape.

Post rows

FieldTypeWhat it does
resultTypestringIdentifies this as a post row.
postobjectGroups post identity, content, publication, and engagement data.
post.idstringPublic post ID for joining or checking the source row, when available.
post.urlstringCanonical public post URL.
post.titlestringPublic post title.
post.descriptionstringPublic subtitle or description, when available.
post.publishedAtstringPost publication time.
post.postTypestringSource post type, such as newsletter, podcast, thread, or video.
post.accessStatusstringSays whether the post is public, paid, or otherwise restricted.
post.authorsarray of objectsPublic post byline details.
post.authors[]objectOne public post author.
post.authors[].namestringPublic author name.
post.authors[].handlestringPublic author handle, when available.
post.authors[].idstringPublic author ID, when available.
post.authors[].urlstringPublic author profile URL, when available.
post.publicationobjectPublication context for the post.
post.publication.idstringPublic publication ID, when available.
post.publication.namestringPublic publication name.
post.publication.handlestringPublic publication handle, when available.
post.publication.urlstringPublic publication URL.
post.publication.domainstringPublication domain, when available.
post.publication.descriptionstringPublic publication description, when available.
post.publication.authorsarray of objectsAvailable public publication authors.
post.publication.authors[]objectOne public publication author.
post.publication.authors[].namestringPublic publication author name.
post.publication.authors[].handlestringPublic publication author handle, when available.
post.publication.authors[].idstringPublic publication author ID, when available.
post.publication.authors[].urlstringPublic publication author profile URL, when available.
post.publication.categorystringPublication category, when available.
post.publication.languagestringPublication language or language code, when available.
post.publication.brandingobjectPublic publication branding, when available.
post.publication.branding.logoUrlstringPublic publication logo URL, when available.
post.publication.branding.coverImageUrlstringPublic publication cover image URL, when available.
post.publication.branding.accentColorstringPublication accent color, when available.
post.publication.setupobjectPublic publication setup details, when available.
post.publication.setup.subscriptionStatusstringPublic subscription status, when available.
post.publication.setup.hasFoundingPlanbooleanWhether a public founding plan is available, when shown.
post.publication.setup.hasCommunitybooleanWhether a public community is available, when shown.
post.publication.setup.createdAtstringPublication creation time, when available.
post.engagementobjectPublic post engagement counts and score, when available.
post.engagement.reactionCountintegerNumber of post reactions, when available.
post.engagement.commentCountintegerNumber of post comments, when available.
post.engagement.restackCountintegerNumber of post restacks, when available.
post.engagement.scorenumberAggregate source engagement measure, when available.
post.reactionBreakdownarray of objectsCount for each reaction type exposed by the source.
post.reactionBreakdown[]objectOne reaction type and count.
post.reactionBreakdown[].typestringReaction type.
post.reactionBreakdown[].countintegerCount for that reaction type.
post.wordCountintegerPost word count, when available.
post.languagestringPost language or language code, when available.
post.mediaobjectPublic cover and in-article image references, when available.
post.media.coverImageobjectCover image reference, when available.
post.media.coverImage.urlstringPublic cover image URL.
post.media.coverImage.altTextstringCover image alt text, when available.
post.media.coverImage.captionstringCover image caption, when available.
post.media.imagesarray of objectsIn-article image references, when available.
post.media.images[]objectOne in-article image reference.
post.media.images[].urlstringPublic in-article image URL.
post.media.images[].altTextstringImage alt text, when available.
post.media.images[].captionstringImage caption, when available.
post.audioobjectAudio details for an audio post, when available.
post.audio.urlstringPublic audio file URL.
post.audio.durationSecondsnumberAudio duration in seconds, when available.
post.contentobjectFull public article or public preview, when available.
post.content.htmlstringArticle HTML, when available.
post.content.textstringReadable article text, when available.
post.content.isCompletebooleanSays whether the content is the full public body instead of a preview.
qualityobjectConfidence and source-data warnings for the row.
quality.confidencestringConfidence level for the row fields.
quality.warningsarray of stringsNotes about missing or uncertain source data.
quality.warnings[]stringOne warning about missing or uncertain source data.

Current-beta post row

{
"resultType": "post",
"post": {
"url": "https://arxivblog.substack.com/p/next-generation-ai-attack-vectors",
"title": "Next generation AI attack vectors will be ideas, say Anthropic researchers",
"publishedAt": "2026-08-21T17:08:27.058Z",
"postType": "newsletter",
"accessStatus": "public",
"id": "212161880",
"description": "Computer scientists have bred self-propagating \"mind viruses\" that spread from one AI agent to the next through ordinary conversation — no hacking required",
"authors": [
{
"name": "Physics arXiv Blog",
"handle": "physicsarxivblog",
"id": "75337004"
}
],
"publication": {
"name": "Emerging Technology from the arXiv",
"url": "https://arxivblog.substack.com/",
"id": "5026881",
"handle": "arxivblog",
"domain": "arxivblog.substack.com",
"description": "Technology. Science. Insight.",
"authors": [
{
"name": "Physics arXiv Blog",
"handle": "physicsarxivblog",
"id": "75337004"
}
],
"language": "en",
"branding": {
"logoUrl": "https://substackcdn.com/image/fetch/$s_!-WgM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3743002d-f5ed-4304-9f23-701618b0b1d2_1280x1280.png",
"accentColor": "#FF6719"
},
"setup": {
"subscriptionStatus": "paid",
"hasFoundingPlan": true,
"hasCommunity": true,
"createdAt": "2025-05-15T12:12:29.439Z"
}
},
"engagement": {
"reactionCount": 30,
"commentCount": 0,
"restackCount": 13,
"score": 43
},
"reactionBreakdown": [
{
"type": "❤",
"count": 30
}
],
"wordCount": 1113,
"language": "en",
"media": {
"coverImage": {
"url": "https://substackcdn.com/image/fetch/$s_!jAvp!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F47f0a7f9-f2cd-4927-9bb6-539ad99de42d_550x665.png"
}
},
"audio": {
"url": "https://substack-video.s3.amazonaws.com/video_upload/post/212161880/tts/5cbb9c7b-74ce-4fe0-9b74-bd84b8e5cfde/en-GB-AdaMultilingualNeural.mp3"
}
},
"quality": {
"confidence": "high",
"warnings": []
}
}

Publication rows

FieldTypeWhat it does
resultTypestringIdentifies this as a publication row.
publicationobjectGroups public publication identity, context, branding, and setup data.
publication.idstringPublic publication ID, when available.
publication.namestringPublic publication name.
publication.handlestringPublic publication handle, when available.
publication.urlstringPublic publication URL.
publication.domainstringPublication domain, when available.
publication.descriptionstringPublic publication description, when available.
publication.authorsarray of objectsAvailable public publication authors.
publication.authors[]objectOne public publication author.
publication.authors[].namestringPublic author name.
publication.authors[].handlestringPublic author handle, when available.
publication.authors[].idstringPublic author ID, when available.
publication.authors[].urlstringPublic author profile URL, when available.
publication.categorystringPublication category, when available.
publication.languagestringPublication language or language code, when available.
publication.brandingobjectPublic publication branding, when available.
publication.branding.logoUrlstringPublic publication logo URL, when available.
publication.branding.coverImageUrlstringPublic publication cover image URL, when available.
publication.branding.accentColorstringPublication accent color, when available.
publication.setupobjectPublic publication setup details, when available.
publication.setup.subscriptionStatusstringPublic subscription status, when available.
publication.setup.hasFoundingPlanbooleanWhether a public founding plan is available, when shown.
publication.setup.hasCommunitybooleanWhether a public community is available, when shown.
publication.setup.createdAtstringPublication creation time, when available.
discoveryobjectThe category, topic, or publication value that produced the row, when available.
discovery.methodstringDiscovery method, such as category, topic, or recommendation.
discovery.valuestringSubmitted category, topic, handle, or URL that produced the row.
discovery.rankingstringCategory ranking view used for discovery, when applicable.
qualityobjectConfidence and source-data warnings for the row.
quality.confidencestringConfidence level for the row fields.
quality.warningsarray of stringsNotes about missing or uncertain source data.
quality.warnings[]stringOne warning about missing or uncertain source data.

Current-beta publication row

{
"resultType": "publication",
"publication": {
"name": "Emerging Technology from the arXiv",
"url": "https://arxivblog.substack.com/",
"id": "5026881",
"handle": "arxivblog",
"domain": "arxivblog.substack.com",
"description": "Technology. Science. Insight.",
"authors": [
{
"name": "Physics arXiv Blog",
"handle": "physicsarxivblog",
"id": "75337004"
}
],
"language": "en",
"branding": {
"logoUrl": "https://substackcdn.com/image/fetch/$s_!-WgM!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fsubstack-post-media.s3.amazonaws.com%2Fpublic%2Fimages%2F3743002d-f5ed-4304-9f23-701618b0b1d2_1280x1280.png",
"accentColor": "#FF6719"
},
"setup": {
"subscriptionStatus": "paid",
"hasFoundingPlan": true,
"hasCommunity": true,
"createdAt": "2025-05-15T12:12:29.439Z"
}
},
"quality": {
"confidence": "high",
"warnings": []
}
}

Comment rows

FieldTypeWhat it does
resultTypestringIdentifies this as a comment row.
commentobjectGroups comment text, author, time, engagement, and thread relationship data.
comment.idstringPublic comment ID, when available.
comment.bodystringPublic comment body.
comment.createdAtstringTime when the comment was posted.
comment.authorobjectPublic comment author details, when available.
comment.author.namestringPublic author name, when available.
comment.author.handlestringPublic author handle, when available.
comment.author.idstringPublic author ID, when available.
comment.author.urlstringPublic author profile URL, when available.
comment.engagementobjectPublic comment engagement counts and score, when available.
comment.engagement.reactionCountintegerNumber of comment reactions, when available.
comment.engagement.replyCountintegerNumber of direct replies, when available.
comment.engagement.scorenumberAggregate source comment engagement measure, when available.
comment.depthintegerComment depth in the thread. A root comment is 0.
comment.parentIdstringPublic parent comment ID, when this is a reply.
comment.postobjectPublic post that contains the comment.
comment.post.idstringPublic post ID, when available.
comment.post.titlestringPublic post title, when available.
comment.post.urlstringCanonical public post URL.
comment.post.publicationobjectPublication context for the commented post, when available.
comment.post.publication.idstringPublic publication ID, when available.
comment.post.publication.namestringPublic publication name.
comment.post.publication.handlestringPublic publication handle, when available.
comment.post.publication.urlstringPublic publication URL.
comment.post.publication.domainstringPublication domain, when available.
comment.post.publication.descriptionstringPublic publication description, when available.
comment.post.publication.authorsarray of objectsAvailable public publication authors.
comment.post.publication.authors[]objectOne public publication author.
comment.post.publication.authors[].namestringPublic author name.
comment.post.publication.authors[].handlestringPublic author handle, when available.
comment.post.publication.authors[].idstringPublic author ID, when available.
comment.post.publication.authors[].urlstringPublic author profile URL, when available.
comment.post.publication.categorystringPublication category, when available.
comment.post.publication.languagestringPublication language or language code, when available.
comment.post.publication.brandingobjectPublic publication branding, when available.
comment.post.publication.branding.logoUrlstringPublic publication logo URL, when available.
comment.post.publication.branding.coverImageUrlstringPublic publication cover image URL, when available.
comment.post.publication.branding.accentColorstringPublication accent color, when available.
comment.post.publication.setupobjectPublic publication setup details, when available.
comment.post.publication.setup.subscriptionStatusstringPublic subscription status, when available.
comment.post.publication.setup.hasFoundingPlanbooleanWhether a public founding plan is available, when shown.
comment.post.publication.setup.hasCommunitybooleanWhether a public community is available, when shown.
comment.post.publication.setup.createdAtstringPublication creation time, when available.
qualityobjectConfidence and source-data warnings for the row.
quality.confidencestringConfidence level for the row fields.
quality.warningsarray of stringsNotes about missing or uncertain source data.
quality.warnings[]stringOne warning about missing or uncertain source data.

Current-beta comment row

{
"resultType": "comment",
"comment": {
"body": "Yep! Spec decoding doesn't reduce the work, it just converts memory-bound idle time into tokens i.e. compute you'd already paid for.",
"createdAt": "2026-08-26T19:35:43.743Z",
"depth": 0,
"post": {
"url": "https://blog.bytebytego.com/p/how-to-make-llms-3x-faster",
"id": "212180385",
"title": "How to Make LLMs 3X Faster",
"publication": {
"name": "ByteByteGo Newsletter",
"url": "https://blog.bytebytego.com/",
"id": "817132",
"handle": "bytebytego",
"domain": "blog.bytebytego.com",
"description": "Explain complex systems with simple terms, from the authors of the best-selling system design book series. Join over 1,000,000 friendly readers.",
"authors": [
{
"name": "Alex Xu",
"handle": "bytebytego",
"id": "22329494"
},
{
"name": "Sahn Lam",
"handle": "sahnlam",
"id": "55391021"
},
{
"name": "ByteByteGo",
"handle": "bytebytego399569",
"id": "106455990"
}
],
"language": "en",
"branding": {
"logoUrl": "https://substackcdn.com/image/fetch/$s_!1eXV!,f_auto,q_auto:good,fl_progressive:steep/https%3A%2F%2Fbucketeer-e05bbc84-baa3-437e-9518-adb32be77984.s3.amazonaws.com%2Fpublic%2Fimages%2F8a5609ae-1239-4400-9491-6010a15c4d60_504x504.png",
"coverImageUrl": "https://substack-post-media.s3.amazonaws.com/public/images/a4e1c1bd-03ee-4126-b3e4-19553b2d2fc6_1279x821.png",
"accentColor": "#9D6FFF"
},
"setup": {
"subscriptionStatus": "paid",
"hasFoundingPlan": true,
"hasCommunity": true,
"createdAt": "2022-03-27T03:36:45.845Z"
}
}
},
"id": "323271360",
"author": {
"name": "Mitchell Kosowski",
"handle": "mitchellkosowski",
"id": "803879"
},
"engagement": {
"reactionCount": 0,
"replyCount": 0,
"score": 1
}
},
"quality": {
"confidence": "high",
"warnings": []
}
}

💳 Pricing

How billing works

Pricing is pay per event. An event is charged when the matching public row is saved. The exact rate depends on the event and the Apify plan tier.

EventCharge
substack-post-retrievedOne saved public post. The rates are $0.0018 on FREE, $0.0009 on BRONZE, $0.0007 on SILVER, $0.0005 on GOLD, $0.00035 on PLATINUM, and $0.00025 on DIAMOND.
substack-publication-retrievedOne saved public publication at $0.0018.
substack-comment-retrievedOne saved public comment at $0.0018.

Use filters and maxItems to limit the rows a run can save. Leaving maxItems empty returns all available results until the source is exhausted. This pricing explanation does not assume a charge for an empty or no-result run.

🔌 Integrations

Dataset access

Start the Actor in Apify Console or through the standard Actor API. Open the dataset after the run to review rows or export them in the formats provided by Apify.

Video guide

❓ FAQ

What happens with a paid or restricted post?

The Actor returns public identity, access status, metadata, and a public preview when the source provides one. It does not promise subscriber-only body content.

How do I search posts inside a publication?

Choose publicationSearch, add a publication target, and enter postQuery. The query uses text found in post titles or subtitles. You can also add the post filters that apply to the target.

How do I discover publications by topic or category?

Choose topicDiscovery and enter a topic, or choose categoryDiscovery and enter a category with its ranking view. You can also choose publicationRecommendations to read public recommendations from a publication target.

Can I retrieve one post by URL?

Yes. Choose post, add its canonical public URL to postUrls, and set any post filters you need.

Can I return all available rows?

Yes. Leave maxItems empty. The Actor continues until all available results are returned or the source is exhausted.

Can I read public comments?

Yes. Choose postComments and add one or more canonical public post URLs. Comment rows can include body, author, time, engagement, depth, and parent comment ID when the source provides them.

What if a source is unavailable?

Open the sourceAvailability report from the output. It provides a place to review unavailable sources and fetch failures separately from successful rows.

Can I use more than one publication target?

Yes. Add a list of same-kind public publication targets for archive, details, recommendations, or publication search work. The same filters apply to the whole run.

Do I need a Substack login or API key?

No. The Actor reads public Substack data without a login or API key. Public availability and source changes can still affect what a run returns.

How can I reduce the work in a run?

Use postQuery, date, language, audience, post type, author, tag, engagement, and word-count filters when they fit your target. Set maxItems when you need a smaller result set, and leave article content off unless you need the public body.

📝 Changelog

0.0: Initial release

🆘 Support

For issues, questions, or feature requests, file a ticket and I'll fix or implement it in less than 24h 🫡

Made with ❤️ by Maxime Dupré