{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Comments API — Comments & Replies with Likes",
    "description": "Scrape YouTube comments as data. One row per comment: text, author, like count, reply count, relative and approximate absolute time, pinned and hearted flags. Sort by top or newest, walk reply threads, cap per video. Residential proxy included, no API key, no login.",
    "version": "0.1",
    "x-build-id": "chSeVNavUdFd9sNgI"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/insight.solutions~youtube-comments-api/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-insight.solutions-youtube-comments-api",
        "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/insight.solutions~youtube-comments-api/runs": {
      "post": {
        "operationId": "runs-sync-insight.solutions-youtube-comments-api",
        "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/insight.solutions~youtube-comments-api/run-sync": {
      "post": {
        "operationId": "run-sync-insight.solutions-youtube-comments-api",
        "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": [
          "videoUrls"
        ],
        "properties": {
          "videoUrls": {
            "title": "YouTube videos",
            "type": "array",
            "description": "One entry per video. Any YouTube link works — a watch URL, a youtu.be share link, a Shorts, embed or live URL, with or without a playlist or timestamp glued on — and so does a bare 11-character video ID. Channel and playlist URLs are rejected, because they are not one video. Duplicates are read, and billed, once.",
            "items": {
              "type": "string"
            }
          },
          "maxCommentsPerVideo": {
            "title": "Top-level comments per video",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "How many top-level comments to return for each video. YouTube serves them twenty at a time, so the walk stops on the page that reaches your number — you may get a few fewer than a round figure if the video runs out of comments first. Replies do not count towards it. Set 0 for every comment the video has, which on a popular video means thousands of rows and a run bounded only by your time and charge budgets.",
            "default": 100
          },
          "sort": {
            "title": "Comment order",
            "enum": [
              "top",
              "newest"
            ],
            "type": "string",
            "description": "Which of YouTube's own two orders to walk. `top` is the default ranking you see on the site — engagement-weighted, with the pinned comment first. `newest` is strictly reverse-chronological. There is no third order: these are the only two YouTube exposes, and `newest` costs one extra request per video because its continuation token only exists inside the first page of the default order.",
            "default": "top"
          },
          "includeReplies": {
            "title": "Include replies",
            "type": "boolean",
            "description": "Walk each comment's reply thread and return one row per reply, `rowType: \"reply\"`, immediately after the comment it answers. Replies are billed at the same rate as comments and a busy thread can hold hundreds, so this is off by default. Use `maxRepliesPerComment` to bound it.",
            "default": false
          },
          "maxRepliesPerComment": {
            "title": "Replies per comment",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "The cap on replies for a single comment, when `includeReplies` is on. Ignored otherwise. Set 0 for the whole thread. YouTube's comment tree is two levels deep — a reply to a reply is filed under the same top-level comment — so this is the only reply limit there is.",
            "default": 50
          },
          "includeAuthorDetails": {
            "title": "Include author identity",
            "type": "boolean",
            "description": "Fill in `authorChannelId`, `authorUrl` and `authorAvatarUrl`. Turn it off and rows keep the display name and the verified / creator / artist badges but carry no channel ID, profile link or avatar — the narrower shape to hold when you only need the text and the numbers. It costs no extra request either way.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Videos in parallel",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "How many videos are walked at once. Each parallel worker keeps its own residential proxy session, so a video that gets blocked burns only its own exit IP. Pages *within* one video cannot be parallelised — each page hands over the token for the next — so this is the only lever on speed. Three is the balance that holds up in practice.",
            "default": 3
          },
          "maxRunSecs": {
            "title": "Maximum run time (seconds)",
            "minimum": 30,
            "maximum": 3600,
            "type": "integer",
            "description": "Wall-clock budget for the whole run. When it is reached the Actor stops walking, keeps and bills for every comment it already wrote, and files a free diagnostic row for each video it never reached. A video stopped part-way keeps its rows and is not marked as failed. Nothing is charged for work that did not happen.",
            "default": 240
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "YouTube blocks datacenter IP ranges wholesale, which is why this Actor is built around Apify's residential proxy and why the proxy cost is already inside the per-comment price. Leave this on the default. Sessions rotate automatically when an exit IP is refused. Clearing it sends requests from the run's own datacenter address, which YouTube will almost certainly block.",
            "default": {
              "useApifyProxy": true,
              "apifyProxyGroups": [
                "RESIDENTIAL"
              ]
            }
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}