{
  "openapi": "3.0.1",
  "info": {
    "title": "TikTok Comments Scraper, No Login: Video Comments & Replies",
    "description": "TikTok comments scraper and extractor, no login: video links or handles in, one row per comment and reply out. Text, time, likes, reply count, the commenter's handle, name and avatar. Walks past TikTok's false list end and adds a second region's view. Export to CSV, JSON or Excel. Misses free.",
    "version": "0.1",
    "x-build-id": "k8cmiwiNcC1hPX0ji"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/hyperbach~tiktok-comments-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-hyperbach-tiktok-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/hyperbach~tiktok-comments-scraper/runs": {
      "post": {
        "operationId": "runs-sync-hyperbach-tiktok-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/hyperbach~tiktok-comments-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-hyperbach-tiktok-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": {
          "videoUrls": {
            "title": "Video URLs",
            "maxItems": 10000,
            "type": "array",
            "description": "TikTok videos to read, one per line: a video or photo link (`https://www.tiktok.com/@user/video/7332342275151760642`), a short link (`vm.tiktok.com/…`, `vt.tiktok.com/…`, `tiktok.com/t/…`), an `m.tiktok.com/v/<id>.html` or embed link, or a bare video id. A profile link is read as a profile. Each value gets its own row: the video's, or a free row that says why not (private, removed, comments off, a dead link).",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "profiles": {
            "title": "Profiles (creators' handles)",
            "maxItems": 1000,
            "type": "array",
            "description": "Creators whose newest videos to read: a handle (`@nasa` or `nasa`) or a profile link. TikTok's logged-out profile embed lists a creator's 12 newest videos (the pinned ones first); `videosPerProfile` picks how many of them are read.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "commentsPerVideo": {
            "title": "Comments per video",
            "minimum": 0,
            "maximum": 10000000,
            "type": "integer",
            "description": "The most top-level comments a video delivers (replies are counted apart, by `repliesPerComment`); 0 = every comment TikTok's list serves to a logged-out reader. The list ends before the video's own count: that count includes replies and comments TikTok does not show logged out; the video row says how far the list went.",
            "default": 100
          },
          "repliesPerComment": {
            "title": "Replies per comment",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "Also read each comment's replies, up to this many per comment, as their own rows with `is_reply` true and the `parent_comment_id`; the comment's row then carries the thread's own total. 0 = no replies. Each reply is a row and is charged like a comment. The comment filters pick comments: a kept comment's replies are not filtered.",
            "default": 0
          },
          "sortBy": {
            "title": "Which comments a limit keeps",
            "enum": [
              "ranked",
              "newest",
              "oldest",
              "most_liked"
            ],
            "type": "string",
            "description": "`ranked`: TikTok's own order (the first comments of its list). `newest`, `oldest`, `most_liked`: this Actor reads the list (to its end, or up to 100 pages plus 10 for each comment kept) and keeps the newest, oldest or most liked `commentsPerVideo` (TikTok's list has no sort of its own). With `commentsPerVideo` 0 every comment comes in the list's order.",
            "default": "ranked"
          },
          "commentsNewerThan": {
            "title": "Comments newer than",
            "type": "string",
            "description": "Only comments posted at or after this time: a date (`2026-10-01`), a date and time (`2026-10-01T12:00:00Z`) or a span back from now (`7 days`, `12 hours`, `2 weeks`). TikTok's list is not in time order, so the list is read (up to 100 pages of a video plus 10 for each comment kept) and the rest is left out, never charged."
          },
          "commentsOlderThan": {
            "title": "Comments older than",
            "type": "string",
            "description": "Only comments posted at or before this time (the same forms as `commentsNewerThan`)."
          },
          "commentKeywords": {
            "title": "Comments with any of these words",
            "type": "array",
            "description": "Only comments whose text holds any of these words or phrases (case-insensitive). A comment without them is left out and not charged.",
            "default": [],
            "items": {
              "type": "string"
            }
          },
          "minCommentLikes": {
            "title": "Minimum likes",
            "minimum": 0,
            "maximum": 100000000,
            "type": "integer",
            "description": "Only comments with at least this many likes (as the read view counts them). 0 = every comment.",
            "default": 0
          },
          "videosPerProfile": {
            "title": "Videos per profile",
            "minimum": 1,
            "maximum": 12,
            "type": "integer",
            "description": "How many of a profile's newest videos to read (1-12: the logged-out profile embed lists 12). The pinned videos (up to 3, first in the list) are not counted: they are read beside the newest unless `excludePinnedVideos` is on.",
            "default": 3
          },
          "excludePinnedVideos": {
            "title": "Leave the pinned videos out",
            "type": "boolean",
            "description": "A profile's pinned videos come first in its list (up to 3); on: they are not read.",
            "default": false
          },
          "videosNewerThan": {
            "title": "Videos newer than",
            "type": "string",
            "description": "Only a profile's videos uploaded at or after this time (a date or a span such as `30 days`), read from the video's id."
          },
          "videosOlderThan": {
            "title": "Videos older than",
            "type": "string",
            "description": "Only a profile's videos uploaded at or before this time (the same forms)."
          },
          "readCountry": {
            "title": "Read comments from",
            "enum": [
              "US",
              "GB",
              "DE",
              "FR",
              "CA",
              "BR",
              "JP",
              "MX",
              "AU"
            ],
            "type": "string",
            "description": "The country TikTok's comment list is read from. The list is a per-region view: which comments come first, the like counts and the list's total differ by country (an ordinary video showed 13-39 of the same 50 first comments in the US and in other countries). Every row names the data centre and the region it was read from. TikTok often walls readers in Canada, Brazil, Japan, Mexico and Australia (measured in November 2026): a run from there can end PARTIAL, and a video TikTok refuses is a free `failed` row. The US, the UK, Germany and France read reliably.",
            "default": "US"
          },
          "secondView": {
            "title": "Read the list on a second view",
            "type": "boolean",
            "description": "When a video's list ends before `commentsPerVideo` (or 0: all), read it once more from another country's data centre and add the comments the first view did not serve (up to a fifth more on ordinary videos; each comment once). Off: one read.",
            "default": true
          },
          "includeRawRecord": {
            "title": "Include TikTok's raw record",
            "type": "boolean",
            "description": "Add each comment's record as TikTok served it, in `raw`.",
            "default": false
          },
          "maxItems": {
            "title": "Max comments (whole run)",
            "minimum": 0,
            "maximum": 10000000,
            "type": "integer",
            "description": "The most charged rows (comments and replies) of the whole run; 0 = no cap beyond your charge limit. Every input still gets its row.",
            "default": 0
          },
          "proxyUrl": {
            "title": "Proxy URL",
            "type": "string",
            "description": "Your own proxy (scheme://user:pass@host:port) for every call instead of ours. Leave empty: the Actor brings its own connections at no cost to you."
          },
          "feedback": {
            "title": "Feedback to the maintainers",
            "maxLength": 2000,
            "type": "string",
            "description": "A note to the people who maintain this Actor: what you needed and did not get. For example a missing field, a wrong or empty result, or the Actor you switch from or to, and why. The run does not read it: the rows and the charges stay the same. A person reads every note."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}