Skip to content

API reference

TikTok API

Public videos, profiles, followers, posts, sounds, comments, replies and search results as JSON, with engagement counts and playable media URLs. No TikTok login needed.

POST/api/v1/tiktokJSON body: {"endpoint", "params"}1 credit per request
Only successful calls are chargedTimes out after 30 seconds

Every call is a POST with a JSON body naming the endpoint and its params:

endpointReturnsRequired
/Video details and media URLsurl
/user/infoProfile and countersunique_id or user_id
/user/postsAn account's videosunique_id
/user/followersAccounts that follow a useruser_id
/user/followingAccounts a user followsuser_id
/user/searchAccounts matching a keywordkeywords
/feed/searchVideos matching a keywordkeywords
/music/infoSound detailsmusic_id
/music/postsVideos using a soundmusic_id
/comment/listComments on a videourl
/comment/replyReplies to a commentcomment_id, video_id or url

Response envelope

Successful calls return success, data (the endpoint's payload), processed_time, duration, statusCode and creditsUsed. Errors return success: false, an error message and a code equal to the HTTP status, for example {"success": false, "error": "unique_id is required.", "code": 400}.

Quick start

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/user/info",
    "params": {"unique_id": "tiktok"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/user/info",
        "params": {"unique_id": "tiktok"},
    },
    timeout=60,
)
data = response.json()
print(data["data"]["user"]["nickname"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/user/info",
    params: { unique_id: "tiktok" },
  }),
});
const data = await response.json();
console.log(data.data.user.nickname);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/user/info",
        "params" => ["unique_id" => "tiktok"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["user"]["nickname"]);

Errors

{
  "success": false,
  "error": "unique_id is required.",
  "code": 400
}

Video details

Metadata, statistics, author, sound and playable media URLs for one video.

POST/api/v1/tiktokendpoint "/"1 credit

Parameters in params

  • urlstringRequired
    The video URL, for example https://www.tiktok.com/@user/video/7682907275505224982. It must contain /video/; for profiles, use User profile.
  • hdstring
    Set to 1 to ask for the HD video URL when one is available.
This endpoint names the video ID id. List endpoints return the same value as video_id.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/",
    "params": {
      "url": "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982"
    }
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/",
        "params": {
            "url": "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
        },
    },
    timeout=60,
)
data = response.json()
print(data["data"]["title"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/",
    params: {
      url: "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
    },
  }),
});
const data = await response.json();
console.log(data.data.title);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/",
        "params" => [
            "url" => "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
        ],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["title"]);

Response

200 OK
{
  "success": true,
  "data": {
    "id": "7682907275505224982",
    "title": "luna eterna #lofihouse #electronicmusic #club #fyp #2000smusic",
    "duration": 31,
    "create_time": 1788816252,
    "region": "IE",
    "play_count": 354200,
    "digg_count": 54000,
    "comment_count": 740,
    "share_count": 2873,
    "collect_count": 20159,
    "play": "https://www.tiktok.com/aweme/v1/play/?…",
    "cover": "https://p16-common-sign.tiktokcdn-us.com/…",
    "author": {
      "id": "7002179649582711813",
      "unique_id": "aetherrr.flp",
      "nickname": "aether",
      "avatar": "https://p16-common-sign.tiktokcdn-us.com/…"
    },
    "music_info": {
      "id": "7682907287056337667",
      "title": "original sound - aetherrr.flp",
      "author": "aether",
      "duration": 31
    },
    …
  },
  "processed_time": 1.2008,
  "duration": "1.20",
  "statusCode": 200,
  "creditsUsed": 1
}

User profile

Profile details and counters for an account, looked up by username or by numeric ID.

POST/api/v1/tiktokendpoint "/user/info"1 credit

Parameters in params

  • unique_idstring
    The username without @. An @handle or a profile URL such as https://www.tiktok.com/@tiktok works too. Required unless you send user_id.
  • user_idstring
    The numeric account ID, the data.user.id of an earlier lookup. Used when unique_id is left out. Useful after an account changes its username.
Send one of the two. Both return the same response shape.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/user/info",
    "params": {"unique_id": "tiktok"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/user/info",
        "params": {"unique_id": "tiktok"},
    },
    timeout=60,
)
data = response.json()
print(data["data"]["stats"]["followerCount"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/user/info",
    params: { unique_id: "tiktok" },
  }),
});
const data = await response.json();
console.log(data.data.stats.followerCount);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/user/info",
        "params" => ["unique_id" => "tiktok"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["stats"]["followerCount"]);

