TikTok API & Scraper
The TikTok API reads public tiktok.com the way a logged-out visitor sees it, in 21 actions.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
user_profile returns an account's nickname, bio, verified and private flags, exact follower, following, like and video counts, whether it has a story up and whether it is LIVE. user_videos returns the newest 30 videos per call with exact play, like, comment, share, save and repost counts, music, hashtags, mentions and the paid-partnership flags, and pages back through the whole account. comments and comment_replies return the comment threads. user_stories returns the stories an account has up (on 2026-11-03, 55 of 400 creators checked had one, and all 59 accounts with a story returned it). user_live says whether an account is broadcasting now, with the room title, current viewers and start time. search_videos, search_users and search_photos search like the logged-out site; hashtag_info, hashtag_videos, music_info and music_videos read hashtag and sound pages; trending, feed and related_videos return TikTok's own recommendation feeds. Every field TikTok sends comes back as sent, next to the named fields.
What a TikTok field actually contains
Fields that read differently from how they look. Every row was measured against live tiktok.com on 2026-11-03.
| Field | What it holds |
|---|---|
| stats.play_count, like_count, ... | Exact counts from TikTok's statsV2 strings. TikTok's older stats block rounds and overflows them (khaby.lame: 163,000,000 followers there against 162,971,182 exact, and heartCount -1,602,757,111 against 2,692,210,185 likes); both blocks are returned as sent. |
| paid_partnership | true when the creator switched on TikTok's branded-content disclosure (adLabelVersion 2). tiktok.com shows these videos with a "Paid partnership" tag: 25 of 25 rendered videos did, and 26 of 26 videos without the flag showed no tag. |
| partner_brand | The brand handle TikTok prints after the tag ("Paid partnership @verizon"). Often empty: TikTok shows the tag without a brand. |
| promotional_content | true when the creator promotes their own brand (brandOrganicType). tiktok.com shows "Promotional content": 10 of 10 rendered videos did. |
| disclosure_label | The tag text tiktok.com shows a US viewer. On shop-affiliate videos it reads "Eligible for commission"; TikTok's shop flag behind that wording changes between responses for the same video, so the wording can differ from one call to the next while paid_partnership stays the same. |
| is_shop_video, has_product_anchor | TikTok's e-commerce flag and the presence of a TikTok Shop product anchor. The product itself (title, price) is not in any logged-out response. |
| is_ad | TikTok's own isAd flag, returned as sent. tiktok.com shows no label for it (0 of 8 such videos had a tag); it is not a paid-ad marker. |
| has_story, user_stories | has_story comes from the profile page. Stories last 24 hours; user_stories returns 1 to 4 per page with a cursor. |
| private_account | On user_videos, user_followers and user_stories: true when the account is private. TikTok then returns an empty list rather than an error. |
| is_live, user_live | user_profile.is_live reads the profile page and can lag (13 of 15 live accounts had it set); user_live asks TikTok's LIVE endpoint, which answered for 139 of 139 accounts checked. |
| response_extra | TikTok's own envelope fields for the call (log ids, search ad_info, comment top_gifts), as sent. |
Video and image URLs are signed CDN links that expire after some hours: store the media, not the URL. Search runs from Europe because TikTok asks for a login to search from the US; region gb returns English-market results.
Real request and response JSON
Captured from the indexed primary action, user_profile, on .
{
"method": "POST",
"url": "https://api.reefapi.com/tiktok/v1/user_profile",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"username": "tiktok"
}
}{
"ok": true,
"meta": {
"api": "tiktok",
"endpoint": "user_profile",
"mode": "live",
"latency_ms": 1238.6,
"record_count": 1,
"bytes": 0,
"cache_hit": false,
"charged_credits": 1,
"version": "2.1.0",
"request_id": "15711872dcf545de",
"fetched_at": "2026-11-03T17:29:04.730Z"
},
"data": {
"id": "107955",
"username": "tiktok",
"nickname": "TikTok",
"sec_uid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM",
"verified": true,
"avatar": "https://p19-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/ba67b11de451691939223e9d978e613a~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=10399&refresh_token=0198bc82&x-expires=1793898000&x-signature=S%2FUUCseqUTcgQOpy2sgUooy7lAY%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast2b",
"url": "https://www.tiktok.com/@tiktok",
"shortId": "",
"uniqueId": "tiktok",
"avatarLarger": "https://p19-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/ba67b11de451691939223e9d978e613a~tplv-tiktokx-cropcenter:1080:1080.jpeg?dr=10399&refresh_token=0198bc82&x-expires=1793898000&x-signature=S%2FUUCseqUTcgQOpy2sgUooy7lAY%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast2b",
"avatarMedium": "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/ba67b11de451691939223e9d978e613a~tplv-tiktokx-cropcenter:720:720.jpeg?dr=10399&refresh_token=dafc6a1b&x-expires=1793898000&x-signature=DLS5FetcnsdC1Pw5htMAjxTica4%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast2b",
"avatarThumb": "https://p16-common-sign.tiktokcdn-eu.com/tos-maliva-avt-0068/ba67b11de451691939223e9d978e613a~tplv-tiktokx-cropcenter:100:100.jpeg?dr=10399&refresh_token=45e33aa5&x-expires=1793898000&x-signature=lRJpNwLBb9MUAPyd%2BF75BFrgiTo%3D&t=4d5b0474&ps=13740610&shp=a5d48078&shcp=81f88b70&idc=useast2b",
"signature": "Your next discovery is waiting on TikTok.",
"createTime": 1425144149,
"secUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM",
"ftc": false,
"relation": 0,
"openFavorite": false,
"bioLink": {
"link": "tiktok.com/discovermore",
"risk": 0
},
"commentSetting": 0,
"commerceUserInfo": {
"commerceUser": true,
"downLoadLink": {
"android": "",
"ios": ""
},
"category": "Others",
"categoryButton": false
},
"duetSetting": 0,
"stitchSetting": 0,
"privateAccount": false,
"secret": "[redacted-secret]",
"isADVirtual": false,
"roomId": "",
"uniqueIdModifyTime": 0,
"ttSeller": false,
"downloadSetting": 0,
"profileTab": {
"showMusicTab": true,
"showQuestionTab": true,
"showPlayListTab": true
},
"followingVisibility": 1,
"recommendReason": "",
"nowInvitationCardUrl": "",
"nickNameModifyTime": 1638559600,
"isEmbedBanned": false,
"canExpPlaylist": true,
"profileEmbedPermission": 1,
"language": "en",
"eventList": [],
"suggestAccountBind": false,
"isOrganization": 1,
"UserStoryStatus": 0,
"shortDramaCreator": {},
"bio": "Your next discovery is waiting on TikTok.",
"bio_link": "tiktok.com/discovermore",
"private": false,
"region": null,
"created_at": "2015-02-28T17:22:29Z",
"is_business": true,
"category": "Others",
"is_live": false,
"live_room_id": null,
"has_story": false,
"stats": {
"follower_count": 96562200,
"following_count": 1,
"like_count": 466077460,
"video_count": 1505,
"friend_count": 1,
"followerCount": 96600000,
"followingCount": 1,
"heart": 466100000,
"heartCount": 466100000,
"videoCount": 1505,
"diggCount": 0,
"friendCount": 1
},
"statsV2": {
"followerCount": "96562200",
"followingCount": "1",
"heart": "466077460",
"heartCount": "466077460",
"videoCount": "1505",
"diggCount": "0",
"friendCount": "1"
},
"itemList": [],
"response_extra": {
"shareMeta": {
"title": "TikTok on TikTok",
"desc": "@tiktok 96.6m Followers, 1 Following, 466.1m Likes - Watch awesome short videos created by TikTok"
},
"statusCode": 0,
"statusMsg": "",
"needFix": true
}
}
}What the TikTok API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| user_profile | A TikTok account's public profile: nickname, bio and bio link, verified/private flags, region, avatar, follower / following / like / video counts, its sec_uid (used by the list actions), whether it has an active story and the LIVE room id the profile page shows while it broadcasts (use user_live for real-time LIVE status). Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Social-listening tools call user_profile to get a TikTok account's public profile. | username |
| user_videos | The videos an account posted, newest first (pinned videos flagged), with full stats, music and hashtags. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Creator and influencer platforms call user_videos to get the videos an account posted, newest first (pinned videos flagged), with full stats, music an…. | username, sec_uid, cursor, count |
| user_reposts | Videos an account reposted (public reposts tab), with full stats. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Brand-monitoring teams call user_reposts to get videos an account reposted (public reposts tab), with full stats. | username, sec_uid, cursor, count |
| user_followers | Accounts that follow a user (public follower list), newest followers first, each with bio and counts. Paginate with the returned cursor. (The FOLLOWING list is login-only on TikTok.) Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Audience analysts call user_followers to get accounts that follow a user (public follower list), newest followers first, each with bio and…. | username, sec_uid, cursor, count |
| video_detail | One video or photo post: caption, author, sound, hashtags, mentions, location, duration, cover, play and download URLs, and play / like / comment / share / save / repost counts. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Social-listening tools call video_detail to get one video or photo post. | video_id |
| comments | Top-level comments on a video with text, likes, reply count, author and whether the creator liked or pinned it. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Creator and influencer platforms call comments to get top-level comments on a video with text, likes, reply count, author and whether the creator l…. | video_id, cursor, count |
| comment_replies | Replies under one comment (the comment id comes from `comments`). Paginate with the cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Brand-monitoring teams call comment_replies to get replies under one comment (the comment id comes from `comments`). | video_id, comment_id, cursor, count |
| search_videos | Videos matching a keyword, as TikTok's logged-out search ranks them: the 'Top' tab's video results (default) or the 'Videos' tab (tab=videos). Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Audience analysts call search_videos to get videos matching a keyword, as TikTok's logged-out search ranks them. | keyword, cursor, search_id, region, tab |
| search_users | Accounts matching a keyword, with follower counts and bios. Paginate with cursor + search_id. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Social-listening tools call search_users to get accounts matching a keyword, with follower counts and bios. | keyword, cursor, search_id, region |
| hashtag_info | A hashtag's page data: id, description, cover, total views and video count. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Creator and influencer platforms call hashtag_info to get a hashtag's page data. | hashtag |
| hashtag_videos | Videos under a hashtag, as the hashtag page lists them. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Brand-monitoring teams call hashtag_videos to get videos under a hashtag, as the hashtag page lists them. | hashtag, hashtag_id, cursor, count |
| music_info | A sound's page data: title, artist, album, duration, original-sound flag, audio URL, cover and how many videos use it. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Audience analysts call music_info to get a sound's page data. | music_id |
| music_videos | Videos that use a sound. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Social-listening tools call music_videos to get videos that use a sound. | music_id, cursor, count |
| trending | TikTok's Explore page: currently trending videos with full stats. Each call returns a fresh set. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Creator and influencer platforms call trending to get tikTok's Explore page. | count |
| feed | The logged-out For-You feed: a fresh page of recommended videos with full stats on every call. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Brand-monitoring teams call feed to get the logged-out For-You feed. | count |
| search_photos | Photo (slideshow) posts matching a keyword, from TikTok's logged-out Photo search tab, with image URLs and full stats. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Audience analysts call search_photos to get photo (slideshow) posts matching a keyword, from TikTok's logged-out Photo search tab, with i…. | keyword, cursor, search_id, region |
| user_playlists | A creator's public playlists (TikTok 'mixes'): name, video count, cover. Feed an id to playlist_videos. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Social-listening tools call user_playlists to get a creator's public playlists (TikTok 'mixes'). | username, sec_uid, cursor, count |
| playlist_videos | The videos in one public playlist, in playlist order. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Creator and influencer platforms call playlist_videos to get the videos in one public playlist, in playlist order. | playlist_id, cursor, count |
| user_stories | An account's active stories (TikTok keeps them 24 hours), newest first, each as a full video or photo record with stats. An account with no story returns an empty list; user_profile's has_story says whether one is up. Paginate with the returned cursor. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Brand-monitoring teams call user_stories to get an account's active stories (TikTok keeps them 24 hours), newest first, each as a full video…. | username, user_id, cursor |
| user_live | Whether an account is broadcasting LIVE right now, and its current (or last) LIVE room: title, viewer count, total entries, start time, cover and stream URLs. No signature needed - TikTok's own logged-out LIVE page data. Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Audience analysts call user_live to get whether an account is broadcasting LIVE right now, and its current (or last) LIVE room. | username |
| related_videos | Videos TikTok recommends next to a given video ('You may like'). Every record also carries every field TikTok sent, unmodified, next to the named fields; envelope fields of TikTok's answer are in response_extra. | Social-listening tools call related_videos to get videos TikTok recommends next to a given video ('You may like'). | video_id, count |
Call user_profile from your stack
curl -X POST https://api.reefapi.com/tiktok/v1/user_profile \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"username":"tiktok"}'import requests
r = requests.post(
"https://api.reefapi.com/tiktok/v1/user_profile",
headers={"x-api-key": REEF_KEY},
json={
"username": "tiktok"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/tiktok/v1/user_profile", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"username": "tiktok"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.tiktok.user_profile with {"username":"tiktok"}.Who uses this API and why
- Track a list of influencers every day: followers, new videos and per-video plays, likes, comments and shares.
- Flag paid partnerships and promotional posts across a creator roster.
- Watch competitors' accounts for stories and LIVE broadcasts.
- Pull comment threads under a brand's or a creator's videos.
- Find creators by keyword and by hashtag, then follow their growth.
Questions developers ask before integrating
Do I need a TikTok account or a login?
No. Everything is what a logged-out visitor sees on tiktok.com. Nothing uses an account.
Can I track an influencer's posts every day?
Yes. user_profile plus user_videos (the 30 newest videos with exact counts) is two calls per account. On 2026-11-03, 20 of 20 influencers came back this way, 31 videos each on average.
Does it show sponsored or paid-partnership videos?
Yes, for creator partnerships: paid_partnership and partner_brand follow the "Paid partnership" tag tiktok.com shows, and promotional_content follows the "Promotional content" tag. Paid ads in the For You feed are only shown to logged-in users, so they are not in the data.
Can I see which TikTok Shop products a video promotes?
Only that it has a shop product attached (has_product_anchor) and whether TikTok marks it as a shop video. The product title and price are not in any logged-out tiktok.com response.
Can I get stories?
Yes. user_stories returns an account's active stories with full stats; has_story on the profile tells you when to call it. On 2026-11-03, 59 of 59 accounts with a story returned it.
Can I check if someone is LIVE?
Yes. user_live returns whether the account is live now, the room title, current viewers, total entries and start time (on 2026-11-03: 24 of 139 accounts checked were live).
What is not available?
The list of accounts someone follows, the videos they liked, products pinned in a LIVE shopping room and paid feed ads. TikTok only shows these to logged-in users or over its live app channel.
Why is the response so large?
Every field TikTok sends is returned, including the video bitrate and cover variants. A page of 30 videos is about 840 KB of JSON (about 100 KB gzipped).
What is the TikTok API?
TikTok API is a ReefAPI endpoint group for public tiktok profiles, videos with full stats, comments, stories, live status and paid-partnership flags, no login. It returns live JSON through POST requests under /tiktok/v1.
Is the TikTok API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. TikTok calls use the same shared credit balance as every other ReefAPI engine.
Do I need a TikTok login or account?
No login to TikTok is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the TikTok data?
The page example is captured from a live user_profile call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the TikTok API use?
TikTok actions currently cost 1 credit per successful call. Failed or blocked calls are free. All APIs draw from one credit pool.
Can I call TikTok from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call tiktok actions with the same key, credit pool and JSON envelope used by normal REST requests.