TikTok Video Detail Scraper avatar

TikTok Video Detail Scraper

Pricing

from $2.00 / 1,000 video details

Go to Apify Store
TikTok Video Detail Scraper

TikTok Video Detail Scraper

Fetch TikTok video details (caption, author, stats, media URLs) by ID. Requests are signed in pure Python - no browser and no JS engine.

Pricing

from $2.00 / 1,000 video details

Rating

0.0

(0)

Developer

COIN J

COIN J

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

a day ago

Last modified

Security

Limited permissions

Share

Fetch TikTok video details - caption, hashtags, mentions, author counters, engagement stats, music, and CDN media URLs - for a list of video URLs or IDs. Every request is signed locally in pure Python: no browser, no Node.js, no JS engine, no external TikTok API.

What you get

One dataset item per input, with the same field layout as the popular TikTok video scrapers, so existing pipelines keep working.

GroupFields
Videoid, text, textLanguage, createTime, createTimeISO, webVideoUrl, submittedVideoUrl, isAd, isSlideshow, isMuted, isPinned, isSponsored, locationCreated
Stats (flat)playCount, diggCount, commentCount, shareCount, collectCount, repostCount
authorMetaid, name, profileUrl, nickName, verified, privateAccount, signature, avatar, originalAvatarUrl, fans, video, following, heart, followDatasetUrl
musicMetamusicName, musicAuthor, musicOriginal, musicId, playUrl, coverMediumUrl
videoMetawidth, height, duration, coverUrl, definition, format, downloadAddr
MediamediaUrls (CDN ladder, best first), slideshowImageLinks
Text extrasmentions, detailedMentions, hashtags, effectStickers
Provenanceinput, url, fromProfileSection, searchQuery, searchHashtag, searchMusic, originalVideoDetail, commentsDatasetUrl
Errorserror, errorCode, invalidUrls

Input

{
"postURLs": [
"https://www.tiktok.com/@user/video/7621991999251467550",
"7621991999251467550"
],
"maxConcurrency": 5,
"proxyConfiguration": { "useApifyProxy": true }
}

Accepted inputs: full video URLs, short links (vt. / vm. forms), bare numeric video IDs.

Error handling

Failures never abort a run - each one becomes its own dataset item with the same field shape:

errorCodeMeaning
INVALID_URLSInput carried no TikTok video ID
POST_NOT_FOUND_OR_PRIVATEVideo deleted, private, or unavailable
POST_SENSITIVETikTok restricts this video (region or sensitive content)
FETCH_FAILEDNetwork or parsing failure after retries

How it works

  1. Resolves the input to a numeric video ID.
  2. Builds the /api/item/detail/ query from a captured desktop-web request profile.
  3. Signs it locally in Python: X-Dynosaur (SDK envelope), X-Gnarly (behaviour envelope), X-Bogus.
  4. Sends the request with curl_cffi impersonating Chrome, so the TLS fingerprint matches what TikTok's SDK expects.
  5. Maps the payload into the flat record shape above.

Signatures are generated fresh for every request, so the same video can be re-fetched any number of times.

Fields that are always null

These keys exist for shape compatibility but the detail endpoint does not expose the data:

locationCreated, locationMeta, isMuted, isPinned, isSponsored, originalVideoDetail, commentsDatasetUrl, fromProfileSection, searchQuery, searchHashtag, searchMusic

isPinned additionally needs profile context, and commentsDatasetUrl would require a comments collector (out of scope for this Actor).

Notes and limits

  • Video URLs and IDs only - profiles, hashtags and search feeds are out of scope.
  • The MP4 files themselves are not downloaded: mediaUrls and videoMeta.downloadAddr return TikTok CDN links, which are short-lived. Save what you need promptly.
  • repostCount is null on videos where TikTok does not report it.
  • Residential proxies give the best success rate, because requests are signed for the desktop web client.
  • TikTok changes its signing SDK periodically. If runs start returning empty bodies, the signing profile needs refreshing.

Local development

uv venv .venv
uv pip install --python .venv/Scripts/python.exe -r requirements.txt
python tests/check_mapper.py # offline field-shape checks
apify run # local run; input in storage/key_value_stores/default/INPUT.json
apify push # deploy