Response

200 OK
{
  "success": true,
  "data": {
    "user": {
      "id": "107955",
      "uniqueId": "tiktok",
      "nickname": "TikTok",
      "signature": "Your next discovery is waiting on TikTok.",
      "verified": true,
      "privateAccount": false,
      "secUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM",
      "avatarLarger": "https://p19-common-sign.tiktokcdn-us.com/…",
      …
    },
    "stats": {
      "followerCount": 96000000,
      "followingCount": 1,
      "heartCount": 464900000,
      "videoCount": 1509,
      …
    }
  },
  "processed_time": 0.6777,
  "duration": "0.68",
  "statusCode": 200,
  "creditsUsed": 1
}

User posts

An account's videos, newest first, one page at a time.

POST/api/v1/tiktokendpoint "/user/posts"1 credit

Parameters in params

  • unique_idstringRequired
    Username, @handle or profile URL.
  • countintegerDefault 10
    Videos per page, up to 10 (larger values are capped at 10). Pages can be shorter than asked.
  • cursorstring
    The cursor from the previous page. Leave it out for the first page.
Keep paging while hasMore is set. See Pagination.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/user/posts",
    "params": {"unique_id": "tiktok", "count": 10}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/user/posts",
        "params": {"unique_id": "tiktok", "count": 10},
    },
    timeout=60,
)
data = response.json()
print(data["data"]["cursor"], data["data"]["hasMore"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/user/posts",
    params: { unique_id: "tiktok", count: 10 },
  }),
});
const data = await response.json();
console.log(data.data.cursor, data.data.hasMore);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/user/posts",
        "params" => ["unique_id" => "tiktok", "count" => 10],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
echo $data["data"]["cursor"], " ", $data["data"]["hasMore"], PHP_EOL;

Response

200 OK
{
  "success": true,
  "data": {
    "videos": [
      {
        "video_id": "7692114317151423775",
        "title": "ATEEZ on the FYF. BTS on tour. dance challenges on repeat…",
        "play_count": 38600,
        "digg_count": 1151,
        "comment_count": 209,
        "create_time": 1790959957,
        "author": {
          "unique_id": "tiktok",
          "nickname": "TikTok",
          …
        },
        …
      },
      …
    ],
    "cursor": "1788444219000",
    "hasMore": true
  },
  "processed_time": 1.6474,
  "duration": "1.65",
  "statusCode": 200,
  "creditsUsed": 1
}

Followers and following

The accounts that follow a user, or that the user follows, each with its profile and counters.

POST/api/v1/tiktokendpoints "/user/followers", "/user/following"1 credit

Parameters in params

  • user_idstringRequired
    The numeric account ID: data.user.id from User profile. A username is rejected with 400.
  • countintegerDefault 20
    Accounts to return, 1 to 50. TikTok can return fewer.
Each call returns one page and there is no cursor, so raise count (up to 50) to get more accounts. /user/followers returns data.followers and /user/following returns data.followings. total is the account's full follower or following count, not the number of accounts returned.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/user/following",
    "params": {"user_id": "7664638705177150477", "count": 20}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/user/following",
        "params": {"user_id": "7664638705177150477", "count": 20},
    },
    timeout=60,
)
data = response.json()
print(data["data"]["total"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/user/following",
    params: { user_id: "7664638705177150477", count: 20 },
  }),
});
const data = await response.json();
console.log(data.data.total);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/user/following",
        "params" => ["user_id" => "7664638705177150477", "count" => 20],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["total"]);

Response

200 OK
{
  "success": true,
  "data": {
    "followings": [
      {
        "id": "7566352102659064887",
        "unique_id": "freedom250",
        "nickname": "Freedom 250",
        "signature": "Freedom 250 is a non-partisan organization delivering pres…",
        "verified": true,
        "region": "US",
        "follower_count": 120894,
        "following_count": 72,
        "aweme_count": 167,
        "total_favorited": 1253317,
        "avatar": "https://p16-common-sign.tiktokcdn-eu.com/…",
        …
      },
      …
    ],
    "total": 23
  },
  "duration": "0.82",
  "statusCode": 200,
  "creditsUsed": 1
}

The accounts NASA follows (user ID 7664638705177150477). aweme_count is an account's video count and total_favorited its total likes. /user/followers returns the same fields in data.followers.

Sound details

Title, author, duration, audio URL and how many videos use a sound.

