{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Comments Scraper - Comment Replies & Threads",
    "description": "YouTube comments scraper that returns every comment AND every reply, with parentCommentId on every reply row so full comment threads reconstruct from one flat dataset. No login, no Google API key, no cookie.",
    "version": "0.0",
    "x-build-id": "ZIcldcrRLRXkbV4NX"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/eiv~youtube-comments-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-eiv-youtube-comments-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/eiv~youtube-comments-scraper/runs": {
      "post": {
        "operationId": "runs-sync-eiv-youtube-comments-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/eiv~youtube-comments-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-eiv-youtube-comments-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": {
          "videos": {
            "title": "YouTube videos",
            "type": "array",
            "description": "Video URLs or bare 11-character video ids. `watch?v=`, `youtu.be/`, `/shorts/`, `/live/` and `/embed/` links all work, and extra parameters are ignored. Shorts are ordinary videos to this endpoint, so they need no special handling. A channel or playlist URL is rejected with a message rather than guessed at.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Start URLs",
            "type": "array",
            "description": "The same videos, in the shape other Actors and the Apify UI hand over. Merged with the list above and deduplicated by video id.",
            "items": {
              "type": "object",
              "required": [
                "url"
              ],
              "properties": {
                "url": {
                  "type": "string",
                  "title": "URL of a web page",
                  "format": "uri"
                }
              }
            }
          },
          "sourceDatasetId": {
            "title": "Source dataset id",
            "type": "string",
            "description": "Read video URLs out of another run's dataset, for chaining after a channel or search Actor."
          },
          "sourceDatasetField": {
            "title": "Source dataset field",
            "type": "string",
            "description": "Which field in that dataset holds the video URL or id. Defaults to `url`."
          },
          "sortBy": {
            "title": "Comment order",
            "enum": [
              "top",
              "newest"
            ],
            "type": "string",
            "description": "Verified to change the output rather than merely being accepted: id-diffing Top against Newest gave 4/10, 0/10 and 1/10 first-page overlap across three videos, and Newest returned strict recency. Newest costs one extra request per video because its token only exists inside the first page's sort menu, and that discarded page is never billed to you.",
            "default": "top"
          },
          "includeReplies": {
            "title": "Include replies",
            "type": "boolean",
            "description": "Fetch reply threads as well as top-level comments. Every reply row carries `parentCommentId` and `isReply`, so a flat dataset groups back into threads. Replies cost the same per row as comments.",
            "default": true
          },
          "maxCommentsPerVideo": {
            "title": "Max top-level comments per video",
            "minimum": 1,
            "maximum": 100000,
            "type": "integer",
            "description": "Bounds the **output**: top-level comment rows kept per video. Replies are counted separately against the per-thread cap below. YouTube serves 20 comments per page and the page size is not settable.",
            "default": 100
          },
          "maxRepliesPerThread": {
            "title": "Max replies per thread",
            "minimum": 0,
            "maximum": 5000,
            "type": "integer",
            "description": "Upper bound on replies collected per comment thread. This is the setting that decides how long a run takes: YouTube serves replies on a separate request per thread, so 100 comments with replies on is at least 100 requests whatever this is set to, and raising it adds another request per thread for roughly every 10 replies. Measured on a real video: 100 comments at 10 replies per thread is 100 requests and about 830 rows, while the same 100 comments at 50 replies per thread is 151 requests and about 2,200 rows. Threads cut by this limit are marked repliesTruncated so a partial thread is never passed off as a complete one.",
            "default": 10
          },
          "maxPagesPerVideo": {
            "title": "Max pages per video",
            "minimum": 1,
            "maximum": 5000,
            "type": "integer",
            "description": "Bounds the **work**, where the cap above bounds the output. Needed because one measured video handed back a valid continuation token on five consecutive pages while returning zero comments; this Actor stops on zero new ids, and this is the belt-and-braces bound behind that.",
            "default": 200
          },
          "maxTotalComments": {
            "title": "Max rows for the whole run",
            "minimum": 1,
            "maximum": 1000000,
            "type": "integer",
            "description": "A ceiling across every video, counting comments and replies together. Reached mid-video, the run stops cleanly and the status rows say so.",
            "default": 10000
          },
          "requestDelayMs": {
            "title": "Delay between requests (ms)",
            "minimum": 0,
            "maximum": 60000,
            "type": "integer",
            "description": "Measured clean at 174.5 requests/minute with no delay and no rate limiting across 159 consecutive requests — the ceiling was never found. The default is deliberately about a third of that, because the measurement came from one residential line and your run happens on shared datacenter IPs.",
            "default": 1000
          },
          "maxConcurrency": {
            "title": "Concurrent videos",
            "minimum": 1,
            "maximum": 20,
            "type": "integer",
            "description": "How many videos are scraped at once. Comments within a video are inherently sequential because each page's token comes from the page before it.",
            "default": 4
          },
          "proxyConfig": {
            "title": "Proxy",
            "type": "object",
            "description": "Apify datacenter proxy, on by default. Residential is deliberately not used: it is billed per gigabyte and would consume the margin this Actor is priced on, and the transport was measured not to need it.",
            "default": {
              "useApifyProxy": true
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}