{
  "openapi": "3.0.1",
  "info": {
    "title": "YouTube Comments Scraper: New Comments Alerts, Bulk by Video",
    "description": "Scrape YouTube comments for a list of videos, or only new comments since last run as alerts. One row per comment: text, likes, replies, author name and channel ID, pinned and creator flags. No login, no API key, no API quota. Comments to Google Sheets, Slack or n8n. Comments-off videos are free.",
    "version": "1.0",
    "x-build-id": "0uGlkWfztylbr7Mbb"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/accountable_eel~youtube-comments-lookup/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-accountable_eel-youtube-comments-lookup",
        "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/accountable_eel~youtube-comments-lookup/runs": {
      "post": {
        "operationId": "runs-sync-accountable_eel-youtube-comments-lookup",
        "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/accountable_eel~youtube-comments-lookup/run-sync": {
      "post": {
        "operationId": "run-sync-accountable_eel-youtube-comments-lookup",
        "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": [
          "videos"
        ],
        "properties": {
          "videos": {
            "title": "YouTube videos",
            "type": "array",
            "description": "One video per line: a full link (watch, youtu.be, Shorts, live or embed) or just the 11-character video ID. No login, no API key and no API quota: this reads the same public comments a signed-out visitor sees. Accepted formats: https://www.youtube.com/watch?v=dQw4w9WgXcQ, https://youtu.be/dQw4w9WgXcQ, https://www.youtube.com/shorts/dQw4w9WgXcQ, dQw4w9WgXcQ. You're only charged for the ones we actually find — a miss costs nothing.",
            "items": {
              "type": "string"
            }
          },
          "testRun": {
            "title": "Try it first — only process the first 5",
            "type": "boolean",
            "description": "Turn this on to test your input on a small sample before running the full list. Turn it off to process everything.",
            "default": false
          },
          "onlyFound": {
            "title": "Hide rows with no result",
            "type": "boolean",
            "description": "Only keep rows where something was actually found. Misses are always free, whether or not you show them here.",
            "default": false
          },
          "includeKeywords": {
            "title": "Only keep rows containing",
            "type": "array",
            "description": "Optional. Only keep results that mention at least one of these words (e.g. a job title, a city, a product name). Leave empty to keep everything.",
            "items": {
              "type": "string"
            }
          },
          "excludeKeywords": {
            "title": "Skip rows containing",
            "type": "array",
            "description": "Optional. Drop any result that mentions one of these words. Leave empty to skip nothing.",
            "items": {
              "type": "string"
            }
          },
          "maxResults": {
            "title": "Stop after this many results",
            "minimum": 1,
            "type": "integer",
            "description": "Optional. Stop the run once this many results have been found — useful for a quick, cheap sample. Leave blank for no limit."
          },
          "maxComments": {
            "title": "Most comments per video (1-1,000)",
            "type": "integer",
            "description": "You pay per comment returned, so this is also your budget control. Counts top-level comments and replies together. Leave at 100 for a monitor; the first run of a monitor fetches up to this many, later runs usually stop as soon as they reach comments you already have.",
            "default": 100
          },
          "sort": {
            "title": "Sort comments by",
            "enum": [
              "newest",
              "top"
            ],
            "type": "string",
            "description": "Newest first is what a monitor wants: new comments arrive at the top, so each run reads only as far as it needs. Top comments is YouTube's own ranking, useful for a one-off export of the most-liked discussion.",
            "default": "newest"
          },
          "includeReplies": {
            "title": "Include replies",
            "type": "boolean",
            "description": "Also read the replies under each comment, each as its own row with 'Replying to comment ID' filled in. Replies count toward 'Most comments per video' and are billed like any other comment.",
            "default": false
          },
          "deltaMode": {
            "title": "Only return comments that are new since the last run",
            "type": "boolean",
            "description": "Turns this actor into a comment monitor. A comment counts as new when its YouTube comment ID has not been returned for that video by an earlier run of the same watchlist. Already-seen comments are dropped and never billed, so your Slack, Sheets or n8n step only sees fresh ones. Memory is kept per video: adding a new video to your list never re-sends the other videos' old comments. The first run returns every comment it reads (or none, with 'Seed silently' on) and remembers them.",
            "default": false
          },
          "skipFirstRun": {
            "title": "Seed silently (no comments on a video's first run)",
            "type": "boolean",
            "description": "With monitoring on, the first run for each video remembers every comment it reads but returns and bills none of them. From the next run on you get only comments posted since. Use this when you want alerts, not an initial backlog.",
            "default": false
          },
          "deltaName": {
            "title": "Watchlist name (optional)",
            "type": "string",
            "description": "Leave empty for one shared memory per video across all your runs. Type a name to keep a separate memory, for example when two schedules watch the same video for different teams. Naming a watchlist with monitoring off returns every comment but still stamps each with 'Is this comment new?' and 'First seen', so you can filter them yourself in Sheets, n8n or Make. A comment no run has read for 90 days is forgotten.",
            "default": ""
          },
          "columns": {
            "title": "Which columns do you want?",
            "type": "array",
            "description": "Choose which pieces of information to include in each result row. All are included by default.",
            "items": {
              "type": "string",
              "enum": [
                "videoId",
                "videoTitle",
                "videoUrl",
                "sort",
                "totalCommentCount",
                "commentCount",
                "newCommentCount",
                "monitorStatus",
                "comments",
                "commentId",
                "parentCommentId",
                "isReply",
                "text",
                "publishedText",
                "publishedAtApprox",
                "likeCount",
                "replyCount",
                "authorName",
                "authorChannelId",
                "authorIsVerified",
                "authorIsCreator",
                "isPinned",
                "isNew",
                "firstSeenAt"
              ],
              "enumTitles": [
                "Video ID",
                "Video title",
                "Video link",
                "Sort order used",
                "Comments on the video in total",
                "Comments returned",
                "New comments since last run",
                "Monitor status",
                "All comments found (full list)",
                "Comment ID",
                "Replying to comment ID (empty for top-level)",
                "Is a reply",
                "Comment text",
                "Posted (as YouTube shows it)",
                "Posted at (approximate)",
                "Likes",
                "Replies",
                "Author (public display name)",
                "Author channel ID",
                "Author is verified",
                "Written by the video's creator",
                "Pinned comment",
                "Is this comment new?",
                "First seen on a run"
              ]
            },
            "default": [
              "videoId",
              "videoTitle",
              "videoUrl",
              "sort",
              "totalCommentCount",
              "commentCount",
              "newCommentCount",
              "monitorStatus",
              "comments",
              "commentId",
              "parentCommentId",
              "isReply",
              "text",
              "publishedText",
              "publishedAtApprox",
              "likeCount",
              "replyCount",
              "authorName",
              "authorChannelId",
              "authorIsVerified",
              "authorIsCreator",
              "isPinned",
              "isNew",
              "firstSeenAt"
            ]
          },
          "expandRows": {
            "title": "One row per comment (recommended) — turn off for one row per video instead",
            "type": "boolean",
            "description": "When on, each comment found gets its own row instead of being grouped under its video. You're still only charged once per video, no matter how many rows it produces.",
            "default": true
          },
          "maxConcurrency": {
            "title": "Max concurrency",
            "minimum": 1,
            "maximum": 10,
            "type": "integer",
            "description": "Parallel requests. Keep conservative — this target has no browser fallback, so getting blocked costs more than slow-and-steady.",
            "default": 3
          },
          "proxyConfiguration": {
            "title": "Proxy configuration",
            "type": "object",
            "description": "Apify Proxy config. Residential recommended for anti-bot-sensitive targets.",
            "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
                  },
                  "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}