POST/api/v1/tiktokendpoint "/music/info"1 credit

Parameters in params

  • music_idstringRequired
    The sound ID. You can send the sound page URL as url instead.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/music/info",
    "params": {"music_id": "7683546066251827217"}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/music/info",
        "params": {"music_id": "7683546066251827217"},
    },
    timeout=60,
)
data = response.json()
print(data["data"]["video_count"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/music/info",
    params: { music_id: "7683546066251827217" },
  }),
});
const data = await response.json();
console.log(data.data.video_count);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/music/info",
        "params" => ["music_id" => "7683546066251827217"],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["video_count"]);

Response

200 OK
{
  "success": true,
  "data": {
    "id": "7683546066251827217",
    "title": "Hoe Craft",
    "author": "MC",
    "album": "Hoe Craft",
    "duration": 60,
    "original": false,
    "video_count": 218,
    "play": "https://sf16.tiktokcdn-us.com/…",
    "cover": "https://p16-common.tiktokcdn-us.com/…"
  },
  "processed_time": 0.1327,
  "duration": "0.13",
  "statusCode": 200,
  "creditsUsed": 1
}

Videos using a sound

Videos made with a sound, one page at a time.

POST/api/v1/tiktokendpoint "/music/posts"1 credit

Parameters in params

  • music_idstringRequired
    The sound ID, or the sound page URL as url.
  • countintegerDefault 10
    Videos per page, 1 to 35. Pages can be shorter than asked.
  • cursorinteger
    The cursor from the previous page.
Keep paging while hasMore is 1. See Pagination.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/music/posts",
    "params": {"music_id": "7682907287056337667", "count": 30}
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/music/posts",
        "params": {"music_id": "7682907287056337667", "count": 30},
    },
    timeout=60,
)
data = response.json()
print(data["data"]["cursor"], data["data"]["hasMore"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/music/posts",
    params: { music_id: "7682907287056337667", count: 30 },
  }),
});
const data = await response.json();
console.log(data.data.cursor, data.data.hasMore);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/music/posts",
        "params" => ["music_id" => "7682907287056337667", "count" => 30],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
echo $data["data"]["cursor"], " ", $data["data"]["hasMore"], PHP_EOL;

Response

200 OK
{
  "success": true,
  "data": {
    "videos": [
      {
        "video_id": "7682907275505224982",
        "title": "luna eterna #lofihouse #electronicmusic #club #fyp #2000smusic",
        "play_count": 353558,
        "digg_count": 53947,
        "comment_count": 741,
        "create_time": 1788816252,
        "play": "https://v19.tiktokcdn.com/…",
        "author": {
          "id": "7002179649582711813",
          "unique_id": "aetherrr.flp",
          "nickname": "aether"
        },
        …
      },
      …
    ],
    "cursor": 12,
    "hasMore": 1
  },
  "processed_time": 1.9064,
  "duration": "1.91",
  "statusCode": 200,
  "creditsUsed": 1
}

Comments

Comments on a video, with their authors.

POST/api/v1/tiktokendpoint "/comment/list"1 credit

Parameters in params

  • urlstringRequired
    The video URL.
  • countintegerDefault 20
    Comments per page, 1 to 50.
  • cursorinteger
    The cursor from the previous page.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/comment/list",
    "params": {
      "url": "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
      "count": 20
    }
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/comment/list",
        "params": {
            "url": "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
            "count": 20,
        },
    },
    timeout=60,
)
data = response.json()
print(data["data"]["total"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/comment/list",
    params: {
      url: "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
      count: 20,
    },
  }),
});
const data = await response.json();
console.log(data.data.total);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/comment/list",
        "params" => [
            "url" => "https://www.tiktok.com/@aetherrr.flp/video/7682907275505224982",
            "count" => 20,
        ],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["total"]);

Response

200 OK
{
  "success": true,
  "data": {
    "comments": [
      {
        "id": "7683068165794579233",
        "text": "For all who like this vibe",
        "digg_count": 1698,
        "reply_total": 16,
        "create_time": 1788853752,
        "video_id": "7682907275505224982",
        "user": {
          "unique_id": "tempeo.records",
          "nickname": "Tempeo Records",
          …
        }
      },
      …
    ],
    "cursor": 10,
    "hasMore": true,
    "total": 740
  },
  "processed_time": 0.3403,
  "duration": "0.34",
  "statusCode": 200,
  "creditsUsed": 1
}

To read the replies to a comment, pass its id to Comment replies.

