{
  "openapi": "3.0.1",
  "info": {
    "title": "Substack Scraper – Newsletter Posts, Engagement & Monitoring",
    "description": "Scrape any Substack newsletter's full post archive with engagement metadata (likes, comments, paywall status, word count, authors), fetch single posts, and monitor newsletters incrementally — via Substack's public JSON API. No login.",
    "version": "0.1",
    "x-build-id": "CM3H9qft2ARNLA5Uv"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/bitofacoder~substack-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-bitofacoder-substack-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/bitofacoder~substack-scraper/runs": {
      "post": {
        "operationId": "runs-sync-bitofacoder-substack-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/bitofacoder~substack-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-bitofacoder-substack-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": [
          "mode"
        ],
        "properties": {
          "mode": {
            "title": "Mode",
            "enum": [
              "publication",
              "post",
              "monitor"
            ],
            "type": "string",
            "description": "What to scrape. Each mode uses a different set of fields below.",
            "default": "publication"
          },
          "publicationUrls": {
            "title": "Newsletter URLs",
            "type": "array",
            "description": "Used by 'publication' and 'monitor' modes. A Substack subdomain (acx.substack.com), a custom domain (www.thefp.com), or a bare name (platformer → platformer.substack.com). One run scrapes each.",
            "default": [
              "astralcodexten.substack.com"
            ],
            "items": {
              "type": "string"
            }
          },
          "sort": {
            "title": "Sort order",
            "enum": [
              "new",
              "top"
            ],
            "type": "string",
            "description": "For 'publication' mode: archive order. 'new' = newest first, 'top' = most popular.",
            "default": "new"
          },
          "includePostBody": {
            "title": "Include full post body",
            "type": "boolean",
            "description": "Fetch each post's full HTML body (one extra HTTP request per post — slower and uses more compute, though it does NOT add billable result items). Full body is only available for free posts; paywalled posts return the free preview only and are flagged with isPreviewOnly.",
            "default": false
          },
          "postUrls": {
            "title": "Post URLs",
            "type": "array",
            "description": "Used by 'post' mode. Full Substack post URLs, e.g. ['https://www.astralcodexten.com/p/open-thread-439'].",
            "items": {
              "type": "string"
            }
          },
          "monitorStoreName": {
            "title": "Monitor state store name",
            "type": "string",
            "description": "Named key-value store that holds per-newsletter watermarks across runs. IMPORTANT: give each separate monitor task its OWN unique name — two tasks sharing a name (including this default) will overwrite each other's watermarks, and concurrent runs on the same name can lose new posts. Use the same name across runs of the SAME task to keep tracking incrementally.",
            "default": "substack-monitor-state"
          },
          "resetMonitorState": {
            "title": "Reset monitor state",
            "type": "boolean",
            "description": "For 'monitor' mode: clear the saved watermarks before running so this run re-baselines (re-emits recent posts) instead of returning only what's new. Use to start fresh on a newsletter.",
            "default": false
          },
          "maxItems": {
            "title": "Max posts per newsletter",
            "minimum": 1,
            "type": "integer",
            "description": "Upper limit of posts per newsletter (per newsletter in monitor mode). Default is kept low for a fast, cheap first run — raise it to pull more; the full archive of a large newsletter can be hundreds of posts.",
            "default": 10
          },
          "maxTotalItems": {
            "title": "Max items total (whole run)",
            "minimum": 1,
            "type": "integer",
            "description": "Hard ceiling on the total number of results — and pay-per-result charges — across ALL newsletters in one run. Leave empty for no overall cap. 'Max posts per newsletter' above still applies to each."
          },
          "requestDelayMs": {
            "title": "Delay between requests (ms)",
            "minimum": 0,
            "type": "integer",
            "description": "Optional pause before each HTTP request. Leave at 0 for normal runs. Raise to ~200–500 for very large archives or includePostBody runs (hundreds of requests to one site) when running without a proxy, to avoid rate limiting.",
            "default": 0
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Off by default — Substack's public API is open and small runs don't need a proxy. Enable Apify Proxy to rotate IPs and spread the per-IP rate limit on large runs.",
            "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
                  }
                }
              },
              "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}