{
  "openapi": "3.0.1",
  "info": {
    "title": "(NEW) TikTok Scraper – Videos, Profiles, Hashtags, Comments",
    "description": "Scrape TikTok videos, hashtags, profiles, search, comments and followers from $0.35 per 1,000. Clockworks-compatible input, AI analysis, no login.",
    "version": "0.0",
    "x-build-id": "V2W1Rayh6bwyR1auN"
  },
  "servers": [
    {
      "url": "https://api.apify.com/v2"
    }
  ],
  "paths": {
    "/acts/harshmaur~tiktok-scraper/run-sync-get-dataset-items": {
      "post": {
        "operationId": "run-sync-get-dataset-items-harshmaur-tiktok-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/harshmaur~tiktok-scraper/runs": {
      "post": {
        "operationId": "runs-sync-harshmaur-tiktok-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/harshmaur~tiktok-scraper/run-sync": {
      "post": {
        "operationId": "run-sync-harshmaur-tiktok-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": {
          "profiles": {
            "title": "😎 Profiles (usernames)",
            "type": "array",
            "description": "TikTok usernames to scrape, with or without the @. Each profile returns its videos (up to the number below) with the author's profile data on every row. A profile link such as https://www.tiktok.com/@khaby.lame also works.",
            "items": {
              "type": "string"
            }
          },
          "hashtags": {
            "title": "#️⃣ Hashtags",
            "type": "array",
            "description": "Hashtags to scrape, with or without the #. Each hashtag returns its videos up to the number below. Turn on 'Exact hashtag match' in the filters to keep only videos that really carry the tag.",
            "items": {
              "type": "string"
            }
          },
          "resultsPerPage": {
            "title": "💯 Videos per profile, hashtag, search or music",
            "minimum": 0,
            "maximum": 10000,
            "type": "integer",
            "description": "The most videos to take from EACH profile, hashtag, search keyword, music or listing link. Also caps related videos per video URL. Video URLs you paste are always scraped.",
            "default": 1
          },
          "maxItems": {
            "title": "🛑 Max videos in total (optional)",
            "minimum": 0,
            "type": "integer",
            "description": "A hard cap on videos for the whole run, across all inputs. Use it to keep the cost of a large list predictable. Leave empty for no total cap."
          },
          "profileScrapeSections": {
            "title": "Profile sections",
            "uniqueItems": true,
            "type": "array",
            "description": "Which tabs of each profile to scrape: the profile's own videos, the videos it reposted, or both.",
            "items": {
              "type": "string",
              "enum": [
                "videos",
                "reposts",
                "stories"
              ],
              "enumTitles": [
                "Videos",
                "Reposts",
                "Stories (not available: TikTok returns none without login)"
              ]
            },
            "default": [
              "videos"
            ]
          },
          "profileSorting": {
            "title": "Profile video order",
            "enum": [
              "latest",
              "popular",
              "oldest"
            ],
            "type": "string",
            "description": "Latest returns the newest videos first, Oldest the first videos the account posted, Popular the most played. Applies to the Videos tab.",
            "default": "latest"
          },
          "excludePinnedPosts": {
            "title": "Skip pinned videos",
            "type": "boolean",
            "description": "Leave out the videos a creator pinned to the top of the profile. Pinned videos are often old, so skipping them keeps a 'latest videos' run truly recent.",
            "default": false
          },
          "maxFollowersPerProfile": {
            "title": "Followers per profile",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "How many followers of each profile to list. Each follower is one row with dataType 'follower'. 0 skips followers.",
            "default": 0
          },
          "maxFollowingPerProfile": {
            "title": "Following per profile",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "How many accounts each profile follows to list. Each one is a row with dataType 'follower' and connectionType 'following'. 0 skips this list.",
            "default": 0
          },
          "oldestPostDateUnified": {
            "title": "Videos posted on or after",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])(T[0-2]\\d:[0-5]\\d(:[0-5]\\d)?(\\.\\d+)?Z?)?$|^\\d+(\\s*days?)?$",
            "type": "string",
            "description": "Only keep videos posted on or after this date. Through the API you can also send a number of days, for example 30 for the last 30 days."
          },
          "newestPostDate": {
            "title": "Videos posted on or before",
            "pattern": "^(\\d{4})-(0[1-9]|1[0-2])-(0[1-9]|[12]\\d|3[01])(T[0-2]\\d:[0-5]\\d(:[0-5]\\d)?(\\.\\d+)?Z?)?$|^\\d+(\\s*days?)?$",
            "type": "string",
            "description": "Only keep videos posted on or before this date. Pair it with the field above for a date window."
          },
          "leastDiggs": {
            "title": "Minimum likes",
            "minimum": 0,
            "type": "integer",
            "description": "Only keep videos with at least this many likes (hearts). Works together with the date filter."
          },
          "mostDiggs": {
            "title": "Maximum likes",
            "minimum": 0,
            "type": "integer",
            "description": "Only keep videos with at most this many likes. Useful to find smaller creators or posts before they take off."
          },
          "hashtagMatch": {
            "title": "Hashtag match",
            "enum": [
              "related",
              "exact"
            ],
            "type": "string",
            "description": "Related returns everything TikTok files under the hashtag, including videos that do not carry it. Exact keeps only videos whose caption contains the hashtag. Videos filtered out are not charged.",
            "default": "related"
          },
          "searchQueries": {
            "title": "Search keywords",
            "type": "array",
            "description": "Keywords to search for. Each keyword returns up to 'Videos per profile, hashtag, search or music' videos, or up to 'Profiles per keyword' accounts when the section is Profiles.",
            "items": {
              "type": "string"
            }
          },
          "searchSection": {
            "title": "Search tab",
            "enum": [
              "",
              "/video",
              "/user"
            ],
            "type": "string",
            "description": "Top and Videos both return videos for the keyword, with the order and period options below. Profiles returns the accounts that posted the matching videos, one row each.",
            "default": ""
          },
          "maxProfilesPerQuery": {
            "title": "Profiles per keyword",
            "minimum": 0,
            "maximum": 1000,
            "type": "integer",
            "description": "How many accounts to return per keyword when the search tab is Profiles.",
            "default": 10
          },
          "videoSearchSorting": {
            "title": "Video search order",
            "enum": [
              "MOST_RELEVANT",
              "MOST_LIKED",
              "LATEST"
            ],
            "type": "string",
            "description": "Order of video search results. No extra charge.",
            "default": "MOST_RELEVANT"
          },
          "videoSearchDateFilter": {
            "title": "Video search period",
            "enum": [
              "ALL_TIME",
              "PAST_24_HOURS",
              "PAST_WEEK",
              "PAST_MONTH",
              "LAST_3_MONTHS",
              "LAST_6_MONTHS"
            ],
            "type": "string",
            "description": "Keep only search results posted within this period. No extra charge.",
            "default": "ALL_TIME"
          },
          "postURLs": {
            "title": "Video URLs",
            "type": "array",
            "description": "Links to single TikTok videos or photo posts, including short vm.tiktok.com and vt.tiktok.com links, or bare video IDs. Every link returns one row, or a free failure row that says why it could not be read.",
            "items": {
              "type": "string"
            }
          },
          "scrapeRelatedVideos": {
            "title": "Also scrape related videos",
            "type": "boolean",
            "description": "For each video URL, also return the videos TikTok recommends next to it, up to 'Videos per profile, hashtag, search or music'.",
            "default": false
          },
          "musics": {
            "title": "Music (sounds)",
            "type": "array",
            "description": "TikTok sound links (tiktok.com/music/…) or music IDs. Each one returns videos that use the sound.",
            "items": {
              "type": "string"
            }
          },
          "startUrls": {
            "title": "Any TikTok URL",
            "type": "array",
            "description": "Paste TikTok links of any kind in one list: profile, hashtag, search, music or video pages. Each link is handled like the matching field above.",
            "items": {
              "type": "string"
            }
          },
          "commentsPerPost": {
            "title": "Comments per video",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "The most comments, replies included, to collect from each video. 0 skips comments.",
            "default": 0
          },
          "topLevelCommentsPerPost": {
            "title": "Top-level comments per video (optional)",
            "minimum": 0,
            "type": "integer",
            "description": "Cap on comments that are not replies. Leave empty to let 'Comments per video' decide alone."
          },
          "maxRepliesPerComment": {
            "title": "Replies per comment",
            "minimum": 0,
            "maximum": 100000,
            "type": "integer",
            "description": "How many replies to collect under each comment. Replies carry repliesToId, the cid of the comment they answer. 0 skips replies.",
            "default": 0
          },
          "shouldDownloadVideos": {
            "title": "Download videos without watermark ($)",
            "type": "boolean",
            "description": "Save each video's MP4 file, without the TikTok watermark.",
            "default": false
          },
          "shouldDownloadCovers": {
            "title": "Download cover images",
            "type": "boolean",
            "description": "Save the thumbnail of each video.",
            "default": false
          },
          "shouldDownloadSlideshowImages": {
            "title": "Download slideshow images",
            "type": "boolean",
            "description": "Save every image of photo and slideshow posts. Links go to slideshowImageLinks.",
            "default": false
          },
          "shouldDownloadAvatars": {
            "title": "Download profile pictures",
            "type": "boolean",
            "description": "Save the author's avatar for each video.",
            "default": false
          },
          "shouldDownloadMusicCovers": {
            "title": "Download sound covers",
            "type": "boolean",
            "description": "Save the cover art of the sound each video uses.",
            "default": false
          },
          "downloadSubtitlesOptions": {
            "title": "Subtitles and transcripts",
            "enum": [
              "NEVER_DOWNLOAD_SUBTITLES",
              "DOWNLOAD_SUBTITLES",
              "DOWNLOAD_AND_TRANSCRIBE_VIDEOS_WITHOUT_SUBTITLES",
              "TRANSCRIBE_ALL_VIDEOS"
            ],
            "type": "string",
            "description": "Download subtitles saves the captions TikTok already has (links in videoMeta.subtitleLinks). The transcribe options also write a speech-to-text transcript to videoMeta.transcript, either only for videos without captions or for all videos.",
            "default": "NEVER_DOWNLOAD_SUBTITLES"
          },
          "aiAnalysis": {
            "title": "AI labels: category, sponsored, brand safety, sentiment ($)",
            "type": "boolean",
            "description": "Adds aiAnalysis to each video: a content category, whether it looks sponsored, whether it is brand safe, and its sentiment.",
            "default": false
          },
          "aiQuestions": {
            "title": "Your own yes/no questions",
            "maxItems": 20,
            "type": "array",
            "description": "Up to 20 questions answered with true or false for every video, for example 'Does the video show a dog?'. Answers go to aiAnalysis.answers. Needs the AI labels option.",
            "items": {
              "type": "string"
            }
          },
          "aiVideoSummary": {
            "title": "AI video summary ($)",
            "type": "boolean",
            "description": "A short summary of what the video is about, from its picture and sound. Saved in videoMeta.aiVideoSummary.",
            "default": false
          },
          "aiVideoDescription": {
            "title": "AI scene-by-scene description ($)",
            "type": "boolean",
            "description": "A timed description of what is seen and heard in each scene. Saved in videoMeta.aiVideoDescription.",
            "default": false
          },
          "proxyCountryCode": {
            "title": "Scrape as if from country",
            "enum": [
              "None",
              "AF",
              "AL",
              "DZ",
              "AS",
              "AD",
              "AO",
              "AI",
              "AG",
              "AR",
              "AM",
              "AU",
              "AT",
              "AZ",
              "BS",
              "BH",
              "BB",
              "BY",
              "BE",
              "BZ",
              "BJ",
              "BM",
              "BT",
              "BO",
              "BA",
              "BW",
              "BR",
              "VG",
              "BN",
              "BG",
              "BF",
              "BI",
              "KH",
              "CM",
              "CA",
              "CV",
              "KY",
              "TD",
              "CL",
              "CO",
              "CK",
              "CR",
              "HR",
              "CY",
              "CZ",
              "CD",
              "DK",
              "DJ",
              "DO",
              "EC",
              "EG",
              "SV",
              "EE",
              "ET",
              "FK",
              "FJ",
              "FI",
              "FR",
              "PF",
              "GA",
              "GE",
              "DE",
              "GH",
              "GI",
              "GR",
              "GL",
              "GD",
              "GP",
              "GT",
              "GN",
              "GW",
              "GY",
              "HN",
              "HU",
              "IS",
              "ID",
              "IQ",
              "IE",
              "IM",
              "IL",
              "IT",
              "CI",
              "JM",
              "JP",
              "JE",
              "KZ",
              "KE",
              "XK",
              "KW",
              "LA",
              "LV",
              "LB",
              "LS",
              "LR",
              "LY",
              "LT",
              "LU",
              "MO",
              "MG",
              "MW",
              "MY",
              "MV",
              "ML",
              "MT",
              "MH",
              "MQ",
              "MR",
              "MU",
              "MX",
              "MD",
              "MC",
              "MN",
              "ME",
              "MA",
              "MZ",
              "MM",
              "NA",
              "NR",
              "NP",
              "NL",
              "NZ",
              "NI",
              "NG",
              "MK",
              "NO",
              "OM",
              "PS",
              "PA",
              "PG",
              "PY",
              "PE",
              "PH",
              "PL",
              "PT",
              "PR",
              "QA",
              "CG",
              "RO",
              "RU",
              "RW",
              "RE",
              "KN",
              "LC",
              "MF",
              "PM",
              "VC",
              "SM",
              "SA",
              "SN",
              "RS",
              "SL",
              "SG",
              "SX",
              "SK",
              "SB",
              "SO",
              "ZA",
              "KR",
              "ES",
              "LK",
              "SR",
              "SZ",
              "SE",
              "CH",
              "TW",
              "TJ",
              "TZ",
              "TH",
              "TG",
              "TO",
              "TT",
              "TN",
              "TR",
              "TC",
              "TV",
              "VI",
              "UG",
              "UA",
              "AE",
              "GB",
              "US",
              "UY",
              "VE",
              "VN",
              "WF",
              "YE",
              "ZM",
              "ZW",
              "AX"
            ],
            "type": "string",
            "description": "Load TikTok from this country, to see the search and hashtag results people there see. None lets the scraper pick the most reliable route.",
            "default": "None"
          },
          "mcpConnector": {
            "title": "Send results to an app (MCP connector)",
            "type": "string",
            "description": "Pick an authorized MCP connector (Slack, Notion, Airtable, Google Sheets, …) to receive the scraped videos. Your credentials stay in Apify and are never exposed to this actor (Apify's proxy injects them). Leave empty to scrape only. Tip: schedule a hashtag or a creator to get new videos in your workspace."
          },
          "mcpMode": {
            "title": "Delivery mode",
            "enum": [
              "perPost",
              "summary"
            ],
            "type": "string",
            "description": "perPost: one message or record per video. summary: a single digest of the whole run.",
            "default": "perPost"
          },
          "mcpTarget": {
            "title": "Target page / database / channel",
            "type": "string",
            "description": "Where to write — the destination ID the tool needs: a Notion database/page ID, a Google Sheet ID, or a Slack channel. Leave blank for connectors that post to a default location. Advanced shapes go in Arguments JSON below."
          },
          "mcpMessage": {
            "title": "Message template",
            "type": "string",
            "description": "Template for each message. Use {{field}} placeholders from any video field, nested paths included — common ones: {{text}}, {{webVideoUrl}}, {{authorMeta.name}}, {{playCount}}, {{diggCount}}, {{commentCount}}, {{shareCount}}, {{createTimeISO}}. Missing fields render empty.",
            "default": "*@{{authorMeta.name}}* — {{diggCount}} likes · {{playCount}} views\n{{text}}\n{{webVideoUrl}}"
          },
          "mcpTool": {
            "title": "Tool override (advanced)",
            "type": "string",
            "description": "Force a specific tool name on the connector (e.g. send_message, create_page, append_row). Leave empty to auto-detect the connector's write/notify tool."
          },
          "mcpArguments": {
            "title": "Tool arguments override (advanced)",
            "type": "object",
            "description": "Extra/override arguments merged into each tool call as JSON — e.g. {\"channel\": \"#tiktok\"} for Slack. {{field}} placeholders work inside string values too, so you can nest live data into any shape — e.g. Notion: {\"properties\": {\"Title\": {\"title\": [{\"text\": {\"content\": \"{{text}}\"}}]}, \"Link\": {\"url\": \"{{webVideoUrl}}\"}}}."
          },
          "mcpMaxItems": {
            "title": "Max videos to send",
            "minimum": 1,
            "maximum": 1000,
            "type": "integer",
            "description": "Safety cap on how many videos are piped to the connector per run (perPost mode). Protects against flooding the destination.",
            "default": 50
          },
          "mcpServerUrl": {
            "title": "MCP server URL (dev / diagnostic)",
            "type": "string",
            "description": "Advanced/testing only. Connect directly to a raw MCP server URL, bypassing the connector above. For real use prefer a connector — your credentials then stay in Apify. When set, this overrides the connector."
          },
          "mcpServerToken": {
            "title": "MCP server token (dev / diagnostic)",
            "type": "string",
            "description": "Bearer token for the dev MCP server URL above. A token entered here IS visible to the actor at runtime — for production use an MCP Connector instead. Ignored unless the URL is set."
          }
        }
      },
      "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
                  }
                }
              }
            }
          }
        }
      }
    }
  }
}