{
  "openapi": "3.0.1",
  "info": {
    "title": "TikTok Comments Scraper By Real Comment Filter",
    "description": "TikTok Comments Scraper extracts comments from public TikTok videos at scale. Collect comment text, usernames, likes, replies, and timestamps. Ideal for sentiment analysis, audience research, moderation workflows, and social media insights.",
    "version": "0.1",
    "x-build-id": "n2yAITDeFGWW0k4iY"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/scraper-engine~tiktok-comments-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-scraper-engine-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/scraper-engine~tiktok-comments-scraper/runs": {
      "post": {
        "operationId": "runs-sync-scraper-engine-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/scraper-engine~tiktok-comments-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-scraper-engine-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": "🎬 TikTok video links",
            "type": "array",
            "description": "Video pages to pull the comment section from. Full links, short vm./vt. links and bare numeric video IDs all work. Example: https://www.tiktok.com/@mrbeast/video/7578547467189374239",
            "items": {
              "type": "string"
            }
          },
          "maxCommentsPerVideo": {
            "title": "💬 Comments to keep per video",
            "minimum": 1,
            "type": "integer",
            "description": "How many UNIQUE comments to keep from each video. Duplicates are dropped before they count toward this number, so asking for 100 gives you 100 distinct comments — not 100 rows containing 13 repeats. Default is 10.",
            "default": 10
          },
          "maxRepliesPerThread": {
            "title": "↩️ Replies to follow per comment",
            "minimum": 0,
            "type": "integer",
            "description": "Replies pulled from each comment thread, nested under `replies`. This scraper pages the reply endpoint properly, so values above 20 are genuinely delivered when the thread is that deep. Set 0 to skip replies entirely and run much faster. Default is 3.",
            "default": 3
          },
          "deduplicateBy": {
            "title": "🔑 De-duplicate rows by",
            "enum": [
              "commentId",
              "commentIdAndText"
            ],
            "type": "string",
            "description": "Comment ID only — removes the same comment returned on two different pages. Comment ID + same author & text — additionally folds a commenter who posted word-for-word the same thing twice under two different IDs.",
            "default": "commentId"
          },
          "collapseDuplicateTexts": {
            "title": "🗜️ Collapse identical comments into one row",
            "type": "boolean",
            "description": "Turn a wall of copy-pasted comments into one row per distinct text, keeping the most-liked example and reporting how many people wrote it in `duplicateTextCount`. Leave OFF to keep every commenter as their own row (each still labelled with its group). On a live 238-comment sample this found 13 texts spanning 36 rows.",
            "default": false
          },
          "mediaCommentHandling": {
            "title": "🎨 What to do with media comments",
            "enum": [
              "include",
              "onlyMedia",
              "excludeMedia"
            ],
            "type": "string",
            "description": "Keep everything, keep only the comments that contain an image or sticker, or drop them to leave a text-only dataset.",
            "default": "include"
          },
          "hideLikelySpam": {
            "title": "🧯 Hide rows that look like spam",
            "type": "boolean",
            "description": "Filters out rows whose `spamScore` reaches the threshold below. Leave OFF to keep every row and just read the score — recommended, since the score is advisory. Default is off.",
            "default": false
          },
          "spamScoreThreshold": {
            "title": "📊 Spam score needed to hide a row",
            "minimum": 0,
            "maximum": 100,
            "type": "integer",
            "description": "0-100. Weights: link in text 45, repeated text in this run 30, three or more @mentions 30, emoji-only text 15, author commented 3+ times in this run 15. At the default of 60 no single weak signal alone hides a row, but two independent ones do. Only used when the toggle above is on.",
            "default": 60
          },
          "creatorUsernames": {
            "title": "👤 TikTok usernames",
            "type": "array",
            "description": "Usernames without the @, one per line or pasted in bulk. Example: mrbeast",
            "items": {
              "type": "string"
            }
          },
          "videosPerCreator": {
            "title": "📺 Videos to take from each creator",
            "minimum": 1,
            "maximum": 1000000,
            "type": "integer",
            "description": "How many videos to collect per username before their comment sections are scraped. Default is 10.",
            "default": 10
          },
          "creatorTabs": {
            "title": "🗂️ Which profile tab to read",
            "minItems": 1,
            "uniqueItems": true,
            "type": "array",
            "description": "Videos is the profile's own uploads. Reposts is the reposted tab, which many profiles do not have at all.",
            "items": {
              "type": "string",
              "enum": [
                "videos",
                "reposts"
              ],
              "enumTitles": [
                "Videos (own uploads)",
                "Reposts"
              ]
            },
            "default": [
              "videos"
            ]
          },
          "videoOrder": {
            "title": "🔀 Order videos by",
            "enum": [
              "latest",
              "oldest",
              "popular"
            ],
            "type": "string",
            "description": "Newest first, oldest first, or most-liked. Oldest and Most liked are re-ordered locally from a wider candidate pool, so they cost more time. The date filters below apply to Newest and Oldest.",
            "default": "latest"
          },
          "videosPostedAfter": {
            "title": "📅 Only videos posted on or after",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$|^(\\d+)\\s*(day|week|month|year)s?$",
            "type": "string",
            "description": "Absolute (2026-01-31) or relative (3 months, 2 weeks, 10 days)."
          },
          "videosPostedBefore": {
            "title": "📆 Only videos posted on or before",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])$|^(\\d+)\\s*(day|week|month|year)s?$",
            "type": "string",
            "description": "Absolute (2026-06-30) or relative (1 month, 6 weeks)."
          },
          "skipPinnedVideos": {
            "title": "📌 Skip pinned videos",
            "type": "boolean",
            "description": "Pinned videos sit at the top of a profile and are often months old. Tick to ignore them.",
            "default": false
          },
          "aiEnhancement": {
            "title": "🤖 Ask an AI model to double-check each comment",
            "type": "boolean",
            "description": "Adds `aiIsSpam`, `aiCategory` (genuine / question / praise / criticism / joke / engagement_bait / promo_spam / scam) and `aiSpamReason`. Costs one provider call per 25 comments, billed by your provider, not here. Default is off.",
            "default": false
          },
          "aiModel": {
            "title": "🧠 AI model / provider",
            "enum": [
              "claude-haiku-4-5",
              "claude-sonnet-5",
              "claude-opus-4-8",
              "claude-fable-5",
              "gpt-4o-mini",
              "gpt-4o",
              "gpt-4.1-mini",
              "gpt-4.1",
              "o3-mini",
              "o1",
              "gemini-2.0-flash-lite",
              "gemini-2.0-flash",
              "gemini-1.5-pro",
              "gemini-2.5-flash",
              "gemini-2.5-pro",
              "grok-2-latest",
              "grok-3-mini",
              "grok-3",
              "grok-beta",
              "deepseek-chat",
              "deepseek-reasoner",
              "sonar",
              "sonar-pro",
              "sonar-reasoning",
              "mistral-small-latest",
              "mistral-large-latest"
            ],
            "type": "string",
            "description": "Provider auto-detected from the name: claude-*=Anthropic, gpt-*/o1/o3=OpenAI, gemini-*=Google, grok-*=xAI, deepseek-*=DeepSeek, sonar*=Perplexity, mistral-*=Mistral. The cheap mini/flash/haiku models are plenty for this classification.",
            "default": "claude-haiku-4-5"
          },
          "aiApiKey": {
            "title": "🔑 AI provider API key",
            "type": "string",
            "description": "Your own key for the provider selected above. Stored encrypted. If left empty the matching environment variable is used instead: ANTHROPIC_API_KEY, OPENAI_API_KEY, GOOGLE_API_KEY, XAI_API_KEY, DEEPSEEK_API_KEY, PERPLEXITY_API_KEY or MISTRAL_API_KEY."
          },
          "proxyConfiguration": {
            "title": "🌐 Proxy configuration",
            "type": "object",
            "description": "Optional. Used as the datacenter fallback stage if the direct request is blocked."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}