Comment replies

The replies to one comment, with their authors.

POST/api/v1/tiktokendpoint "/comment/reply"1 credit

Parameters in params

  • comment_idstringRequired
    The parent comment's id from Comments. Comments with replies have reply_total above 0.
  • video_idstringRequired
    The video the comment is on. You can send the video URL as url instead.
  • countintegerDefault 20
    Replies per page, 1 to 50.
  • cursorinteger
    The cursor from the previous page.
Keep paging while hasMore is set. total is the number of replies to the comment.

Request

curl -X POST "https://scrapingbot.io/api/v1/tiktok" \
  -H "x-api-key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "endpoint": "/comment/reply",
    "params": {
      "video_id": "7692161454694206733",
      "comment_id": "7692163746915566368"
    }
  }'
import requests

response = requests.post(
    "https://scrapingbot.io/api/v1/tiktok",
    headers={"x-api-key": "YOUR_API_KEY"},
    json={
        "endpoint": "/comment/reply",
        "params": {
            "video_id": "7692161454694206733",
            "comment_id": "7692163746915566368",
        },
    },
    timeout=60,
)
data = response.json()
print(data["data"]["total"])
const response = await fetch("https://scrapingbot.io/api/v1/tiktok", {
  method: "POST",
  headers: {
    "x-api-key": "YOUR_API_KEY",
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    endpoint: "/comment/reply",
    params: {
      video_id: "7692161454694206733",
      comment_id: "7692163746915566368",
    },
  }),
});
const data = await response.json();
console.log(data.data.total);
<?php
$ch = curl_init("https://scrapingbot.io/api/v1/tiktok");
curl_setopt_array($ch, [
    CURLOPT_POST => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => [
        "x-api-key: YOUR_API_KEY",
        "Content-Type: application/json",
    ],
    CURLOPT_POSTFIELDS => json_encode([
        "endpoint" => "/comment/reply",
        "params" => [
            "video_id" => "7692161454694206733",
            "comment_id" => "7692163746915566368",
        ],
    ]),
]);
$data = json_decode(curl_exec($ch), true);
print_r($data["data"]["total"]);

Response

200 OK
{
  "success": true,
  "data": {
    "comments": [
      {
        "id": "7692165300930315021",
        "text": "Bro we haven’t even had Artemis III yet",
        "digg_count": 6,
        "create_time": 1790971850,
        "video_id": "7692161454694206733",
        "user": {
          "unique_id": "zx6paul",
          "nickname": "Zx6Paul",
          …
        },
        …
      },
      …
    ],
    "cursor": 2,
    "hasMore": false,
    "total": 2
  },
  "processed_time": 0.982,
  "duration": "1.05",
  "statusCode": 200,
  "creditsUsed": 1
}

Pagination

List endpoints (/user/posts, /music/posts, /feed/search, /comment/list, /comment/reply) return one page plus two fields that tell you how to get the next one:

  • cursor: send it back unchanged on the next request (as offset or cursor for /feed/search, together with search_id).
  • hasMore: keep going while it is 1 (some endpoints say true). Only 0 or false means the end.
Page sizes vary. TikTok often returns around 10 items even when you ask for more, and a short page doesn't mean you've reached the end. Rely on hasMore, not on the page size.

/user/search, /user/followers and /user/following return a single page; raise count to get more.

  • Use video_id as the stable ID and de-duplicate on it; the same video can appear on two pages.
  • Each page is a separate request and costs 1 credit.

Collect every video that uses a sound

import requests

API = "https://scrapingbot.io/api/v1/tiktok"
HEADERS = {"x-api-key": "YOUR_API_KEY"}

videos, seen, cursor = [], set(), None
while True:
    params = {"music_id": "7682907287056337667", "count": 30}
    if cursor is not None:
        params["cursor"] = cursor
    body = {"endpoint": "/music/posts", "params": params}
    page = requests.post(
        API, headers=HEADERS, json=body, timeout=60
    ).json()
    if not page.get("success"):
        raise RuntimeError(page.get("error"))
    data = page["data"]
    for video in data.get("videos", []):
        if video["video_id"] not in seen:
            seen.add(video["video_id"])
            videos.append(video)
    if not data.get("hasMore"):  # 0 or false: no more pages
        break
    cursor = data["cursor"]

print(len(videos), "videos")

Stuck on something?

Try requests in the dashboard playgrounds, check every call in your usage log, or write to [email protected]. A real developer answers.