Skip to content

TikTok API

The TrueScrape TikTok API exposes 32 public endpoints covering One TikTok ad, Search the TikTok Ads Library and Collection videos. Every call is a GET against public, logged-out pages and returns the same unified schema as every other platform here. Calls cost 1 credit each. A cache hit is free, and a failed or empty response is never charged.

Endpoints

EndpointReturnsCreditsCacheableBatchable
/v1/tiktok/ad-library/adOne TikTok ad1yesyes
/v1/tiktok/ad-library/searchSearch the TikTok Ads Library1yesno
/v1/tiktok/collection/videosCollection videos1yesyes
/v1/tiktok/comment-repliesReplies to a comment1yesyes
/v1/tiktok/commentsComments on a video1yesyes
/v1/tiktok/creators/popularPopular creators1yesyes
/v1/tiktok/followersAccounts following a creator1yesyes
/v1/tiktok/followingAccounts a creator follows1yesyes
/v1/tiktok/hashtagHashtag details1yesyes
/v1/tiktok/hashtag-videosVideos using a hashtag1yesyes
/v1/tiktok/liveLive stream info1yesyes
/v1/tiktok/playlist-videosVideos in a playlist1yesyes
/v1/tiktok/playlistsA creator's playlists1yesyes
/v1/tiktok/productProduct details1yesyes
/v1/tiktok/profileProfile details1yesyes
/v1/tiktok/profile/regionCreator region1yesyes
/v1/tiktok/search/keywordSearch videos by keyword1yesyes
/v1/tiktok/search/suggestionsSearch suggestions1yesyes
/v1/tiktok/search/topTop (blended) search1yesyes
/v1/tiktok/search/usersSearch creators1yesyes
/v1/tiktok/shop/product/reviewsProduct reviews1yesyes
/v1/tiktok/shop/productsSeller's product catalogue1yesyes
/v1/tiktok/shop/searchSearch TikTok Shop1yesyes
/v1/tiktok/songSound / song details1yesyes
/v1/tiktok/song-videosVideos using a sound1yesyes
/v1/tiktok/songs/popularPopular songs1yesyes
/v1/tiktok/transcriptVideo transcript1yesyes
/v1/tiktok/trendingTrending feed1yesyes
/v1/tiktok/user-videosVideos posted by a creator1yesyes
/v1/tiktok/user/showcaseCreator's product showcase1yesyes
/v1/tiktok/videoVideo or photo-post details1yesyes
/v1/tiktok/videos/popularPopular videos1yesyes

Reference

GET/v1/tiktok/ad-library/ad1 creditcacheablebatchable

One TikTok ad

One TikTok ad by id or URL. Two public surfaces carry ads and an id alone does not say which: Creative Center Top Ads (ads.tiktok.com) is checked first, then the Commercial Content Library (library.tiktok.com). Pass a URL from either and only that source is queried. Both return the same Ad shape; fields a source does not publish are null rather than inferred - Top Ads carries no flight dates or advertiser entity, and the library carries no performance metrics. countries here is the ad's own targeting, unlike a search result's, where it is the market that was searched. An id neither source knows is a 404; an id that only one source could be asked about is not, because a source that did not answer has not said no. Reach bands stay in raw, not in the impressions fields, because reach is not impressions.

