Substack Posts Scraper
Pricing
from $5.00 / 1,000 post scrapeds
Substack Posts Scraper
Scrape Substack newsletter posts from any publication on a subdomain or custom domain. Returns full post text, engagement, tags and paywall status.
Substack Posts Scraper
Pricing
from $5.00 / 1,000 post scrapeds
Scrape Substack newsletter posts from any publication on a subdomain or custom domain. Returns full post text, engagement, tags and paywall status.
You can access the Substack Posts Scraper programmatically from your own applications by using the Apify API. You can also choose the language preference from below. To use the Apify API, you’ll need an Apify account and your API token, found in API & Integrations in Apify Console.
{ "openapi": "3.0.1", "info": { "version": "0.2", "x-build-id": "BeQkpclKL1v1ZmlBp" }, "servers": [ { "url": "https://api.apify.com/v2" } ], "paths": { "/acts/khadinakbar~substack-posts-scraper/run-sync-get-dataset-items": { "post": { "operationId": "run-sync-get-dataset-items-khadinakbar-substack-posts-scraper", "x-openai-isConsequential": false, "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.", "tags": [ "Run Actor" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/inputSchema" } } } }, "parameters": [ { "name": "token", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Enter your Apify token here" } ], "responses": { "200": { "description": "OK" } } } }, "/acts/khadinakbar~substack-posts-scraper/runs": { "post": { "operationId": "runs-sync-khadinakbar-substack-posts-scraper", "x-openai-isConsequential": false, "summary": "Executes an Actor and returns information about the initiated run in response.", "tags": [ "Run Actor" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/inputSchema" } } } }, "parameters": [ { "name": "token", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Enter your Apify token here" } ], "responses": { "200": { "description": "OK", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/runsResponseSchema" } } } } } } }, "/acts/khadinakbar~substack-posts-scraper/run-sync": { "post": { "operationId": "run-sync-khadinakbar-substack-posts-scraper", "x-openai-isConsequential": false, "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.", "tags": [ "Run Actor" ], "requestBody": { "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/inputSchema" } } } }, "parameters": [ { "name": "token", "in": "query", "required": true, "schema": { "type": "string" }, "description": "Enter your Apify token here" } ], "responses": { "200": { "description": "OK" } } } } }, "components": { "schemas": { "inputSchema": { "type": "object", "required": [ "startUrls" ], "properties": { "startUrls": { "title": "Substack publication or post URLs", "type": "array", "description": "One or more Substack publication URLs. Accepts publication roots (e.g. 'https://platformer.substack.com' or custom domain 'https://www.lennysnewsletter.com') and single post URLs ('https://.../p/some-post'). Each publication is paginated up to maxPosts. NOT a keyword search input — this actor scrapes by publication URL.", "items": { "type": "object", "properties": { "url": { "type": "string", "title": "URL", "description": "A Substack publication or post URL, e.g. https://platformer.substack.com" } }, "required": [ "url" ] } }, "maxPosts": { "title": "Max posts per publication", "minimum": 1, "maximum": 2000, "type": "integer", "description": "Hard cap on the number of posts scraped and billed per publication. Each post counts as one billable result. Defaults to 50. Set lower for cheap test runs.", "default": 50 }, "includeBodyHtml": { "title": "Include full body HTML", "type": "boolean", "description": "When true (default), fetches each post's detail page to capture the complete article HTML. Public posts return full HTML; paid posts return metadata + paywall signal only. Adds one HTTP request per post.", "default": true }, "includeBodyText": { "title": "Include plain text body", "type": "boolean", "description": "When true (default), includes a plain-text version of the article body (derived from the HTML). Public posts return full text; paid posts return the teaser only. Disable to reduce payload size.", "default": true }, "publishedAfter": { "title": "Published after (ISO date)", "type": "string", "description": "Optional ISO 8601 date or datetime. Only posts published on or after this date are returned, e.g. '2026-01-01' or '2026-06-01T00:00:00Z'. Leave empty for no lower bound.", "default": "" }, "publishedBefore": { "title": "Published before (ISO date)", "type": "string", "description": "Optional ISO 8601 date or datetime. Only posts published on or before this date are returned. Leave empty for no upper bound.", "default": "" }, "audience": { "title": "Audience filter", "enum": [ "all", "free", "paid" ], "type": "string", "description": "Filter posts by paywall audience. 'all' (default) returns every post; 'free' returns only free posts; 'paid' returns only paid/paywalled posts (metadata + teaser).", "default": "all" }, "proxyConfiguration": { "title": "Proxy (optional)", "type": "object", "description": "Optional Apify proxy. Substack's public JSON API works without one, so leave this off unless you hit a transient network block.", "default": { "useApifyProxy": false } } } }, "runsResponseSchema": { "type": "object", "properties": { "data": { "type": "object", "properties": { "id": { "type": "string" }, "actId": { "type": "string" }, "userId": { "type": "string" }, "startedAt": { "type": "string", "format": "date-time", "example": "2025-01-08T00:00:00.000Z" }, "finishedAt": { "type": "string", "format": "date-time", "example": "2025-01-08T00:00:00.000Z" }, "status": { "type": "string", "example": "READY" }, "meta": { "type": "object", "properties": { "origin": { "type": "string", "example": "API" }, "userAgent": { "type": "string" } } }, "stats": { "type": "object", "properties": { "inputBodyLen": { "type": "integer", "example": 2000 }, "rebootCount": { "type": "integer", "example": 0 }, "restartCount": { "type": "integer", "example": 0 }, "resurrectCount": { "type": "integer", "example": 0 }, "computeUnits": { "type": "integer", "example": 0 } } }, "options": { "type": "object", "properties": { "build": { "type": "string", "example": "latest" }, "timeoutSecs": { "type": "integer", "example": 300 }, "memoryMbytes": { "type": "integer", "example": 1024 }, "diskMbytes": { "type": "integer", "example": 2048 } } }, "buildId": { "type": "string" }, "defaultKeyValueStoreId": { "type": "string" }, "defaultDatasetId": { "type": "string" }, "defaultRequestQueueId": { "type": "string" }, "buildNumber": { "type": "string", "example": "1.0.0" }, "containerUrl": { "type": "string" }, "usage": { "type": "object", "properties": { "ACTOR_COMPUTE_UNITS": { "type": "integer", "example": 0 }, "DATASET_READS": { "type": "integer", "example": 0 }, "DATASET_WRITES": { "type": "integer", "example": 0 }, "KEY_VALUE_STORE_READS": { "type": "integer", "example": 0 }, "KEY_VALUE_STORE_WRITES": { "type": "integer", "example": 1 }, "KEY_VALUE_STORE_LISTS": { "type": "integer", "example": 0 }, "REQUEST_QUEUE_READS": { "type": "integer", "example": 0 }, "REQUEST_QUEUE_WRITES": { "type": "integer", "example": 0 }, "DATA_TRANSFER_INTERNAL_GBYTES": { "type": "integer", "example": 0 }, "DATA_TRANSFER_EXTERNAL_GBYTES": { "type": "integer", "example": 0 }, "PROXY_RESIDENTIAL_TRANSFER_GBYTES": { "type": "integer", "example": 0 }, "PROXY_SERPS": { "type": "integer", "example": 0 }, "PROXY_UNBLOCKER_UNITS": { "type": "integer", "example": 0 } } }, "usageTotalUsd": { "type": "number", "example": 0.00005 }, "usageUsd": { "type": "object", "properties": { "ACTOR_COMPUTE_UNITS": { "type": "integer", "example": 0 }, "DATASET_READS": { "type": "integer", "example": 0 }, "DATASET_WRITES": { "type": "integer", "example": 0 }, "KEY_VALUE_STORE_READS": { "type": "integer", "example": 0 }, "KEY_VALUE_STORE_WRITES": { "type": "number", "example": 0.00005 }, "KEY_VALUE_STORE_LISTS": { "type": "integer", "example": 0 }, "REQUEST_QUEUE_READS": { "type": "integer", "example": 0 }, "REQUEST_QUEUE_WRITES": { "type": "integer", "example": 0 }, "DATA_TRANSFER_INTERNAL_GBYTES": { "type": "integer", "example": 0 }, "DATA_TRANSFER_EXTERNAL_GBYTES": { "type": "integer", "example": 0 }, "PROXY_RESIDENTIAL_TRANSFER_GBYTES": { "type": "integer", "example": 0 }, "PROXY_SERPS": { "type": "integer", "example": 0 }, "PROXY_UNBLOCKER_UNITS": { "type": "integer", "example": 0 } } } } } } } } }}OpenAPI is a standard for designing and describing RESTful APIs, allowing developers to define API structure, endpoints, and data formats in a machine-readable way. It simplifies API development, integration, and documentation.
OpenAPI is effective when used with AI agents and GPTs by standardizing how these systems interact with various APIs, for reliable integrations and efficient communication.
By defining machine-readable API specifications, OpenAPI allows AI models like GPTs to understand and use varied data sources, improving accuracy. This accelerates development, reduces errors, and provides context-aware responses, making OpenAPI a core component for AI applications.
You can download the OpenAPI definitions for Substack Posts Scraper from the options below:
If you’d like to learn more about how OpenAPI powers GPTs, read our blog post.
You can also check out our other API clients: