SocialCrawl

TikTok

TikTok profiles, videos, comments, single-comment lookup, search, trending, sounds, transcripts, and on-screen text through one unified API

TikTok accounts and their videos, the comment section down to a single named comment, three flavours of search, per-country trending, sound-level discovery, spoken transcripts, and the text burned into the frame. Commerce data lives on the separate TikTok Shop API.

Base URL: /v1/tiktok/...

A TikTok video carries three different texts and each has its own endpoint. The caption comes back on post, the spoken words on post/transcript, and the on-screen overlay on video/screen-text. post also surfaces the creator's own text stickers at post.ext.on_screen_texts without the OCR pass.

Quickstart

1. Fetch a profile

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/profile?handle=charlidamelio" \
  -H "x-api-key: YOUR_API_KEY"

2. Fetch their content

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/profile/videos?handle=charlidamelio" \
  -H "x-api-key: YOUR_API_KEY"

3. Read computed fields

When an endpoint supports a computed field and the required source inputs are present, the unified response includes that optional field. Depending on the endpoint, optional fields can include engagement_rate, language, content_category, and estimated_reach. See Computed fields for formulas, clamping rules, and null semantics.

Accounts

EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/profile1Display name, bio, follower and like counts, verification, the two-letter region, numeric user_idhandle or user_id
GET /v1/tiktok/profile/full5Profile, recent videos, and computed metrics in one call instead of threehandle or user_id, posts (1-100, default 25), include
GET /v1/tiktok/profile/videos1A page of recent public videos with captions, view/like/comment/share countshandle, sort_by, region, max_cursor
GET /v1/tiktok/profile/region1Just the two-letter country code, for routing or de-duplicating by markethandle
GET /v1/tiktok/user/followers1Who follows this account, pagedhandle or user_id, min_time
GET /v1/tiktok/user/following1Who this account follows, pagedhandle or user_id, min_time
GET /v1/tiktok/user/audience5Top follower countries with sampled counts and each country's sharehandle
GET /v1/tiktok/user/live1The account's live room: cover, title, start time, status, viewer and entry countshandle

user/audience is geography only. Age and gender are not publicly available on TikTok, or on any other platform here, so no endpoint returns them.

user/live can still return a room after the broadcast has ended. Check is_live, status and the start time yourself rather than treating a response as proof the stream is on. Answers are cached for at most a minute, an account that has never streamed returns is_live: false with an empty room, and a handle that does not exist is a 404 at 0 credits.

Videos and text

EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/post1One video in full: caption, engagement, author, sound, video metadataurl, download_media, region
GET /v1/tiktok/post/transcript10The spoken words from the video's caption trackurl, use_ai_as_fallback, language
GET /v1/tiktok/video/screen-text5Native text stickers plus AI OCR of the cover frameurl
GET /v1/tiktok/collection/videos1The public videos inside a collection URL, pagedurl, max_cursor

download_media=true on post adds direct media URLs. use_ai_as_fallback=true on post/transcript transcribes the audio when TikTok publishes no caption track.

Comments

EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/post/comments1A page of the comment section: username, text, likes, reply counturl, cursor
GET /v1/tiktok/video/comment/replies1One thread opened upcomment_id and url, both required
GET /v1/tiktok/comment2 or 6One named comment, or the comments matching an author or a snippetcomment_url, or post_url plus comment_id

Pull a page of the section first, then expand any thread you want using that comment's id together with the same video URL.

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/post/comments?url=https://www.tiktok.com/@stoolpresidente/video/7623818255903329566" \
  -H "x-api-key: YOUR_API_KEY"

curl "https://www.socialcrawl.dev/v1/tiktok/video/comment/replies?url=https://www.tiktok.com/@stoolpresidente/video/7623818255903329566&comment_id=7623828115408274207" \
  -H "x-api-key: YOUR_API_KEY"

For the whole nested thread in one call, use /v1/prism/comments. See Which endpoint should I use? for the full comparison.

Finding one comment without paging the section

TikTok exposes no fetch-one-comment read, so GET /v1/tiktok/comment is a bounded server-side scan that stops the instant it finds your target. That is why it is priced flat rather than per page. You can address the target three ways:

  • comment_url: a .../@{handle}/video/{id}?comment_id={cid} link, an m.tiktok.com share link, or a vm.tiktok.com shortlink, all resolved for you. TikTok's share sheet emits the cid base64-encoded (?cid=NzY1...), and that form is decoded automatically.
  • post_url plus comment_id: the same thing in two parts. comment_id must be the numeric id. If the target is a reply, also pass parent_comment_id: a reply URL does not carry its parent, and supplying it resolves the reply directly instead of scanning.
  • A search: post_url plus either author_username or text_contains (an exact, case-insensitive snippet), returning up to max matches (1-20, default 5).
cURL
curl "https://www.socialcrawl.dev/v1/tiktok/comment?comment_url=https://www.tiktok.com/@stoolpresidente/video/7623818255903329566?comment_id=7623828115408274207" \
  -H "x-api-key: YOUR_API_KEY"

Three things make it safe to call speculatively. It costs a flat 2 credits, or 6 with deep_scan=true, which raises the page ceiling and the deadline for deeply-buried comments; there is nothing in between and nothing above. A not-found returns 404 and is fully refunded, so you can point it at a comment that may have been deleted without paying to find out. And every response carries lookup.position_hint: store it, pass it back on the next lookup of the same comment, and the scan probes that last-known location first.

For recurring tracking of a known set, POST /v1/prism/comment-lookup re-checks up to 25 comments in one call with per-item found, not-found, errored, or deferred status.

EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/search1Video-only keyword search, paged and filterablequery, date_posted, sort_by, region
GET /v1/tiktok/search/top1TikTok's own Top-tab relevance ranking rather than a recency listquery, publish_time, sort_by, region
GET /v1/tiktok/search/users1 to 31Accounts matching a term, with follower counts and verification; include=profile adds the bio, region, bio link and category per rowquery, cursor, include, limit (1-30)
GET /v1/tiktok/search/hashtag1The feed under one tag, the right shape for tracking a campaignhashtag, region, cursor
GET /v1/tiktok/search/suggestions1Autocomplete terms for a partial query, one fixed listquery, region

search/top returns videos only; it does not include accounts. Expand a seed with search/suggestions first, then call search or search/top.

Bio and region next to user search results

search/users rows carry the counts, the identity and the verification flag, and nothing the search surface does not publish: author.bio, author.location, author.ext.bio_link and author.ext.business_category are null on a plain call. Add include=profile and every row is filled from the profile lookup in the same call: the bio, the two-letter region, the link in the bio and the account category. 1 credit for the page plus 1 per row filled from a fresh lookup, so 31 at most for the 30-row page; rows already in cache are free, rows that could not be filled are refunded and named in _warnings, and the counts the row already carried are never overwritten. limit=N (1 to 30) takes the top N rows and caps the extra credits with it, so limit=5&include=profile costs at most 6. The join adds 4 to 9 seconds on a fresh page (never more than 12; the lookups run in parallel and the call waits for the slowest) and nothing when the rows are already cached. The hydration block on the response lists the rows looked up, filled and served from cache, the credits held and kept, and the milliseconds the join added.

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/search/users?query=cooking&include=profile" \
  -H "x-api-key: YOUR_API_KEY"

Follower counts next to search results

search and search/top rows carry the creator's follower count on post.ext.author_followers; the hashtag feed does not. Every row carries two join keys: post.author.username and post.ext.author_id, the creator's numeric user id. Either one resolves to the current follower count on author.followers through GET /v1/tiktok/profile: pass the username as handle or the id as user_id. The id survives username changes; the handle is the one that works on audience-gated accounts, so retry a 404 id lookup as a handle lookup before treating the creator as gone.

For a crawl, deduplicate creators across the whole run first. The same creators recur across keywords, and you pay once per creator rather than once per row. POST /v1/prism/profiles resolves up to 50 usernames in one call at 1 credit per resolved profile, refunds rows that fail, and never serves from cache. Match rows to your input by each row's index.

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/profile?user_id=7527113447973487646" \
  -H "x-api-key: YOUR_API_KEY"
EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/trending5Popular videos now; feed=local keeps most in one countryregion, feed
GET /v1/tiktok/song1A sound's title, artist, duration, cover, and how many videos use itclipId
GET /v1/tiktok/song/videos1The videos made with that sound, pagedclipId, cursor

trending has no keyword and no cursor, so there is nothing to page. The two sound endpoints together are how you tell a rising sound from a saturated one before you brief a creator on it.

trending has two feeds, and region does something different on each.

  • Default (feed=global). TikTok's web trending feed, fetched through a connection in region. region sets where the request comes from, not where the videos come from, and for most countries the feed is one worldwide pool. On 13/09/2026 over 12 calls in six countries, 22% of its videos were registered in the requested country: US 65%, BR 43%, GB 9%, FR 8%, JP 6%, DE 0%. About 13 videos, 3 to 12 seconds.
  • Local (feed=local). The For You feed TikTok's app serves to a phone set to region. Most, not all, of its videos are from that country: 57% across 10 pages measured the same day (DE 52%, US 66%, GB 41%, JP 81%), and 51% were captioned in the country's main language. A median of 24 videos (8 to 27), 12 to 35 seconds. When no video comes back the call returns 503 and refunds the credits, which happened on 1 of 25 test calls, so retry. A local call never falls back to the global feed.

Both cost 5 credits and return each video once. Every row carries post.ext.region, the two-letter country the video is registered to, so when you need only one country, filter on it. Local rows also carry post.ext.content_language, TikTok's own caption-language tag, which is null when TikTok could not tell.

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/trending?region=DE&feed=local" \
  -H "x-api-key: YOUR_API_KEY"
cURL
curl "https://www.socialcrawl.dev/v1/tiktok/trending?region=US" \
  -H "x-api-key: YOUR_API_KEY"

curl "https://www.socialcrawl.dev/v1/tiktok/song/videos?clipId=7016187547651328773" \
  -H "x-api-key: YOUR_API_KEY"

TikTok's own trend boards

TikTok publishes ranked trend boards for advertisers, now part of TikTok One. Two of them are live, and you need nothing but a market and a time window to read them.

EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/hashtags/popular2 per hashtag, minimum 6TikTok's trending hashtags for a market: the overall board and 15 industry boardscountryCode (27 markets), period, industry
GET /v1/tiktok/videos/popular25 per board plus 1 per videoTikTok's Top Videos board, ranked by views, engagement or 6-second viewscountryCode (US, JP, VN, TH, ID), period, orderBy, limit
  • Hashtags. TikTok shows three hashtags per board to a reader who is not logged in, so one board is three rows and costs 6 credits. Pass industry=all to read the overall board and all 15 industry boards in one call: 44 to 46 unique hashtags for Germany on 13/09/2026, for about 90 credits, in 3 to 4 seconds. Each row carries its rank, the window's post and view counts, a daily popularity curve and the top creators under post.ext.trend. A hashtag that ranks on more than one board comes back once and is billed once; post.ext.trend.boards lists every board it ranks on with its rank there (in Germany #marvelrivals was third overall and first in Games). period is 7, 30 or 90 days.
  • Videos. TikTok publishes this board for five markets only. A request for any other market, Germany included, returns 400 at no charge and points you to the hashtag board.

These values from the old boards are gone and return 400 at no charge: a 120-day window, newOnBoard, a second page, and the business-services, financial-services and life-services industries. The popular songs board was removed by TikTok and the creator board shows "Coming soon", so GET /v1/tiktok/songs/popular and GET /v1/tiktok/creators/popular return 503 and never bill.

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/hashtags/popular?countryCode=DE&period=7&industry=all" \
  -H "x-api-key: YOUR_API_KEY"

Ad Library

EndpointCreditsWhat it returnsKey parameters
GET /v1/tiktok/adlibrary/search5 to 17Ads matching a keyword or an advertiser; include=ad adds the brand, landing page and advertiser link per adquery or advertiser_name, include, limit (1-12)
GET /v1/tiktok/adlibrary/ad5One ad in full: creative, landing page, and brandad_id or url

Same advanced tier as the Facebook, Google, and LinkedIn ad libraries.

Brand and landing page next to ad results

The library's search row names the advertiser and carries the creative, the impression estimate, the spend band and the dates, and nothing about where the ad sends people: post.ext.ad.brand_name, post.ext.ad.landing_page, post.ext.ad.profile_web_link and post.author.avatar_url are null on a plain call. Add include=ad and every ad is filled from the per-ad record in the same call: the registered brand name, the landing page, the advertiser's TikTok profile link and avatar, and the objectives, countries and source where the library has them. 5 credits for the page plus 1 per ad filled from a fresh lookup, so 17 at most for the 12-ad page; ads already in cache are free, and ads that could not be filled are refunded and named in _warnings. limit=N (1 to 12) caps the ads and the extra credits together. The join adds 5 to 20 seconds on a fresh page (never more than 20), and the search itself is often the slow part of the call. Like, comment and share counts are not published by the library on either endpoint; for the performance side of TikTok advertising use ads/top, which reads the Creative Center board.

cURL
curl "https://www.socialcrawl.dev/v1/tiktok/adlibrary/search?advertiser_name=Gymshark&include=ad" \
  -H "x-api-key: YOUR_API_KEY"

All endpoints

36 endpoints available.

EndpointPathCredit Tier
Read TikTok's Creative Center Top Ads board: the best-performing ads in a market, ranked by CTR, impressions or engagement. Metered: 1 credit per ad returned, minimum 10/v1/tiktok/ads/topstandard (10-100cr)metered
List videos in a TikTok collection/v1/tiktok/collection/videosstandard (1cr)
Look up one TikTok comment by URL or id/v1/tiktok/commentstandard (2-6cr)metered
List TikTok videos made with an effect/v1/tiktok/effect/videosstandard (1cr)
Get TikTok effects by id/v1/tiktok/effectsstandard (1cr)
Get TikTok hashtag details/v1/tiktok/hashtagstandard (1cr)
Read TikTok's own trending-hashtag board for a market and time window: the overall board plus 15 industry boards. Metered: 2 credits per hashtag returned, minimum 6/v1/tiktok/hashtags/popularstandard (6-96cr)metered
List TikTok videos tagged at a place/v1/tiktok/location/postsstandard (1cr)
List videos in a TikTok playlist/v1/tiktok/playlist/videosstandard (1cr)
Get TikTok post details/v1/tiktok/poststandard (1cr)
List TikTok post comments/v1/tiktok/post/commentsstandard (1cr)
Get TikTok user profile/v1/tiktok/profilestandard (1cr)
TikTok profile, recent posts, and computed analytics in one call./v1/tiktok/profile/fullstandard (5cr)
List a TikTok account's playlists/v1/tiktok/profile/playlistsstandard (1cr)
Get TikTok profile region/v1/tiktok/profile/regionstandard (1cr)
List TikTok user videos/v1/tiktok/profile/videosstandard (1cr)
Search TikTok videos by keyword/v1/tiktok/searchstandard (1cr)
Search TikTok by hashtag/v1/tiktok/search/hashtagstandard (1cr)
Search TikTok sounds/v1/tiktok/search/musicstandard (1cr)
Get TikTok search suggestions/v1/tiktok/search/suggestionsstandard (1cr)
TikTok top search results/v1/tiktok/search/topstandard (1cr)
Search TikTok users/v1/tiktok/search/usersstandard (1-31cr)metered
Get TikTok song details/v1/tiktok/songstandard (1cr)
List TikTok videos using a song/v1/tiktok/song/videosstandard (1cr)
List TikTok user followers/v1/tiktok/user/followersstandard (1cr)
List TikTok user following/v1/tiktok/user/followingstandard (1cr)
List the videos a TikTok account has liked/v1/tiktok/user/likedstandard (1cr)
Get TikTok user live stream/v1/tiktok/user/livestandard (1cr)
List TikTok comment replies/v1/tiktok/video/comment/repliesstandard (1cr)
Read TikTok's own Top Videos board for the US, Japan, Vietnam, Thailand or Indonesia. Metered: 25 credits per board plus 1 per video returned/v1/tiktok/videos/popularstandard (26-45cr)metered
Get a TikTok Ad Library ad/v1/tiktok/adlibrary/adadvanced (5cr)
Search the TikTok Ad Library/v1/tiktok/adlibrary/searchadvanced (5-17cr)metered
Get TikTok trending feed/v1/tiktok/trendingadvanced (5cr)
Get TikTok user audience demographics/v1/tiktok/user/audienceadvanced (5cr)
Get TikTok video on-screen text/v1/tiktok/video/screen-textadvanced (5cr)
Get TikTok video transcript/v1/tiktok/post/transcriptpremium (10cr)

Platform notes

Follower counts are exact where TikTok exposes them. author.followers is the unrounded integer when the source publishes one. When only the rounded public figure exists, the response sets author.ext.followers_approximate to true.

Repeat profile lookups replay a cached snapshot. A second lookup of the same account within 15 minutes is served from cache at no charge. Send Cache-Control: no-cache when you need a guaranteed-fresh read.

Age and gender do not exist on this platform. user/audience returns geography only, because TikTok publishes no public demographic breakdown for a creator's followers.

region routes a request; it does not filter results. It is accepted on profile/videos, post, search, search/top, and search/hashtag, where it sends the request through that country, which changes what TikTok is willing to serve (a video blocked in one country loads from another) but not which country the results come from. trending requires it: on the default feed it is the same routing, and with feed=local it picks the country the For You feed is built for (see Which country the trending videos come from). To keep only one country's trending videos, filter the rows on post.ext.region.

Identifiers are not interchangeable. profile, user/followers, and profile/full take handle or user_id; post, post/comments, post/transcript, and video/screen-text take the video url; the sound endpoints take clipId.

trim=true costs the same. Most list endpoints accept it and return a lighter payload at the same price.

TikTok Shop moved. Product details, reviews, shop search, and creator showcases now live under /v1/tiktokshop/.... The old /v1/tiktok/shop and /v1/tiktok/user/showcase paths still resolve for backward compatibility.

Next steps