ParameterTypeRequiredDescription
ad_idstringyesNumeric ad id, a library.tiktok.com /ads/detail?ad_id= URL, or an ads.tiktok.com Top Ads URL

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one Ad.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
advertiserIdstring | nullalways
advertiserNamestring | nullalways
urlstring | nullalwaysLink to the ad's page in the platform's ad library.
headlinestring | nullalways
bodystring | nullalways
ctaTextstring | nullalwaysText of the call-to-action button, such as "Shop now".
linkUrlstring | nullalwaysWhere the ad links to. Some ad libraries expose only the destination's domain.
creativeTypestring | nullalwaysFormat of the ad creative, such as `video` or `image`, as the ad library labels it.
imageUrlsstring[]always
videoUrlsstring[]always
platformsstring[]alwaysPlatforms the ad was shown on, in lowercase, such as `facebook` or `instagram`.
countriesstring[]alwaysCountries the ad ran in or targeted, usually as two-letter country codes.
languagesstring[]always
startedAtstring | nullalways
endedAtstring | nullalwaysWhen the ad stopped running. Null while it is still running, or when the ad library reports no end date.
isActiveboolean | nullalways
impressionsLowernumber | nullalwaysLower bound of the impressions range the ad library reports. Libraries publish a range, not an exact figure.
impressionsUppernumber | nullalwaysUpper bound of the impressions range the ad library reports.
spendLowernumber | nullalwaysLower bound of the reported spend range, in `currency`.
spendUppernumber | nullalwaysUpper bound of the reported spend range, in `currency`.
currencystring | nullalwaysCurrency of the spend range, as a code such as `USD`.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/ad-library/ad?ad_id=%3Cad_id%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  ad_id: '<ad_id>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/ad-library/ad?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/ad-library/ad",
    params={
        "ad_id": "<ad_id>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/ad-library/ad
Open the full playground
GET/v1/tiktok/ad-library/search1 creditcacheable

Search the TikTok Ads Library

Ads in TikTok's public Commercial Content Library, by keyword (query) or by advertiser (advertiser_name). An advertiser name is resolved through TikTok's own typeahead first, then searched as an entity, so it matches the registered legal name ("NIKE Retail B.V.") rather than a brand. Results are NOT global: TikTok publishes this archive per market and refuses a search without one, so region is required, validated against the market list the library itself publishes rather than a fixed list here, and every result ran in that market, which is what each ad's countries reports. TikTok returns its own relevance ranking; we ask for the most recently shown first, but that is only a tiebreak within it, so results are not ordered by date. Cursor-paginated 12 at a time, each ad carrying its public library.tiktok.com detail URL. Pages are not guaranteed disjoint: the archive re-ranks live, so an ad can repeat across pages. Political and election ads are outside the archive. Reach is published as a band and is not impressions, so it stays in raw.estimated_audience rather than the impressions fields.

ParameterTypeRequiredDescription
querystringnoKeyword, matched against ad text and advertiser name
advertiser_namestringnoAdvertiser name, resolved through TikTok's typeahead to one advertiser entity
regionstringyesMarket to search. TikTok publishes this archive per market; one of AT, BE, BG, CH, CY, CZ, DE, DK, EE, ES, FI, FR, GB, GR, HR, HU, IE, IS, IT, LI, LT, LU, LV, MT, NL, NO, PL, PT, RO, SE, SI, SK, TR.
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Ad in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
advertiserIdstring | nullalways
advertiserNamestring | nullalways
urlstring | nullalwaysLink to the ad's page in the platform's ad library.
headlinestring | nullalways
bodystring | nullalways
ctaTextstring | nullalwaysText of the call-to-action button, such as "Shop now".
linkUrlstring | nullalwaysWhere the ad links to. Some ad libraries expose only the destination's domain.
creativeTypestring | nullalwaysFormat of the ad creative, such as `video` or `image`, as the ad library labels it.
imageUrlsstring[]always
videoUrlsstring[]always
platformsstring[]alwaysPlatforms the ad was shown on, in lowercase, such as `facebook` or `instagram`.
countriesstring[]alwaysCountries the ad ran in or targeted, usually as two-letter country codes.
languagesstring[]always
startedAtstring | nullalways
endedAtstring | nullalwaysWhen the ad stopped running. Null while it is still running, or when the ad library reports no end date.
isActiveboolean | nullalways
impressionsLowernumber | nullalwaysLower bound of the impressions range the ad library reports. Libraries publish a range, not an exact figure.
impressionsUppernumber | nullalwaysUpper bound of the impressions range the ad library reports.
spendLowernumber | nullalwaysLower bound of the reported spend range, in `currency`.
spendUppernumber | nullalwaysUpper bound of the reported spend range, in `currency`.
currencystring | nullalwaysCurrency of the spend range, as a code such as `USD`.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/ad-library/search?region=%3Cregion%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  region: '<region>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/ad-library/search?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/ad-library/search",
    params={
        "region": "<region>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/ad-library/search
Open the full playground
GET/v1/tiktok/collection/videos1 creditcacheablebatchable

Collection videos

Videos in a public TikTok collection, a creator-curated playlist of other people's posts as well as their own. **Required:** Pass either url or collection_id.

ParameterTypeRequiredDescription
urlstringnoCollection URL, e.g. https://www.tiktok.com/@nasa/collection/Artemis-7123…
collection_idstringnoNumeric collection id
countnumbernoItems per page (default 20, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/collection/videos?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/collection/videos?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/collection/videos",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/collection/videos
Open the full playground
GET/v1/tiktok/comment-replies1 creditcacheablebatchable

Replies to a comment

The reply thread under one TikTok comment. parentId on each reply points back at the comment it answers, so nested threads reconstruct cleanly.

ParameterTypeRequiredDescription
comment_idstringyesid of the parent comment, from tiktok.comments
urlstringyesThe video the comment is on: URL, share link, or numeric id
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Comment in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
postIdstring | nullalways
parentIdstring | nullalwaysId of the comment this one replies to. Null on a top-level comment.
textstringalways
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
authorAvatarUrlstring | nullalways
likeCountnumber | nullalways
replyCountnumber | nullalways
isPinnedboolean | nullalways
isAuthorReplyboolean | nullalwaysWhether the comment was written by the author of the post.
publishedAtstring | nullalwaysWhen the comment was posted. Usually an ISO 8601 timestamp; some platforms expose only relative text such as "2 days ago".
curl
curl "$API/v1/tiktok/comment-replies?comment_id=%3Ccomment_id%3E&url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  comment_id: '<comment_id>',
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/comment-replies?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/comment-replies",
    params={
        "comment_id": "<comment_id>",
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/comment-replies
Open the full playground
GET/v1/tiktok/comments1 creditcacheablebatchable

Comments on a video

Top-level comments on a TikTok, with like counts, reply counts, pinned status and a flag for the creator's own replies. Use tiktok.commentReplies to expand a thread.

ParameterTypeRequiredDescription
urlstringyesVideo URL (preferred), share link, or numeric video id
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Comment in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
postIdstring | nullalways
parentIdstring | nullalwaysId of the comment this one replies to. Null on a top-level comment.
textstringalways
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
authorAvatarUrlstring | nullalways
likeCountnumber | nullalways
replyCountnumber | nullalways
isPinnedboolean | nullalways
isAuthorReplyboolean | nullalwaysWhether the comment was written by the author of the post.
publishedAtstring | nullalwaysWhen the comment was posted. Usually an ISO 8601 timestamp; some platforms expose only relative text such as "2 days ago".
curl
curl "$API/v1/tiktok/comments?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/comments?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/comments",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/comments
Open the full playground
GET/v1/tiktok/creators/popular1 creditcacheablebatchable

Popular creators

Creators trending in a market, from TikTok's own Creative Center leaderboard. Filter by country, follower band and category.

ParameterTypeRequiredDescription
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.
period7 | 30 | 120noTrailing window in days: 7, 30 or 120defaults to 7
follower_band1k-10k | 10k-100k | 100k-1m | 1m+noRestrict to creators in this follower range
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Creator in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
displayNamestring | nullalways
biostring | nullalways
avatarUrlstring | nullalways
bannerUrlstring | nullalways
urlstring | nullalways
verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
followingCountnumber | nullalways
postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
isPrivateboolean | nullalways
isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/creators/popular?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/creators/popular?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/creators/popular",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/creators/popular
Open the full playground
GET/v1/tiktok/followers1 creditcacheablebatchable

Accounts following a creator

The public follower list for a TikTok account, newest first. TikTok caps how deep this list can be walked regardless of paging. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
handlestringyesHandle (@nike), or a full tiktok.com profile URL
countnumbernoItems per page (default 30, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Creator in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
displayNamestring | nullalways
biostring | nullalways
avatarUrlstring | nullalways
bannerUrlstring | nullalways
urlstring | nullalways
verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
followingCountnumber | nullalways
postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
isPrivateboolean | nullalways
isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/followers?handle=%40mkbhd&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  handle: '@mkbhd',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/followers?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/followers",
    params={
        "handle": "@mkbhd",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/followers
Open the full playground
GET/v1/tiktok/following1 creditcacheablebatchable

Accounts a creator follows

The accounts a TikTok creator follows, newest first. Hidden entirely when the creator has set their following list to private. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
handlestringyesHandle (@nike), or a full tiktok.com profile URL
countnumbernoItems per page (default 30, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Creator in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
displayNamestring | nullalways
biostring | nullalways
avatarUrlstring | nullalways
bannerUrlstring | nullalways
urlstring | nullalways
verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
followingCountnumber | nullalways
postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
isPrivateboolean | nullalways
isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/following?handle=%40mkbhd&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  handle: '@mkbhd',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/following?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/following",
    params={
        "handle": "@mkbhd",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/following
Open the full playground
GET/v1/tiktok/hashtag1 creditcacheablebatchable

Hashtag details

Stats for a TikTok hashtag: total videos and total views, plus its description and cover. Read straight off the tag page, so it needs no signer.

ParameterTypeRequiredDescription
hashtagstringyesTag without the # (fyp), or a full /tag/ URL

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with platform, id, name, description, url, coverUrl, videoCount, viewCount, isCommerce, fetchedAt.

Fields
FieldTypePresent
platform"tiktok"always
idstringalways
namestringalways
descriptionstring | nullalways
urlstringalways
coverUrlstring | nullalways
videoCountnumber | nullalways
viewCountnumber | nullalways
isCommerceboolean | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/hashtag?hashtag=%3Chashtag%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  hashtag: '<hashtag>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/hashtag?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/hashtag",
    params={
        "hashtag": "<hashtag>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/hashtag
Open the full playground
GET/v1/tiktok/hashtag-videos1 creditcacheablebatchable

Videos using a hashtag

TikToks carrying a given hashtag, in TikTok's own feed order, with a cursor for the next page.

ParameterTypeRequiredDescription
hashtagstringyesTag without the # (fyp), or a full /tag/ URL
countnumbernoItems per page (default 30, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/hashtag-videos?hashtag=%3Chashtag%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  hashtag: '<hashtag>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/hashtag-videos?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/hashtag-videos",
    params={
        "hashtag": "<hashtag>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/hashtag-videos
Open the full playground
GET/v1/tiktok/live1 creditcacheablebatchable

Live stream info

Details of a creator's stream while they are live: room id, title, cover, current viewers and start time. A creator who is not live returns empty_result, a real answer that costs nothing, so this works as a cheap "are they live?" poll. Pass room_id (from a previous response's roomId) to look the room up directly on TikTok's own webcast surface. No third-party provider is involved. On the room_id path handle may come back empty if the webcast payload omits the room owner. **Required:** Pass either handle or room_id.

ParameterTypeRequiredDescription
handlestringnoHandle (@nike), or a full tiktok.com profile URL
room_idstringnoTikTok LIVE room id, e.g. from a previous tiktok.live response's roomId

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with platform, roomId, handle, title, coverUrl, viewerCount, startedAt, url, creator, fetchedAt.

Fields
FieldTypePresent
platform"tiktok"always
roomIdstringalways
handlestringalways
titlestring | nullalways
coverUrlstring | nullalways
viewerCountnumber | nullalways
startedAtstring | nullalways
urlstringalways
creatorCreatoralways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/live?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/live?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/live",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
GET/v1/tiktok/playlist-videos1 creditcacheablebatchable

Videos in a playlist

The videos inside one TikTok playlist, in the creator's chosen order. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
playlist_idstringyesid from tiktok.playlists, or a /playlist/ URL
countnumbernoItems per page (default 30, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/playlist-videos?playlist_id=%3Cplaylist_id%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  playlist_id: '<playlist_id>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/playlist-videos?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/playlist-videos",
    params={
        "playlist_id": "<playlist_id>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/playlist-videos
Open the full playground
GET/v1/tiktok/playlists1 creditcacheablebatchable

A creator's playlists

The playlists (TikTok calls them "mixes") a creator has organised their videos into. Pair with tiktok.playlistVideos to walk one. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
handlestringyesHandle (@nike), or a full tiktok.com profile URL
countnumbernoItems per page (default 20, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresent
platform"tiktok"always
idstringalways
namestringalways
urlstringalways
coverUrlstring | nullalways
videoCountnumber | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/playlists?handle=%40mkbhd&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  handle: '@mkbhd',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/playlists?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/playlists",
    params={
        "handle": "@mkbhd",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/playlists
Open the full playground
GET/v1/tiktok/product1 creditcacheablebatchable

Product details

A single TikTok Shop product: title, description, images, price and original price, rating, review and sales counts, stock, category and the seller. price is the lowest-priced variant; it is null when TikTok hides the digits from logged-out visitors. Catalogues are per market: region picks one, default US.

ParameterTypeRequiredDescription
urlstringyesProduct id, or a tiktok.com/shop/pdp/… URL
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with platform, id, title, url, description, price, originalPrice, imageUrls, rating, reviewCount, soldCount, inStock, sellerId, sellerName, categoryName, fetchedAt.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
titlestringalways
urlstring | nullalways
descriptionstring | nullalways
priceobjectalways
price.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
price.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
price.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
originalPriceobjectalways
originalPrice.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
originalPrice.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
originalPrice.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
imageUrlsstring[]always
ratingnumber | nullalwaysStar rating out of 5. Null on a product with no reviews yet.
reviewCountnumber | nullalways
soldCountnumber | nullalways
inStockboolean | nullalways
sellerIdstring | nullalways
sellerNamestring | nullalways
categoryNamestring | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/product?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/product?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/product",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/product
Open the full playground
GET/v1/tiktok/profile1 creditcacheablebatchable

Profile details

Public profile for a TikTok account: followers, following, video count, bio, bio link, verification and account region. Private accounts return their public shell with isPrivate: true rather than an error. That is a real answer, not a failure. Total likes received (TikTok's "hearts") is in raw, since it is a like total rather than the lifetime view count viewCount means elsewhere in the schema.

ParameterTypeRequiredDescription
handlestringyesHandle (@nike), or a full tiktok.com profile URL

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one Creator.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
displayNamestring | nullalways
biostring | nullalways
avatarUrlstring | nullalways
bannerUrlstring | nullalways
urlstring | nullalways
verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
followingCountnumber | nullalways
postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
isPrivateboolean | nullalways
isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/profile?handle=%40mkbhd&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  handle: '@mkbhd',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/profile?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/profile",
    params={
        "handle": "@mkbhd",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/profile
Open the full playground
GET/v1/tiktok/profile/region1 creditcacheablebatchable

Creator region

The market TikTok assigns a creator's account. Read from TikTok's own region field: on the profile where TikTok publishes one, otherwise from the region stamped on the creator's recent posts. Never inferred from language, timezone or content. **Required:** Pass either handle or url.

ParameterTypeRequiredDescription
handlestringnoCreator handle, e.g. @nasa
urlstringnoProfile URL, e.g. https://www.tiktok.com/@nasa

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with platform, handle, userId, region, source, agreement, fetchedAt.

Fields
FieldTypePresentDescription
platform"tiktok"always
handlestringalways
userIdstringalways
regionstring | nullalwaysTwo-letter market code as TikTok reports it. Never inferred.
sourceprofile | posts | nullalwaysWhere the value came from, so a caller can weigh it.
agreementobject[]alwaysFrom posts: how many sampled posts agreed. A traveller can carry several.
agreement[].regionstringalways
agreement[].countnumberalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/profile/region?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/profile/region?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/profile/region",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/profile/region
Open the full playground
GET/v1/tiktok/search/keyword1 creditcacheablebatchable

Search videos by keyword

TikToks matching a search term, with the same normalised engagement fields as every other post endpoint. sort_by and date_posted map onto TikTok's own search filters. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
querystringyesSearch term
sort_byrelevance | most_likednoTikTok's own two search orderingsdefaults to relevance
date_postedall | yesterday | week | month | three_months | six_monthsnoRestrict to videos posted within this windowdefaults to all
countnumbernoItems per page (default 12, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/search/keyword?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/search/keyword?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/search/keyword",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/search/keyword
Open the full playground
GET/v1/tiktok/search/suggestions1 creditcacheablebatchable

Search suggestions

TikTok's typeahead completions for a partial query: what the platform thinks people are looking for. Useful for keyword research.

ParameterTypeRequiredDescription
querystringyesPartial search term

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresentDescription
textstringalways
typestring | nullalwaysTikTok's own grouping, when it labels one.
curl
curl "$API/v1/tiktok/search/suggestions?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/search/suggestions?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/search/suggestions",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/search/suggestions
Open the full playground
GET/v1/tiktok/search/top1 creditcacheablebatchable

Top (blended) search

TikTok's blended "Top" search tab: the highest-ranked videos AND accounts for a query, returned as two typed lists. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
querystringyesSearch terms
countnumbernoItems per page (default 12, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with videos, users.

Fields
FieldTypePresent
videosPost[]always
usersCreator[]always
curl
curl "$API/v1/tiktok/search/top?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/search/top?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/search/top",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/search/top
Open the full playground
GET/v1/tiktok/search/users1 creditcacheablebatchable

Search creators

TikTok accounts matching a query, with follower counts and verification. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
querystringyesSearch term
countnumbernoItems per page (default 12, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Creator in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalwaysThe platform's own id for the account, such as a channel id or a numeric user id, always as a string.
handlestring | nullalwaysThe account handle without the leading @. Null when the platform has no handles.
displayNamestring | nullalways
biostring | nullalways
avatarUrlstring | nullalways
bannerUrlstring | nullalways
urlstring | nullalways
verifiedboolean | nullalwaysWhether the platform shows a verification badge on the account. Null where the platform has no public badge or does not expose it.
followerCountnumber | nullalwaysFollowers, subscribers, or the platform's nearest equivalent. Null when the account hides the count or the platform does not expose it.
followingCountnumber | nullalways
postCountnumber | nullalwaysPosts, videos, tracks, repositories, or the platform's nearest equivalent that the account has published.
viewCountnumber | nullalwaysLifetime views across the account, where the platform exposes a total.
likeCountnumber | nullmay be absentTotal likes received across all of the creator's posts. Distinct from `viewCount`. Absent when the platform does not expose it.
isPrivateboolean | nullalways
isBusinessboolean | nullalwaysWhether the platform classifies the account as a business or organisation rather than a person or creator. Null where the platform draws no such line or does not expose it. On Facebook every Page counts, including Pages for public figures.
categorystring | nullalwaysA label the platform attaches to the account, such as a business category, a genre or an account type. What it holds varies by platform.
locationstring | nullalwaysLocation as the platform shows it: a city, a country, a region code or an address, depending on the platform.
externalLinksstring[]alwaysLinks the account lists on its profile, such as a website or other social accounts.
createdAtstring | nullalwaysWhen the account was created. Usually an ISO 8601 timestamp; some platforms expose only the date as shown on the profile.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/search/users?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/search/users?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/search/users",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/search/users
Open the full playground
GET/v1/tiktok/shop/product/reviews1 creditcacheablebatchable

Product reviews

The reviews a TikTok Shop product page shows, with star rating, reviewer, photos and the purchased variant. That is the page's first screen, not every review. region picks the market, default US.

ParameterTypeRequiredDescription
urlstringyesProduct id, or a tiktok.com/shop/pdp/… URL
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
productIdstring | nullalways
textstringalways
ratingnumber | nullalways
authorNamestring | nullalways
authorAvatarUrlstring | nullalways
imageUrlsstring[]always
variantstring | nullalwaysThe variant the reviewer actually bought, when TikTok attaches it.
publishedAtstring | nullalways
curl
curl "$API/v1/tiktok/shop/product/reviews?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/shop/product/reviews?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/shop/product/reviews",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/shop/product/reviews
Open the full playground
GET/v1/tiktok/shop/products1 creditcacheablebatchable

Seller's product catalogue

The products a TikTok Shop store lists, page by page, with price, rating, review and sales counts. Pass the store's URL (tiktok.com/shop/store/<name>/<seller_id>). region picks the market, default US.

ParameterTypeRequiredDescription
urlstringyesTikTok Shop store URL, e.g. https://www.tiktok.com/shop/store/goli-nutrition/7495794203056835079
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
titlestringalways
urlstring | nullalways
descriptionstring | nullalways
priceobjectalways
price.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
price.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
price.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
originalPriceobjectalways
originalPrice.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
originalPrice.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
originalPrice.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
imageUrlsstring[]always
ratingnumber | nullalwaysStar rating out of 5. Null on a product with no reviews yet.
reviewCountnumber | nullalways
soldCountnumber | nullalways
inStockboolean | nullalways
sellerIdstring | nullalways
sellerNamestring | nullalways
categoryNamestring | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/shop/products?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/shop/products?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/shop/products",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/shop/products
Open the full playground
GET/v1/tiktok/shop/search1 creditcacheablebatchable

Search TikTok Shop

The products TikTok Shop search returns for a query, page by page, with price, rating, review and sales counts. US market.

ParameterTypeRequiredDescription
querystringyesSearch terms
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
titlestringalways
urlstring | nullalways
descriptionstring | nullalways
priceobjectalways
price.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
price.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
price.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
originalPriceobjectalways
originalPrice.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
originalPrice.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
originalPrice.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
imageUrlsstring[]always
ratingnumber | nullalwaysStar rating out of 5. Null on a product with no reviews yet.
reviewCountnumber | nullalways
soldCountnumber | nullalways
inStockboolean | nullalways
sellerIdstring | nullalways
sellerNamestring | nullalways
categoryNamestring | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/shop/search?query=ai%20agents&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  query: 'ai agents',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/shop/search?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/shop/search",
    params={
        "query": "ai agents",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/shop/search
Open the full playground
GET/v1/tiktok/song1 creditcacheablebatchable

Sound / song details

Details for a TikTok sound: title, artist, album, cover, clip length, and how many videos use it.

ParameterTypeRequiredDescription
songstringyesMusic id, or a full tiktok.com/music/… URL

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns an object with platform, id, title, authorName, album, url, coverUrl, playUrl, durationSeconds, isOriginalSound, videoCount, fetchedAt.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
titlestringalways
authorNamestring | nullalways
albumstring | nullalways
urlstringalways
coverUrlstring | nullalways
playUrlstring | nullalways
durationSecondsnumber | nullalways
isOriginalSoundboolean | nullalwaysTrue when the sound originated on TikTok rather than a licensed track.
videoCountnumber | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/song?song=%3Csong%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  song: '<song>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/song?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/song",
    params={
        "song": "<song>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
GET/v1/tiktok/song-videos1 creditcacheablebatchable

Videos using a sound

TikToks built on a given sound: the endpoint behind "who is using my track", with a cursor for the next page.

ParameterTypeRequiredDescription
songstringyesMusic id, or a full tiktok.com/music/… URL
countnumbernoItems per page (default 30, max 30)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/song-videos?song=%3Csong%3E&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  song: '<song>',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/song-videos?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/song-videos",
    params={
        "song": "<song>",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/song-videos
Open the full playground
GET/v1/tiktok/songs/popular1 creditcacheablebatchable

Popular songs

Sounds trending in a market, the endpoint behind music A&R and sync-licensing research. From TikTok's Creative Center.

ParameterTypeRequiredDescription
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.
period7 | 30 | 120noTrailing window in days: 7, 30 or 120defaults to 7
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
titlestringalways
authorNamestring | nullalways
albumstring | nullalways
urlstringalways
coverUrlstring | nullalways
playUrlstring | nullalways
durationSecondsnumber | nullalways
isOriginalSoundboolean | nullalwaysTrue when the sound originated on TikTok rather than a licensed track.
videoCountnumber | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/songs/popular?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/songs/popular?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/songs/popular",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/songs/popular
Open the full playground
GET/v1/tiktok/transcript1 creditcacheablebatchable

Video transcript

The spoken transcript of a TikTok, as one text block plus timed cues. Returns the ORIGINAL spoken-language track by default rather than whichever track TikTok lists first, so the text reflects what was actually said. Pass language for a specific track. A miss is an error listing what is available, never a silent substitution into another language.

ParameterTypeRequiredDescription
urlstringyesVideo URL (preferred), share link, or numeric video id
languagestringnoBCP-47 or ISO-639 code, e.g. "en", "es", "pt-BR". Omit for the original spoken track.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one Transcript.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
postIdstringalways
urlstring | nullalways
languagestring | nullalwaysThe transcript's language as the platform labels it, usually a language code such as `en`.
isAutoGeneratedboolean | nullalwaysWhether the platform generated the captions automatically, by speech recognition or machine translation, rather than a person writing them.
textstringalwaysThe full transcript as a single block of text.
cuesobject[]alwaysTimed segments of the transcript.
cues[].startnumberalwaysSeconds from the start of the media.
cues[].endnumber | nullalwaysSeconds from the start of the media. Null when the platform gives no end time.
cues[].textstringalways
durationSecondsnumber | nullalways
sourcecaptions | asr | nullalwaysWhere the transcript came from. `captions`: the platform's own caption track, whether a person wrote it or the platform generated it (see `isAutoGenerated`). `asr`: produced by speech recognition on the audio. Null when this cannot be told.
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/transcript?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/transcript?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/transcript",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/transcript
Open the full playground
GET/v1/tiktok/user-videos1 creditcacheablebatchable

Videos posted by a creator

A creator's public posts, newest first, with view/like/comment/share counts. Photo posts are included and typed as image or carousel. Up to 15 per page, with a cursor for older posts.

ParameterTypeRequiredDescription
handlestringyesHandle (@nike), or a full tiktok.com profile URL
countnumbernoItems per page (default 35, max 35)
cursorstringnopagination.cursor from a previous response
max_cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/user-videos?handle=%40mkbhd&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  handle: '@mkbhd',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/user-videos?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/user-videos",
    params={
        "handle": "@mkbhd",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/user-videos
Open the full playground
GET/v1/tiktok/user/showcase1 creditcacheablebatchable

Creator's product showcase

Products a creator has pinned to their profile showcase. This is what they are actually promoting, as opposed to what they sell. Requires a configured TikTok signer.

ParameterTypeRequiredDescription
handlestringyesCreator handle, e.g. @charlidamelio
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of object in data.items.

Fields
FieldTypePresentDescription
platform"tiktok"always
idstringalways
titlestringalways
urlstring | nullalways
descriptionstring | nullalways
priceobjectalways
price.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
price.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
price.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
originalPriceobjectalways
originalPrice.amountnumber | nullalwaysNumeric amount in major units (12.99, not 1299). Null if unparseable.
originalPrice.currencystring | nullalwaysISO-4217 where TikTok gives one. Null means we will not guess.
originalPrice.formattedstring | nullalwaysExactly what TikTok displayed, e.g. "$12.99".
imageUrlsstring[]always
ratingnumber | nullalwaysStar rating out of 5. Null on a product with no reviews yet.
reviewCountnumber | nullalways
soldCountnumber | nullalways
inStockboolean | nullalways
sellerIdstring | nullalways
sellerNamestring | nullalways
categoryNamestring | nullalways
fetchedAtstringalways
curl
curl "$API/v1/tiktok/user/showcase?handle=%40mkbhd&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  handle: '@mkbhd',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/user/showcase?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/user/showcase",
    params={
        "handle": "@mkbhd",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/user/showcase
Open the full playground
GET/v1/tiktok/video1 creditcacheablebatchable

Video or photo-post details

Full public metadata for one TikTok: caption, hashtags, mentions, author, sound, duration, and view/like/comment/share counts. Photo posts return every image in mediaUrls. Accepts a full URL, a share link (vm.tiktok.com), or a numeric video id.

ParameterTypeRequiredDescription
urlstringyesVideo URL (preferred), share link, or numeric video id

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns one Post.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/video?url=8XkPqR2nLvE&cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  url: '8XkPqR2nLvE',
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/video?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/video",
    params={
        "url": "8XkPqR2nLvE",
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/video
Open the full playground
GET/v1/tiktok/videos/popular1 creditcacheablebatchable

Popular videos

Videos trending in a market over a trailing window, from TikTok's Creative Center. Distinct from /v1/tiktok/trending, which is the personalised For You feed.

ParameterTypeRequiredDescription
regionstringnoTwo-letter market code (US, GB, ID…). TikTok feeds and catalogues are per-market.
period7 | 30 | 120noTrailing window in days: 7, 30 or 120defaults to 7
countnumbernoItems per page (default 20, max 50)
cursorstringnopagination.cursor from a previous response

Also accepts cache_max_age (a hit costs 0 credits) and include_raw (returns the untouched upstream payload under raw).

Returns a list of Post in data.items.

Fields
FieldTypePresentDescription
platformone of 32 stringsalways
idstringalways
typevideo | short | image | carousel | text | live | story | reel | audio | album | episode | unknownalwaysWhat kind of post this is. `short` and `reel` are short-form video formats, `live` is a live stream or a recording of one, `carousel` holds several images or videos, `audio` is a music track, `album` is an album, `episode` is a podcast episode, and `unknown` covers anything else.
urlstring | nullalways
titlestring | nullalways
textstring | nullalwaysThe post's text: a caption, a description or the message body.
authorIdstring | nullalways
authorHandlestring | nullalways
authorNamestring | nullalways
thumbnailUrlstring | nullalways
mediaUrlsstring[]always
durationSecondsnumber | nullalways
viewCountnumber | nullalwaysViews. Null means the platform did not expose a count, which is not the same as zero.
likeCountnumber | nullalwaysLikes, or the platform's nearest equivalent. Null means not exposed, not zero.
commentCountnumber | nullalwaysComments. Null means not exposed, not zero.
shareCountnumber | nullalwaysShares, reposts, or the platform's nearest equivalent. Null means not exposed, not zero.
hashtagsstring[]alwaysHashtags or the platform's own topic tags, without the leading #.
mentionsstring[]alwaysHandles mentioned in the post text, without the leading @.
taggedUsersstring[]may be absentUsernames tagged in the media itself, as distinct from `mentions`, which come from the caption text. Absent when the platform does not report tags; an empty array means it reports none.
isSponsoredboolean | nullalwaysWhether the platform labels the post as an ad, promoted content or a paid partnership.
publishedAtstring | nullalwaysWhen the post was published. Usually an ISO 8601 timestamp; some platforms expose only a date or relative text such as "3 days ago".
fetchedAtstringalwaysWhen this record was fetched from the platform, as an ISO 8601 timestamp. A cached response keeps the time of the original fetch.
curl
curl "$API/v1/tiktok/videos/popular?cache_max_age=7d" \
  -H "x-api-key: $KEY"
TypeScript
const query = new URLSearchParams({
  cache_max_age: '7d',
});

const response = await fetch(`${API}/v1/tiktok/videos/popular?${query}`, {
  headers: { 'x-api-key': KEY },
});

const body = await response.json();
if (!body.success) throw new Error(body.error.code);

// 1 credit, 0 on a cache hit
console.log(body.data, body.meta.creditsCharged);
Python
Python
import os, httpx

r = httpx.get(
    f"{os.environ['API']}/v1/tiktok/videos/popular",
    params={
        "cache_max_age": "7d",
    },
    headers={"x-api-key": os.environ["KEY"]},
    timeout=30,
)

body = r.json()
if not body["success"]:
    raise RuntimeError(body["error"]["code"])

print(body["data"], body["meta"]["creditsCharged"])
Response codes
200Success
400invalid_request. Not charged
401missing_api_key / invalid_api_key / revoked_api_key. Never a billing error
402insufficient_credits. The key is valid, the balance is not
429daily_cap_exceeded or upstream_rate_limited. Not charged
501not_configured. This deployment is not set up to serve this endpoint. Not charged.
502upstream_blocked / upstream_schema_drift. Not charged
504upstream_timeout. Not charged
Try it here
GET/v1/tiktok/videos/popular
Open the full playground

Questions

How much does the TikTok API cost?
Calls cost 1 credit each. Every endpoint is cacheable, and a cache hit costs nothing. A failed request and an empty result are both free, on every endpoint.
Does the TikTok API need a login or cookies?
No. Every endpoint reads public, logged-out pages only — no account, no cookies, no session. An API key identifies your own TrueScrape account and nothing else.
Can I fetch many TikTok targets in one request?
Yes. 31 of 32 are batchable: one POST to /v1/jobs/batch takes many targets and returns a job id to poll.
Can I watch TikTok endpoints for changes?
Yes, 20 of 32. A subscription polls on your schedule and fires your webhook only when the content changed; the rest carry x-subscribable: false in the spec.