{
  "data": {
    "id": "izi31evru0SmgKMn3",
    "actId": "n7xofJAWyJUILJ0N1",
    "userId": "NL4ThgItAwaoBlffQ",
    "startedAt": "2026-10-25T14:15:15.035Z",
    "finishedAt": "2026-10-25T14:15:30.894Z",
    "status": "SUCCEEDED",
    "meta": {
      "origin": "CLI"
    },
    "stats": {
      "durationMillis": 15784,
      "runTimeSecs": 15.784,
      "computeUnits": 0.017537777777777777,
      "imageSizeBytes": 356486144
    },
    "options": {
      "useCache": true,
      "betaPackages": false,
      "memoryMbytes": 4096,
      "diskMbytes": 8192
    },
    "createdByOrganizationMemberUserId": "zifX0mkAFMHe8CatY",
    "exitCode": 0,
    "inputSchema": "{\n  \"title\": \"Substack Scraper Input\",\n  \"description\": \"Export custom-domain Substack publications and post URLs, with an RSS fallback for non-Substack sites.\",\n  \"type\": \"object\",\n  \"schemaVersion\": 1,\n  \"properties\": {\n    \"mode\": {\n      \"title\": \"Mode\",\n      \"type\": \"string\",\n      \"description\": \"What to scrape. substack.com-hosted inputs are reported as blocked_egress.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"publicationPosts\",\n        \"postUrls\"\n      ],\n      \"enumTitles\": [\n        \"Publication posts (archive)\",\n        \"Specific post URLs\"\n      ],\n      \"default\": \"publicationPosts\",\n      \"prefill\": \"publicationPosts\"\n    },\n    \"publications\": {\n      \"title\": \"Publications\",\n      \"type\": \"array\",\n      \"description\": \"(mode=publicationPosts) Custom-domain publication URLs or RSS-capable sites, e.g. `https://www.slowboring.com` or `https://platformer.news`. Bare subdomains and substack.com links are blocked from this actor's cloud network.\",\n      \"editor\": \"stringList\",\n      \"default\": [\n        \"platformer.news\"\n      ],\n      \"prefill\": [\n        \"platformer.news\"\n      ]\n    },\n    \"postUrls\": {\n      \"title\": \"Post URLs\",\n      \"type\": \"array\",\n      \"description\": \"(mode=postUrls) Custom-domain post URLs, e.g. `https://www.noahpinion.blog/p/the-internet-breaks`. substack.com share links are reported as blocked_egress.\",\n      \"editor\": \"stringList\",\n      \"default\": [],\n      \"prefill\": []\n    },\n    \"sortBy\": {\n      \"title\": \"Sort order\",\n      \"type\": \"string\",\n      \"description\": \"(mode=publicationPosts) Newest first or all-time most popular first.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"newest\",\n        \"top\"\n      ],\n      \"enumTitles\": [\n        \"Newest first\",\n        \"Most popular\"\n      ],\n      \"default\": \"newest\",\n      \"prefill\": \"newest\"\n    },\n    \"publishedAfter\": {\n      \"title\": \"Published after\",\n      \"type\": \"string\",\n      \"description\": \"Keep posts published on or after this date (`YYYY-MM-DD`).\",\n      \"editor\": \"textfield\"\n    },\n    \"publishedBefore\": {\n      \"title\": \"Published before\",\n      \"type\": \"string\",\n      \"description\": \"Keep posts published on or before this date (`YYYY-MM-DD`).\",\n      \"editor\": \"textfield\"\n    },\n    \"containsKeyword\": {\n      \"title\": \"Contains keyword\",\n      \"type\": \"string\",\n      \"description\": \"(mode=publicationPosts) Keep posts whose title, teaser or text contains this keyword. Uses Substack's publication search when possible.\",\n      \"editor\": \"textfield\"\n    },\n    \"tagsAnyOf\": {\n      \"title\": \"Tags\",\n      \"type\": \"array\",\n      \"description\": \"Keep posts carrying at least one of these tags (case-insensitive).\",\n      \"editor\": \"stringList\",\n      \"default\": [],\n      \"prefill\": []\n    },\n    \"audienceFilter\": {\n      \"title\": \"Free or paid\",\n      \"type\": \"string\",\n      \"description\": \"Keep all posts, only free posts, or only paid posts.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"all\",\n        \"free\",\n        \"paid\"\n      ],\n      \"enumTitles\": [\n        \"All posts\",\n        \"Free posts only\",\n        \"Paid posts only\"\n      ],\n      \"default\": \"all\",\n      \"prefill\": \"all\"\n    },\n    \"postType\": {\n      \"title\": \"Post type\",\n      \"type\": \"string\",\n      \"description\": \"Keep all post types or a single type.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"all\",\n        \"newsletter\",\n        \"podcast\",\n        \"thread\"\n      ],\n      \"enumTitles\": [\n        \"All types\",\n        \"Newsletter\",\n        \"Podcast\",\n        \"Thread\"\n      ],\n      \"default\": \"all\",\n      \"prefill\": \"all\"\n    },\n    \"mediaFilter\": {\n      \"title\": \"Media\",\n      \"type\": \"string\",\n      \"description\": \"Keep all posts, audio posts, video posts, or text-only posts.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"any\",\n        \"audio\",\n        \"video\",\n        \"text\"\n      ],\n      \"enumTitles\": [\n        \"Any media\",\n        \"With audio\",\n        \"With video\",\n        \"Text only\"\n      ],\n      \"default\": \"any\",\n      \"prefill\": \"any\"\n    },\n    \"bodyFormat\": {\n      \"title\": \"Post body\",\n      \"type\": \"string\",\n      \"description\": \"Body fields to include. `none` is fastest; `all` adds HTML, plain text and Markdown.\",\n      \"editor\": \"select\",\n      \"enum\": [\n        \"none\",\n        \"html\",\n        \"text\",\n        \"markdown\",\n        \"all\"\n      ],\n      \"enumTitles\": [\n        \"No body\",\n        \"HTML\",\n        \"Plain text\",\n        \"Markdown\",\n        \"HTML + text + Markdown\"\n      ],\n      \"default\": \"all\",\n      \"prefill\": \"none\"\n    },\n    \"includePaidPreview\": {\n      \"title\": \"Include paid post preview\",\n      \"type\": \"boolean\",\n      \"description\": \"For paid posts, include the public preview body and flag it as a preview. Turn off for faster metadata-only runs.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"includeComments\": {\n      \"title\": \"Include comments\",\n      \"type\": \"boolean\",\n      \"description\": \"Include public comment threads for free posts. Paid-post comments are members-only.\",\n      \"default\": false,\n      \"prefill\": false\n    },\n    \"maxCommentsPerPost\": {\n      \"title\": \"Max comments per post\",\n      \"type\": \"integer\",\n      \"description\": \"Cap on comments per post, including replies. Set to 0 for no limit.\",\n      \"minimum\": 0,\n      \"maximum\": 5000,\n      \"default\": 20,\n      \"prefill\": 20\n    },\n    \"includePublicationInfo\": {\n      \"title\": \"Include publication info\",\n      \"type\": \"boolean\",\n      \"description\": \"Add publication details such as pricing plans, sections, language and payment status.\",\n      \"default\": true,\n      \"prefill\": false\n    },\n    \"maxItems\": {\n      \"title\": \"Max items\",\n      \"type\": \"integer\",\n      \"description\": \"Hard cap on emitted records.\",\n      \"minimum\": 1,\n      \"maximum\": 10000,\n      \"default\": 50,\n      \"prefill\": 3\n    },\n    \"maxPostsPerPublication\": {\n      \"title\": \"Max posts per publication\",\n      \"type\": \"integer\",\n      \"description\": \"Optional per-publication cap. Set to 0 for no per-publication limit.\",\n      \"minimum\": 0,\n      \"maximum\": 10000,\n      \"default\": 0,\n      \"prefill\": 3\n    }\n  }\n}",
    "readme": "# Substack Publication Post Exporter\n\nTurn a Substack publication's public archive into a clean dataset, or fetch individual posts you already know. Custom-domain newsletters work directly; publications that still live on `*.substack.com` are reported as a clear `blocked_egress` status row instead of a misleading empty result. Free posts arrive with full HTML, readable text and Markdown; paid posts arrive with metadata and a clearly flagged public teaser. No account, login or proxy setup.\n\n## What this actor does\n\n- **Two modes:** export a publication's archive (`publicationPosts`) or fetch specific post URLs (`postUrls`).\n- **Full archive depth:** walk a custom-domain publication from its newest post back through its history, 50 posts at a time.\n- **Free posts in full:** HTML, plain text and clean Markdown for every free post.\n- **Paid posts, honestly:** title, subtitle, author, date, cover, word count, reactions, comments count and the public teaser. The public preview body is optional and flagged with `contentIsPreview`.\n- **Comments:** nested public comment threads for free posts.\n- **Publication details:** name, domain, language, payment status, subscription plans and sections.\n- **Filters:** date range, keyword, tags, free/paid, post type and audio/video presence.\n- **RSS fallback:** non-Substack sites such as Platformer are read through their public feed (up to 20 recent items).\n- **Blocked inputs are visible:** `substack.com`, `*.substack.com` and share links produce a `blocked_egress` row that explains the limitation and the workaround.\n- **Empty fields are omitted:** a post without a subtitle, tag or video simply has no such key.\n\n## Output per post\n\n- `id`, `slug`, `title`, `subtitle`, `url`, `guid` — identity and canonical link\n- `publishedAt`, `publishedAtRaw`, `updatedAt` — ISO date plus the original source value\n- `author`, `authors[]` — primary byline and every byline with name, handle, bio, photo and Twitter\n- `publication`, `publicationUrl`, `publicationInfo` — newsletter name/link, plus plans and sections when enabled\n- `audience`, `isPaid`, `contentAccess`, `contentIsPreview`, `shouldSendFreePreview`, `freeUnlockRequired` — access state\n- `bodyHtml`, `bodyText`, `bodyMarkdown` — body in the requested formats; paid bodies are previews only\n- `summary`, `truncatedBodyText`, `description` — plain excerpt, source teaser and source description\n- `wordCount` (words in the delivered body), `articleWordCount` (full article count from the source), `readingTimeMinutes`\n- `language`, `postType` — language code and `newsletter` / `podcast` / `thread`\n- `coverImage`, `audioUrl`, `podcastUrl`, `podcastDurationSec` — image and audio\n- `videoUrl`, `videoThumbnailUrl`, `videoDurationSec`, `videoWidth`, `videoHeight`, `videoIsPreview` — video details\n- `tags`, `tagSlugs`, `categories`, `sectionId`, `sectionName` — taxonomy; `categories` is kept for older integrations\n- `reactionCount`, `reactions`, `commentCount`, `childCommentCount`, `restacks` — engagement\n- `comments[]` — nested public comments when enabled, with author, date, reactions and replies\n- `dataSource`, `recordType` (`post`), `scrapedAt`\n\n## Blocked input row\n\nWhen an input is hosted on `substack.com` (a bare subdomain, a `substack.com/@handle`, or a share link), the actor emits one row with `recordType: \"blocked_egress\"`, the original `input`, `host`, a plain-language `message` and a `workaround`. This is a limitation of this actor's cloud network, not an empty publication. Use the publication's custom domain or an RSS-capable site instead.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `mode` | string | `publicationPosts` | `publicationPosts` or `postUrls` |\n| `publications` | array | `[\"platformer.news\"]` | Custom-domain publication URLs or RSS-capable sites (mode=publicationPosts) |\n| `postUrls` | array | – | Custom-domain post URLs (mode=postUrls) |\n| `sortBy` | string | `newest` | `newest` or `top` for publication posts |\n| `publishedAfter` | string | – | Keep posts on or after `YYYY-MM-DD` |\n| `publishedBefore` | string | – | Keep posts on or before `YYYY-MM-DD` |\n| `containsKeyword` | string | – | Keep posts whose title, teaser or text contains this keyword |\n| `tagsAnyOf` | array | – | Keep posts with at least one matching tag |\n| `audienceFilter` | string | `all` | `all`, `free` or `paid` |\n| `postType` | string | `all` | `all`, `newsletter`, `podcast` or `thread` |\n| `mediaFilter` | string | `any` | `any`, `audio`, `video` or `text` |\n| `bodyFormat` | string | `all` | `none`, `html`, `text`, `markdown` or `all` |\n| `includePaidPreview` | boolean | `true` | Include the flagged public preview of paid posts |\n| `includeComments` | boolean | `false` | Include public comment threads for free posts |\n| `maxCommentsPerPost` | integer | `20` | Comment cap per post, replies included; `0` means no limit |\n| `includePublicationInfo` | boolean | `true` | Add plans, sections and publication metadata |\n| `maxItems` | integer | `50` | Hard cap on records (1–10,000) |\n| `maxPostsPerPublication` | integer | `0` | Per-publication cap; `0` means no per-publication limit |\n\n### Example: a custom-domain publication with full bodies\n\n```json\n{\n  \"mode\": \"publicationPosts\",\n  \"publications\": [\"https://www.slowboring.com\"],\n  \"maxItems\": 25,\n  \"bodyFormat\": \"all\"\n}\n```\n\n### Example: paid and free posts in a date range\n\n```json\n{\n  \"mode\": \"publicationPosts\",\n  \"publications\": [\"https://www.noahpinion.blog\"],\n  \"publishedAfter\": \"2026-01-01\",\n  \"audienceFilter\": \"all\",\n  \"includePaidPreview\": true,\n  \"maxItems\": 100\n}\n```\n\n### Example: specific custom-domain post URLs\n\n```json\n{\n  \"mode\": \"postUrls\",\n  \"postUrls\": [\n    \"https://www.noahpinion.blog/p/the-internet-breaks\",\n    \"https://www.slowboring.com/p/destroying-womens-sports-in-order\"\n  ],\n  \"bodyFormat\": \"markdown\",\n  \"includeComments\": true\n}\n```\n\n### Example: RSS fallback for a site that left Substack\n\n```json\n{\n  \"mode\": \"publicationPosts\",\n  \"publications\": [\"platformer.news\"],\n  \"maxItems\": 10,\n  \"bodyFormat\": \"text\"\n}\n```\n\n## Use cases\n\n- **Newsletter monitoring** — follow competitor or industry publications without checking each site.\n- **Research and NLP** — export free-post text or Markdown for topic models, search indexes and RAG stores.\n- **Content archives** — keep a searchable copy of a public archive and its free comments.\n- **Media analysis** — track themes, posting cadence, reactions and discussion across newsletters.\n- **Feed consolidation** — merge several custom-domain publications, or an RSS site, into one dataset.\n\n## FAQ\n\n**Do I need a Substack account, cookies or a proxy?**\nNo. The actor reads public custom-domain pages and posts. There is no login step and no proxy setup.\n\n**Which publications work?**\nAny publication served from its own custom domain, plus non-Substack sites with a public RSS feed. Bare `*.substack.com` addresses and `substack.com` share links do not work from this actor's cloud network.\n\n**What is a `blocked_egress` row?**\nIt is a status record that tells you the input is hosted on `substack.com` and cannot be read from this actor's cloud network. It includes the original input, the host, a plain-language message and a workaround. It is not an empty publication.\n\n**Can I download paid posts in full?**\nNo. Paid posts are protected. The actor returns their metadata, the public teaser and, when `includePaidPreview` is on, the public preview body with `contentIsPreview: true`. It never bypasses a paywall.\n\n**How far back does the archive go?**\nAs far as a custom-domain publication's public archive goes — not just the latest page. The RSS fallback returns up to 20 recent items.\n\n**Why are comments missing on some posts?**\nPublic comment threads are available for free posts. Comments on paid posts are members-only, so the actor returns the comment count but not the thread.\n\n**Can I get Markdown for AI or RAG pipelines?**\nYes. Choose `markdown` or `all` in `bodyFormat`. Free posts get clean Markdown with subscribe buttons, share widgets and image wrappers removed. Paid posts get the flagged public preview only.\n\n**Why is a field absent from some records?**\nEmpty values are omitted rather than written as `null`. A post without a subtitle, tag, video or public subscriber count simply does not include that key.\n\n**Do custom domains work the same as a `.substack.com` address?**\nUse the custom domain itself, such as `https://www.slowboring.com` or `https://www.noahpinion.blog`. The `.substack.com` address is reported as `blocked_egress`.\n\n**Is this affiliated with Substack?**\nNo. This is an independent third-party actor that reads publicly available newsletter data. It is not affiliated with or endorsed by Substack.\n",
    "actorDefinition": {
      "actorSpecification": 1,
      "name": "substack-publication-post-exporter",
      "title": "Substack Publication Post Exporter",
      "description": "Export custom-domain Substack publications and post URLs: full archive, free-post HTML/text/Markdown, paid teasers, comments and RSS fallback. substack.com-hosted inputs are reported as blocked from cloud egress.",
      "version": "1.1",
      "buildTag": "latest",
      "dockerfile": "./Dockerfile",
      "readme": "# Substack Publication Post Exporter\n\nTurn a Substack publication's public archive into a clean dataset, or fetch individual posts you already know. Custom-domain newsletters work directly; publications that still live on `*.substack.com` are reported as a clear `blocked_egress` status row instead of a misleading empty result. Free posts arrive with full HTML, readable text and Markdown; paid posts arrive with metadata and a clearly flagged public teaser. No account, login or proxy setup.\n\n## What this actor does\n\n- **Two modes:** export a publication's archive (`publicationPosts`) or fetch specific post URLs (`postUrls`).\n- **Full archive depth:** walk a custom-domain publication from its newest post back through its history, 50 posts at a time.\n- **Free posts in full:** HTML, plain text and clean Markdown for every free post.\n- **Paid posts, honestly:** title, subtitle, author, date, cover, word count, reactions, comments count and the public teaser. The public preview body is optional and flagged with `contentIsPreview`.\n- **Comments:** nested public comment threads for free posts.\n- **Publication details:** name, domain, language, payment status, subscription plans and sections.\n- **Filters:** date range, keyword, tags, free/paid, post type and audio/video presence.\n- **RSS fallback:** non-Substack sites such as Platformer are read through their public feed (up to 20 recent items).\n- **Blocked inputs are visible:** `substack.com`, `*.substack.com` and share links produce a `blocked_egress` row that explains the limitation and the workaround.\n- **Empty fields are omitted:** a post without a subtitle, tag or video simply has no such key.\n\n## Output per post\n\n- `id`, `slug`, `title`, `subtitle`, `url`, `guid` — identity and canonical link\n- `publishedAt`, `publishedAtRaw`, `updatedAt` — ISO date plus the original source value\n- `author`, `authors[]` — primary byline and every byline with name, handle, bio, photo and Twitter\n- `publication`, `publicationUrl`, `publicationInfo` — newsletter name/link, plus plans and sections when enabled\n- `audience`, `isPaid`, `contentAccess`, `contentIsPreview`, `shouldSendFreePreview`, `freeUnlockRequired` — access state\n- `bodyHtml`, `bodyText`, `bodyMarkdown` — body in the requested formats; paid bodies are previews only\n- `summary`, `truncatedBodyText`, `description` — plain excerpt, source teaser and source description\n- `wordCount` (words in the delivered body), `articleWordCount` (full article count from the source), `readingTimeMinutes`\n- `language`, `postType` — language code and `newsletter` / `podcast` / `thread`\n- `coverImage`, `audioUrl`, `podcastUrl`, `podcastDurationSec` — image and audio\n- `videoUrl`, `videoThumbnailUrl`, `videoDurationSec`, `videoWidth`, `videoHeight`, `videoIsPreview` — video details\n- `tags`, `tagSlugs`, `categories`, `sectionId`, `sectionName` — taxonomy; `categories` is kept for older integrations\n- `reactionCount`, `reactions`, `commentCount`, `childCommentCount`, `restacks` — engagement\n- `comments[]` — nested public comments when enabled, with author, date, reactions and replies\n- `dataSource`, `recordType` (`post`), `scrapedAt`\n\n## Blocked input row\n\nWhen an input is hosted on `substack.com` (a bare subdomain, a `substack.com/@handle`, or a share link), the actor emits one row with `recordType: \"blocked_egress\"`, the original `input`, `host`, a plain-language `message` and a `workaround`. This is a limitation of this actor's cloud network, not an empty publication. Use the publication's custom domain or an RSS-capable site instead.\n\n## Input\n\n| Field | Type | Default | Description |\n|---|---|---|---|\n| `mode` | string | `publicationPosts` | `publicationPosts` or `postUrls` |\n| `publications` | array | `[\"platformer.news\"]` | Custom-domain publication URLs or RSS-capable sites (mode=publicationPosts) |\n| `postUrls` | array | – | Custom-domain post URLs (mode=postUrls) |\n| `sortBy` | string | `newest` | `newest` or `top` for publication posts |\n| `publishedAfter` | string | – | Keep posts on or after `YYYY-MM-DD` |\n| `publishedBefore` | string | – | Keep posts on or before `YYYY-MM-DD` |\n| `containsKeyword` | string | – | Keep posts whose title, teaser or text contains this keyword |\n| `tagsAnyOf` | array | – | Keep posts with at least one matching tag |\n| `audienceFilter` | string | `all` | `all`, `free` or `paid` |\n| `postType` | string | `all` | `all`, `newsletter`, `podcast` or `thread` |\n| `mediaFilter` | string | `any` | `any`, `audio`, `video` or `text` |\n| `bodyFormat` | string | `all` | `none`, `html`, `text`, `markdown` or `all` |\n| `includePaidPreview` | boolean | `true` | Include the flagged public preview of paid posts |\n| `includeComments` | boolean | `false` | Include public comment threads for free posts |\n| `maxCommentsPerPost` | integer | `20` | Comment cap per post, replies included; `0` means no limit |\n| `includePublicationInfo` | boolean | `true` | Add plans, sections and publication metadata |\n| `maxItems` | integer | `50` | Hard cap on records (1–10,000) |\n| `maxPostsPerPublication` | integer | `0` | Per-publication cap; `0` means no per-publication limit |\n\n### Example: a custom-domain publication with full bodies\n\n```json\n{\n  \"mode\": \"publicationPosts\",\n  \"publications\": [\"https://www.slowboring.com\"],\n  \"maxItems\": 25,\n  \"bodyFormat\": \"all\"\n}\n```\n\n### Example: paid and free posts in a date range\n\n```json\n{\n  \"mode\": \"publicationPosts\",\n  \"publications\": [\"https://www.noahpinion.blog\"],\n  \"publishedAfter\": \"2026-01-01\",\n  \"audienceFilter\": \"all\",\n  \"includePaidPreview\": true,\n  \"maxItems\": 100\n}\n```\n\n### Example: specific custom-domain post URLs\n\n```json\n{\n  \"mode\": \"postUrls\",\n  \"postUrls\": [\n    \"https://www.noahpinion.blog/p/the-internet-breaks\",\n    \"https://www.slowboring.com/p/destroying-womens-sports-in-order\"\n  ],\n  \"bodyFormat\": \"markdown\",\n  \"includeComments\": true\n}\n```\n\n### Example: RSS fallback for a site that left Substack\n\n```json\n{\n  \"mode\": \"publicationPosts\",\n  \"publications\": [\"platformer.news\"],\n  \"maxItems\": 10,\n  \"bodyFormat\": \"text\"\n}\n```\n\n## Use cases\n\n- **Newsletter monitoring** — follow competitor or industry publications without checking each site.\n- **Research and NLP** — export free-post text or Markdown for topic models, search indexes and RAG stores.\n- **Content archives** — keep a searchable copy of a public archive and its free comments.\n- **Media analysis** — track themes, posting cadence, reactions and discussion across newsletters.\n- **Feed consolidation** — merge several custom-domain publications, or an RSS site, into one dataset.\n\n## FAQ\n\n**Do I need a Substack account, cookies or a proxy?**\nNo. The actor reads public custom-domain pages and posts. There is no login step and no proxy setup.\n\n**Which publications work?**\nAny publication served from its own custom domain, plus non-Substack sites with a public RSS feed. Bare `*.substack.com` addresses and `substack.com` share links do not work from this actor's cloud network.\n\n**What is a `blocked_egress` row?**\nIt is a status record that tells you the input is hosted on `substack.com` and cannot be read from this actor's cloud network. It includes the original input, the host, a plain-language message and a workaround. It is not an empty publication.\n\n**Can I download paid posts in full?**\nNo. Paid posts are protected. The actor returns their metadata, the public teaser and, when `includePaidPreview` is on, the public preview body with `contentIsPreview: true`. It never bypasses a paywall.\n\n**How far back does the archive go?**\nAs far as a custom-domain publication's public archive goes — not just the latest page. The RSS fallback returns up to 20 recent items.\n\n**Why are comments missing on some posts?**\nPublic comment threads are available for free posts. Comments on paid posts are members-only, so the actor returns the comment count but not the thread.\n\n**Can I get Markdown for AI or RAG pipelines?**\nYes. Choose `markdown` or `all` in `bodyFormat`. Free posts get clean Markdown with subscribe buttons, share widgets and image wrappers removed. Paid posts get the flagged public preview only.\n\n**Why is a field absent from some records?**\nEmpty values are omitted rather than written as `null`. A post without a subtitle, tag, video or public subscriber count simply does not include that key.\n\n**Do custom domains work the same as a `.substack.com` address?**\nUse the custom domain itself, such as `https://www.slowboring.com` or `https://www.noahpinion.blog`. The `.substack.com` address is reported as `blocked_egress`.\n\n**Is this affiliated with Substack?**\nNo. This is an independent third-party actor that reads publicly available newsletter data. It is not affiliated with or endorsed by Substack.\n",
      "input": {
        "title": "Substack Scraper Input",
        "description": "Export custom-domain Substack publications and post URLs, with an RSS fallback for non-Substack sites.",
        "type": "object",
        "schemaVersion": 1,
        "properties": {
          "mode": {
            "title": "Mode",
            "type": "string",
            "description": "What to scrape. substack.com-hosted inputs are reported as blocked_egress.",
            "editor": "select",
            "enum": [
              "publicationPosts",
              "postUrls"
            ],
            "enumTitles": [
              "Publication posts (archive)",
              "Specific post URLs"
            ],
            "default": "publicationPosts",
            "prefill": "publicationPosts"
          },
          "publications": {
            "title": "Publications",
            "type": "array",
            "description": "(mode=publicationPosts) Custom-domain publication URLs or RSS-capable sites, e.g. `https://www.slowboring.com` or `https://platformer.news`. Bare subdomains and substack.com links are blocked from this actor's cloud network.",
            "editor": "stringList",
            "default": [
              "platformer.news"
            ],
            "prefill": [
              "platformer.news"
            ]
          },
          "postUrls": {
            "title": "Post URLs",
            "type": "array",
            "description": "(mode=postUrls) Custom-domain post URLs, e.g. `https://www.noahpinion.blog/p/the-internet-breaks`. substack.com share links are reported as blocked_egress.",
            "editor": "stringList",
            "default": [],
            "prefill": []
          },
          "sortBy": {
            "title": "Sort order",
            "type": "string",
            "description": "(mode=publicationPosts) Newest first or all-time most popular first.",
            "editor": "select",
            "enum": [
              "newest",
              "top"
            ],
            "enumTitles": [
              "Newest first",
              "Most popular"
            ],
            "default": "newest",
            "prefill": "newest"
          },
          "publishedAfter": {
            "title": "Published after",
            "type": "string",
            "description": "Keep posts published on or after this date (`YYYY-MM-DD`).",
            "editor": "textfield"
          },
          "publishedBefore": {
            "title": "Published before",
            "type": "string",
            "description": "Keep posts published on or before this date (`YYYY-MM-DD`).",
            "editor": "textfield"
          },
          "containsKeyword": {
            "title": "Contains keyword",
            "type": "string",
            "description": "(mode=publicationPosts) Keep posts whose title, teaser or text contains this keyword. Uses Substack's publication search when possible.",
            "editor": "textfield"
          },
          "tagsAnyOf": {
            "title": "Tags",
            "type": "array",
            "description": "Keep posts carrying at least one of these tags (case-insensitive).",
            "editor": "stringList",
            "default": [],
            "prefill": []
          },
          "audienceFilter": {
            "title": "Free or paid",
            "type": "string",
            "description": "Keep all posts, only free posts, or only paid posts.",
            "editor": "select",
            "enum": [
              "all",
              "free",
              "paid"
            ],
            "enumTitles": [
              "All posts",
              "Free posts only",
              "Paid posts only"
            ],
            "default": "all",
            "prefill": "all"
          },
          "postType": {
            "title": "Post type",
            "type": "string",
            "description": "Keep all post types or a single type.",
            "editor": "select",
            "enum": [
              "all",
              "newsletter",
              "podcast",
              "thread"
            ],
            "enumTitles": [
              "All types",
              "Newsletter",
              "Podcast",
              "Thread"
            ],
            "default": "all",
            "prefill": "all"
          },
          "mediaFilter": {
            "title": "Media",
            "type": "string",
            "description": "Keep all posts, audio posts, video posts, or text-only posts.",
            "editor": "select",
            "enum": [
              "any",
              "audio",
              "video",
              "text"
            ],
            "enumTitles": [
              "Any media",
              "With audio",
              "With video",
              "Text only"
            ],
            "default": "any",
            "prefill": "any"
          },
          "bodyFormat": {
            "title": "Post body",
            "type": "string",
            "description": "Body fields to include. `none` is fastest; `all` adds HTML, plain text and Markdown.",
            "editor": "select",
            "enum": [
              "none",
              "html",
              "text",
              "markdown",
              "all"
            ],
            "enumTitles": [
              "No body",
              "HTML",
              "Plain text",
              "Markdown",
              "HTML + text + Markdown"
            ],
            "default": "all",
            "prefill": "none"
          },
          "includePaidPreview": {
            "title": "Include paid post preview",
            "type": "boolean",
            "description": "For paid posts, include the public preview body and flag it as a preview. Turn off for faster metadata-only runs.",
            "default": true,
            "prefill": false
          },
          "includeComments": {
            "title": "Include comments",
            "type": "boolean",
            "description": "Include public comment threads for free posts. Paid-post comments are members-only.",
            "default": false,
            "prefill": false
          },
          "maxCommentsPerPost": {
            "title": "Max comments per post",
            "type": "integer",
            "description": "Cap on comments per post, including replies. Set to 0 for no limit.",
            "minimum": 0,
            "maximum": 5000,
            "default": 20,
            "prefill": 20
          },
          "includePublicationInfo": {
            "title": "Include publication info",
            "type": "boolean",
            "description": "Add publication details such as pricing plans, sections, language and payment status.",
            "default": true,
            "prefill": false
          },
          "maxItems": {
            "title": "Max items",
            "type": "integer",
            "description": "Hard cap on emitted records.",
            "minimum": 1,
            "maximum": 10000,
            "default": 50,
            "prefill": 3
          },
          "maxPostsPerPublication": {
            "title": "Max posts per publication",
            "type": "integer",
            "description": "Optional per-publication cap. Set to 0 for no per-publication limit.",
            "minimum": 0,
            "maximum": 10000,
            "default": 0,
            "prefill": 3
          }
        }
      },
      "output": {
        "actorOutputSchemaVersion": 1,
        "title": "Substack Publication Post Exporter Output",
        "description": "One record per post (metadata, free body HTML/text/Markdown, flagged paid teaser, media, engagement, comments) or one blocked_egress status row per substack.com-hosted input.",
        "properties": {
          "posts": {
            "type": "string",
            "title": "Substack posts and author profiles",
            "description": "Dataset containing scraped Substack posts and author profiles.",
            "template": "{{links.apiDefaultDatasetUrl}}/items"
          }
        }
      },
      "storages": {
        "dataset": {
          "actorSpecification": 1,
          "views": {
            "overview": {
              "title": "Substack posts",
              "transformation": {
                "fields": [
                  "title",
                  "recordType",
                  "publication",
                  "author",
                  "publishedAt",
                  "audience",
                  "commentCount",
                  "url"
                ]
              },
              "display": {
                "component": "table",
                "properties": {}
              }
            }
          }
        }
      },
      "environmentVariables": {}
    },
    "buildNumber": "1.1.1",
    "imageDigest": "d6d81f40c16190700d1e52a80b69f232c96069e78e58306e5f1f6976219714ec",
    "actVersion": {
      "sourceType": "SOURCE_FILES",
      "buildTag": "latest",
      "versionNumber": "1.1"
    },
    "usage": {
      "ACTOR_COMPUTE_UNITS": 0.017537777777777777
    }
  }
}