{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Comment Scraper — Comments, Replies, Likes",
    "description": "Scrape YouTube comments and their reply threads from any video, channel, or search query. Each comment carries author identity and badges, like and reply counts, and timestamps as structured JSON built for sentiment work. Sort by top or newest and re-run for only what is new.",
    "version": "0.1",
    "x-build-id": "FeEkqY5m2f6Ny7k7l"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/blackfalcondata~youtube-comment-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-blackfalcondata-youtube-comment-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/blackfalcondata~youtube-comment-scraper/runs": {
      "post": {
        "operationId": "runs-sync-blackfalcondata-youtube-comment-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/blackfalcondata~youtube-comment-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-blackfalcondata-youtube-comment-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",
        "properties": {
          "videoUrls": {
            "title": "🎬 Video URLs",
            "type": "array",
            "description": "YouTube video URLs to scrape comments from (one per line). Accepts watch links, Shorts, youtu.be short links, embed links, and bare 11-character video IDs. Every URL you paste here is processed — Max Videos only limits videos discovered from channels and search queries. Also accepts the aliases `videoUrl`, `url`, `urls`, and `startUrls`.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "channelUrls": {
            "title": "📺 Channel URLs",
            "type": "array",
            "description": "Channel URLs or bare @handles (one per line), e.g. \"https://www.youtube.com/@MrBeast\" or \"@veritasium\". The channel's latest videos are collected (up to Max Videos) and their comments are scraped. Default: empty. Also accepts the alias `channelUrl`.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "searchQueries": {
            "title": "🔍 Search Queries",
            "type": "array",
            "description": "Keywords to search on YouTube (one per line). The top matching videos (up to Max Videos) are used as comment sources. Default: empty. Also accepts the aliases `query`, `q`, `keyword`, `keywords`, `search`.",
            "items": {
              "type": "string"
            },
            "default": []
          },
          "maxComments": {
            "title": "💬 Max Comments (per video)",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "Maximum number of top-level comments to scrape per video. YouTube returns comments in pages of roughly 20, so higher values follow more continuation pages and take longer. 0 = no limit of our own, though the walk still stops after 200 pages (roughly 4,000 comments) for one video, and the total cap below always applies. Default: 100. Also accepts the aliases `commentsPerVideo`, `maxCommentsPerVideo`, `commentsCount`, `count`.",
            "default": 100
          },
          "maxItems": {
            "title": "💯 Max Comments (total)",
            "minimum": 0,
            "maximum": 500000,
            "type": "integer",
            "description": "Hard ceiling on how many comments the whole run delivers (and therefore on what the run costs), across every video. Reached mid-run, the run stops and pushes what it has. 0 = unlimited. Default: 1000. Also accepts the alias `maxTotalComments`.",
            "default": 1000
          },
          "sortBy": {
            "title": "🔀 Sort By",
            "enum": [
              "top",
              "newest"
            ],
            "type": "string",
            "description": "Comment order requested from YouTube. \"Top comments\" is YouTube's own ranking (most engagement first); \"Newest first\" is chronological — use it together with Incremental Mode to monitor fresh comments. Default: top. Also accepts the aliases `commentsSort`, `orderBy`, `sort`, `order`.",
            "default": "top"
          },
          "includeReplies": {
            "title": "🧵 Include Replies",
            "type": "boolean",
            "description": "Fetch each comment's reply thread and attach it to the parent comment under `replies`. Replies are part of the parent comment's record — they are not billed as extra results. Replies are fetched for up to 200 comments per video, and up to the first 20 replies on each of those. Adds one extra request per comment thread, so runs take longer. Default: false.",
            "default": false
          },
          "maxVideos": {
            "title": "🎞️ Max Videos (from channels & searches)",
            "minimum": 1,
            "maximum": 200,
            "type": "integer",
            "description": "Maximum number of videos to take from channels and search queries as comment sources, across the whole run (not per channel or per query). Video URLs you paste are always all processed and are not limited by this. A search contributes at most 200 videos, and a channel contributes its latest page of uploads (around 30), so values above those are bounded by what YouTube returns. On a repeated run with Incremental mode on, the videos it scans rotate: each run starts with the ones it has gone longest without visiting, so a limit smaller than the channel or search behind it still works through all of them over time. Default: 10.",
            "default": 10
          },
          "country": {
            "title": "🌍 Country (2-letter code)",
            "type": "string",
            "description": "ISO 3166-1 alpha-2 country code used for YouTube's region context (e.g. \"US\", \"GB\", \"DE\"). Affects which comment set and localisation YouTube returns. Default: US. Also accepts the aliases `geo`, `region`, `gl`.",
            "default": "US"
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy Configuration",
            "type": "object",
            "description": "Network routing for the requests. The default is what this actor is tuned for and needs no change. Usage here is paid by us, not billed to your account.",
            "default": {
              "useApifyProxy": true
            }
          },
          "incrementalMode": {
            "title": "🔁 Incremental Mode",
            "type": "boolean",
            "description": "On repeat runs with the same input, deliver only comments that are new since the last run, plus any whose text was edited. State is stored in a named key-value store keyed by your input, so a scheduled run returns just the fresh discussion. Default: false.",
            "default": false
          },
          "stateKey": {
            "title": "🗝️ State Key",
            "type": "string",
            "description": "Optional label for the incremental state bucket, used as a readable prefix. The bucket itself is still keyed by your targets and settings, so two runs with different inputs never share a memory even under the same label — use it to keep runs apart and to recognise them, not to merge them. Leave empty to derive it automatically. Default: empty."
          },
          "maxRunSeconds": {
            "title": "⏱️ Max Run Time (seconds)",
            "minimum": 0,
            "maximum": 86400,
            "type": "integer",
            "description": "Stop the run and push whatever has been collected after this many seconds. Useful as a guard on large channel jobs. 0 or empty = no limit. Default: empty."
          },
          "excludeEmptyFields": {
            "title": "🧹 Exclude Empty Fields",
            "type": "boolean",
            "description": "Drop null and empty fields from every output record. Produces leaner JSON for LLM and agent pipelines. Default: false.",
            "default": false
          },
          "includeRunMetadata": {
            "title": "📣 Include Run Metadata",
            "type": "boolean",
            "description": "Attach a `_meta` block to every output record describing the run (ids, timestamps, a non-sensitive input summary, and per-type counts). Handy for pipelines that need to trace a record back to the run that produced it. The counts describe what the run produced and are stamped on every record before they are saved, so a run cut short by a charge limit can deliver fewer records than the counts name. A run with no results produces no records and therefore no metadata. Default: false.",
            "default": false
          },
          "appConnector": {
            "title": "Send results to Notion (or another connected app)",
            "type": "string",
            "description": "Optional. Pick a connected app under Settings → API & Integrations to receive your results. Notion is supported today (a run-summary page); other MCP connectors are best-effort as Apify expands its catalog. Up to 500 records are sent to the app; the complete set is always in the dataset."
          },
          "mcpIssueTeam": {
            "title": "Issue tracker team",
            "type": "string",
            "description": "Only when the connected app is an issue tracker: the team (name or ID) the summary issue is created under, if that app requires one."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}