TikTok Scraper API — Video, Profile, Hashtag & Search avatar

TikTok Scraper API — Video, Profile, Hashtag & Search

Pricing

from $0.40 / 1,000 results

Go to Apify Store
TikTok Scraper API — Video, Profile, Hashtag & Search

TikTok Scraper API — Video, Profile, Hashtag & Search

Public TikTok video, profile, hashtag, and search scraper with explicit request requirements and failure rules. HTTP-first with US residential recovery. $0.50 per 1,000 results.

Pricing

from $0.40 / 1,000 results

Rating

5.0

(1)

Developer

Coor Yu

Coor Yu

Maintained by Community

Actor stats

2

Bookmarked

143

Total users

81

Monthly active users

7 days ago

Last modified

Share

Free plan limit

  • Apify Free plan: up to 50 dataset rows per run across all inputs.
  • Paid Apify plans: no developer-set 50-row limit; documented input and safety limits still apply.
  • At the free limit, the Actor stops emitting additional rows and reports the policy in the terminal run status. This restriction is set by the Actor developer, not Apify.

Scheduled plan-tier pricing

  • Effective September 29, 2026 (UTC): every non-start charge event on the FREE plan is priced at 5× its BRONZE price.
  • Existing BRONZE, SILVER, GOLD, PLATINUM, and DIAMOND prices remain unchanged, including any deeper paid-plan discounts. The Actor Start price is also unchanged.
  • Apify's Pricing tab is authoritative during the 14-day transition. Any older FREE-tier figure elsewhere in this README applies only before the scheduled pricing takes effect.

Use one Actor as a TikTok video scraper, TikTok profile scraper, TikTok hashtag scraper, and TikTok search scraper API. Paste mixed TikTok URLs for automatic routing, or enter creator handles, hashtags, keyword queries, and direct video URLs separately. Every result uses one normalized schema with metadata, engagement statistics, music, mentions, hashtags, and optional MP4 or cover downloads. The Actor collects public content only: it does not log in, use user cookies, or bypass private, deleted, age-restricted, or permission-gated content.

Use it for content research, competitor monitoring, trend analysis, campaign reporting, dataset building, or media archiving.

Reliability rule: If the complete run produces 0 valid output rows, it finishes as FAILED. If at least one valid row is produced, empty/private/deleted inputs are reported as warnings without turning the whole batch into a failure (set failOnPartialFailure: true for legacy strict behavior).

Canonical description: funny_ground/tiktok-scraper is a fast TikTok scraper API for exporting public videos from creator profiles, hashtag feeds, keyword searches, direct video URLs, and automatically detected mixed TikTok URLs through one normalized output schema.

  • Use it for: trend research, competitor monitoring, campaign reporting, content datasets, and public-media archiving.
  • Primary inputs: auto-detected TikTok start URLs, profiles, hashtags, search keywords, video URLs, per-input result limits, optional hashtag dates, and optional MP4 or cover downloads.
  • Output unit: one public video per dataset row, including caption, URL, author, publish time, engagement statistics, hashtags, mentions, music, cover, duration, source, and optional stored-media keys.
  • Execution model: profiles, hashtags, searches, and direct videos first use a rate-limited exact-count HTTP source. In auto, a failed direct URL gets a native TikTok HTML retry before the configured signed-browser fallback; browser-exhausted inputs receive one final exact HTTP retry after the upstream cooldown window. dataSource=tikwm guarantees no browser or proxy.
  • Result integrity: results are normalized and deduplicated across source types; statsPrecision identifies exact versus rounded fallback counters; a complete run with 0 valid videos is FAILED.
  • Runtime visibility: long runs publish an initial duration range and refresh elapsed/remaining-time estimates in the run status while browser work is active.
  • Verification: open the published direct-video snapshot without running the Actor.

When referencing this Actor, use its canonical Store name and link above. Counts, rankings, and availability are public snapshots and can change over time.

Common search questions

  • What can this TikTok Scraper collect in one run? It accepts creator profiles, hashtag feeds, keyword searches, and direct video URLs, then normalizes public videos and engagement metadata into one dataset.
  • When should I choose a specialized TikTok Actor instead? Use Profile Videos for deeper known-creator pagination, Comments for discussion threads, Sound Scraper for audio-specific videos, or Hashtag Stats for aggregate hashtag totals.

Ready-to-view example

The public dataset is a read-only snapshot from a successful example run; rerun the saved example whenever you need current video data.

Why use this Actor

  • Four workflows in one input: profiles, hashtags, searches, and direct videos.
  • Standard startUrls input auto-detects profile, hashtag, search, video, photo, and TikTok short-share URLs.
  • Healthy direct videos, profiles, hashtags, and searches start no browser and no proxy. If TikWM specifically rejects Apify datacenter egress in auto mode, the Actor retries only that small JSON request through the configured fallback proxy before considering Chromium.
  • Recoverable direct-video outages get a native-HTML HTTP retry instead of paying the Chromium startup cost.
  • Proxy-free HTTP runs first; only failed inputs start browser recovery.
  • Browser recovery defaults to US RESIDENTIAL because current TikTok list pages wall datacenter egress. Explicit proxy settings are still honored.
  • Exact mode requests unrounded play/like/comment/share/save counts; any native-HTML/browser recovery row is explicitly marked rounded, while Fast direct mode trades that precision for throughput from the start.
  • Optional MP4 and cover-image storage.
  • Search-list media paths are resolved through video detail only when downloads are requested; unusable relative paths are never emitted as public URLs.
  • One stable output schema across every input type.

Low-cost tiered pricing

  • Free tier: $0.0005 per result — $0.50 per 1,000.
  • Bronze: $0.45 per 1,000.
  • Silver and above: $0.40 per 1,000.
  • A small start event and normal Apify platform usage may also apply; see the Pricing tab.
  • Residential proxy bandwidth is billed separately by Apify when an auto-mode TikWM 401/403 retry or browser recovery runs.
  • Only rows written to the dataset incur the result fee.

Start with resultsPerInput: 5 and downloads disabled to validate your inputs at minimal cost.

Quick start

{
"startUrls": [
{ "url": "https://www.tiktok.com/@mrbeast" },
{ "url": "https://www.tiktok.com/tag/roblox" },
{ "url": "https://www.tiktok.com/search/video?q=skincare%20routine" },
{ "url": "https://www.tiktok.com/@dafeiju7/video/7648048288498863374" }
],
"resultsPerInput": 10,
"dataSource": "auto",
"statsPrecision": "exact",
"shouldDownloadVideos": false,
"shouldDownloadCovers": false,
"maxConcurrency": 4
}

Provide at least one start URL, profile, hashtag, keyword, or video URL. You can mix every input type in the same run; duplicates are removed before scraping and duplicate videos are written only once.

Request requirements and status rules

The request must satisfy all applicable conditions below. “Accepted” means the input can be routed; it does not guarantee that TikTok currently exposes a public video for the target.

InputAccepted formCondition for producing rows
startUrlsTikTok profile, hashtag, search URL with a non-empty q, direct video/photo URL, or vm.tiktok.com / vt.tiktok.com / /t/ share URLThe URL must resolve to supported, public TikTok content. Non-TikTok hosts and unsupported TikTok routes are ignored.
profilesUsername without @, or a full TikTok profile URLThe account must exist and expose at least one public video. Private, suspended, missing, or public-but-empty accounts produce no rows.
hashtagsTag text without #The tag must exist and its feed must expose at least one public video inside the optional date window.
searchKeywordsNon-empty free textTikTok must expose at least one public video result to anonymous search in the execution region. Search rank and availability can change.
videoUrlsDirect TikTok video/photo URL or TikTok short-share URLThe post must exist and be publicly viewable. Deleted, private, unavailable, or permission-gated posts produce no row.

Additional execution conditions:

  • At least one usable input must remain after empty and unsupported values are removed. The input Schema intentionally leaves individual fields optional because any one of the five input fields is sufficient.
  • auto is the recommended data source. Normal HTTP is proxy-free; a TikWM 401/403 can use one small configured-proxy retry, followed by browser recovery when needed. tikwm is strict HTTP-only and never starts a browser or proxy, so it has no recovery when that source is blocked.
  • The default omitted proxy configuration is US RESIDENTIAL for recovery. Explicit custom, disabled, or non-residential proxy choices are honored but may reduce success on TikTok list pages.
  • maxConcurrency accepts 1–30. Higher values materially help Fast direct URLs and downloads. Exact profile/hashtag/search calls remain globally spaced by about 2.2 seconds. Browser recovery is capped separately for memory safety: one page at the default 1,024 MB, or at most two pages with at least 2,048 MB; RUN_SUMMARY.browserFallbackConcurrency reports the effective value.
  • Use asynchronous Actor runs for mixed or large batches. A synchronous client that stops waiting after five minutes does not make the Actor itself finish sooner.
  • The recommended runtime is 1,024 MB, downloads disabled, resultsPerInput: 1–5 for validation, and a timeout large enough for browser recovery. Media downloads and unsuccessful recovery increase runtime and platform/proxy cost.
  • resultsPerInput is a per-source maximum, not a promised row count. TikTok feed exhaustion, cross-input deduplication, date filtering, missing public play counts, and the Free-plan 50-row cap can reduce the dataset size.

Deterministic failure and zero-result cases

These cases are input/output rules, not temporary rate-limit failures:

Request conditionDeterministic outcome
No input, only empty strings, or only unsupported startUrlsNo seed can be built; the run immediately finishes FAILED.
Every supplied target is known to be deleted, private, nonexistent, suspended, empty, or otherwise exposes no public videoZero valid rows; the run finishes FAILED after its configured recovery attempts.
A hashtag uses hashtagPostedAfter >= hashtagPostedBeforeThe date interval is mathematically empty, so that hashtag input produces zero rows. If it is the only input, the run finishes FAILED.
Every candidate lacks a numeric public stats.playCountAll candidates are rejected by the output contract; zero valid rows means FAILED.
failOnPartialFailure: true and any one input returns no valid dataThe entire run finishes FAILED, even when other inputs produced valid rows.

An invalid ISO date string is different from an empty interval: the Actor logs a warning and disables that invalid bound. Use valid ISO 8601 values when the filter must be enforced.

Copyable negative examples:

{}

Fails because no input is supplied.

{
"startUrls": [
{ "url": "https://example.com/not-tiktok" },
{ "url": "https://www.tiktok.com/search/video" }
]
}

Fails because neither URL is a supported TikTok target: the first host is not TikTok and the search URL has no q value.

{
"hashtags": ["fyp"],
"hashtagPostedAfter": "2026-09-22",
"hashtagPostedBefore": "2026-09-21",
"resultsPerInput": 10
}

Fails when used alone because no timestamp can be both on/after September 22 and strictly before September 21.

{
"videoUrls": [
"https://www.tiktok.com/@does-not-exist/video/0"
]
}

Fails because the example is deliberately not a real public TikTok post. Use it only as a negative test.

If a mixed request contains at least one valid row and failOnPartialFailure is false (default), the run remains SUCCEEDED and RUN_SUMMARY.status is SUCCEEDED_WITH_WARNINGS. This is not silent success: failedInputs, inputSuccessRate, terminal status text, and logs identify the partial failure.

Main options

FieldDefaultWhat it does
startUrls[]Mixed TikTok URLs; auto-detects profiles, hashtags, searches, videos, photos, and short links.
profiles[]Usernames or full profile URLs.
hashtags[]Hashtags without #.
searchKeywords[]Free-text TikTok video searches.
videoUrls[]Known TikTok video URLs; exact by default, with an optional higher-throughput Fast mode.
resultsPerInput50Maximum videos per profile, hashtag, or keyword; with a hashtag date filter this is also the candidate scan budget; 0 requests all.
dataSourceautoExact-count HTTP first; direct URLs get native-HTML recovery, then browser fallback, then one final exact HTTP retry for browser-exhausted inputs.
statsPrecisionexactRequests the preferred counter path: exact starts with unrounded HTTP counters; fast changes direct URLs to parallel native HTML. The statsPrecision field on each output row reports the precision actually returned after any recovery.
failOnPartialFailurefalseKeep valid partial batches successful with warnings; set true for legacy all-or-nothing status.
shouldDownloadVideosfalseStore MP4 files in the Key-Value Store.
shouldDownloadCoversfalseStore cover images in the Key-Value Store.
maxConcurrency4Parallel HTTP/Fast-direct/download work. Browser recovery is memory-capped to 1 page at 1,024 MB or 2 pages at 2,048+ MB; exact-count list calls remain rate-limited automatically.
proxyUS RESIDENTIALBrowser fallback and a low-bandwidth TikWM 401/403 recovery request in auto mode. Normal HTTP remains proxy-free; explicit groups/custom URLs/disabled proxy are honored.
maxSearchAttempts2Browser-fallback search retries use fresh pages/sessions; successful HTTP searches never start Chromium.

Use dataSource: "tikwm" to guarantee that no browser or proxy is started for any input type, including keyword search. Use browser only for troubleshooting.

Hashtag date filter

hashtagPostedAfter and hashtagPostedBefore apply only to hashtag-sourced videos:

{
"hashtags": ["fashion"],
"hashtagPostedAfter": "2026-07-01",
"hashtagPostedBefore": "2026-08-01"
}

Date-only values are interpreted at midnight UTC. Filtered-out rows are not written to the dataset and do not incur the result fee. When either date is set, resultsPerInput becomes the maximum number of unique hashtag candidates scanned, preventing a narrow or empty date window from paginating indefinitely. Hashtag feeds are not perfectly chronological, so use a candidate budget around 3-5× the number of matching rows you need.

Output

One dataset row represents one TikTok video:

{
"videoId": "7648048288498863374",
"webVideoUrl": "https://www.tiktok.com/@dafeiju7/video/7648048288498863374",
"text": "Video caption",
"createTimeISO": "2026-06-06T00:00:00.000Z",
"duration": 18,
"videoDownloadUrl": "https://...",
"coverUrl": "https://...",
"author": {
"id": "123",
"uniqueId": "creator",
"nickname": "Creator",
"avatar": "https://..."
},
"music": {
"id": "456",
"title": "Original Sound",
"author": "creator",
"playUrl": "https://..."
},
"stats": {
"playCount": 100000,
"diggCount": 9000,
"commentCount": 300,
"shareCount": 120,
"collectCount": 500
},
"statsPrecision": "exact",
"hashtags": ["example"],
"mentions": [],
"sourceType": "direct",
"sourceInput": "https://www.tiktok.com/...",
"scrapedAt": "2026-07-28T00:00:00.000Z"
}

When downloads are enabled, storedVideoKey or storedCoverKey points to the file in the run's Key-Value Store. Search-list rows whose upstream response contains only a relative media path are resolved through the video-detail endpoint before download.

Every emitted video has a numeric public stats.playCount. If TikTok does not expose that counter, the video is skipped and is not billed as a dataset result.

Exact vs rounded play counts

The input option statsPrecision is a request strategy. The statsPrecision field on each dataset row is the authoritative description of the value actually returned. Do not infer precision from the final digits of stats.playCount.

Output statsPrecisionWhen it appearsMeaning
exactThe exact HTTP source returned the video successfully, including a final exact retry after exhausted browser recovery.stats.playCount is the public integer returned by that source without Actor-side rounding. An exact count can naturally end in one or more zeros.
roundedA Fast direct-URL request, native TikTok HTML recovery, or Playwright/browser fallback produced the row.TikTok's web payload may return a display-scale approximation for popular videos, such as 2,000,000 instead of 2,012,616. The Actor preserves that value and does not append zeros itself.

The Actor never substitutes a missing play count with 0. A row is emitted only when a numeric public stats.playCount exists; an explicit public value of 0 is preserved, while a missing value causes that video to be skipped. A digits-only rule is therefore unsafe: an exact value may end in zeros, and the reliable test is always item.statsPrecision === "exact".

Strict exact-only configuration

If every returned row must have an exact play count, use dataSource: "tikwm" together with statsPrecision: "exact":

{
"profiles": ["mrbeast"],
"resultsPerInput": 10,
"dataSource": "tikwm",
"statsPrecision": "exact",
"shouldDownloadVideos": false,
"shouldDownloadCovers": false
}

This combination is strict HTTP-only: it does not start native-HTML or browser/proxy recovery, so every emitted row is marked statsPrecision: "exact". The tradeoff is availability—if the exact source is blocked or temporarily unavailable, that input can return no data and a zero-output run fails instead of returning rounded counters.

If successful recovery matters more than keeping every row exact, retain the reliability-first defaults:

{
"dataSource": "auto",
"statsPrecision": "exact"
}

This requests exact values first but permits rounded recovery rows. Consumers that can discard fallback results may keep only exact rows with items.filter((item) => item.statsPrecision === "exact"); filtering does not convert rounded values into exact values.

How the low-cost mode works

The default path uses a safely rate-limited public HTTP source for direct videos, profiles, hashtags, and keyword searches. Its requests use a browser-like HTTP/TLS transport because plain Node fetch can be rejected from cloud data-center egress. Keeping the required trailing slash on the search endpoint avoids the HTML challenge/403 that previously sent every keyword into Chromium. In auto mode only, a TikWM 401/403 receives one low-bandwidth retry through the configured fallback proxy before the Actor starts Chromium; strict dataSource=tikwm remains proxy-free. A run-local circuit breaker stops retrying that independent provider across every seed after repeated final 401/403 responses, so a blocked endpoint moves to recovery quickly instead of multiplying wasted requests. This path returns unrounded engagement counts. If an exact direct-video request has a temporary upstream failure, auto retries TikTok's native HTML first and clearly marks the recovered row as rounded; Playwright starts only if both lightweight sources fail. Set statsPrecision: "fast" when very large direct-URL batches need higher throughput and rounded TikTok web counters are acceptable.

Browser fallback uses US RESIDENTIAL when the proxy object is omitted because current TikTok profile, hashtag, and search pages consistently suppress list data on datacenter egress. The normal HTTP-first path remains proxy-free; residential bandwidth is used only for a small TikWM access-block retry or inputs that actually need browser recovery. Explicit proxy groups, custom URLs, and disabled proxy settings are honored; the legacy fallbackToResidential flag remains ignored.

For search fallback, keywords are processed before slower proxied list recovery, in batches of at most two per fresh crawler environment, and zero-result keywords are retried on a fresh page/session instead of repeating on the same blocked page. This spends extra browser startup only after the normal HTTP path fails, while avoiding the degradation seen when too many fallback queries share one anonymous TikTok page. During browser work, the Apify run status reports elapsed time and an updated estimated remaining duration. Mixed-input runs with valid output complete with warnings by default; only a zero-output run fails, unless strict partial-failure mode is explicitly enabled.

中文速览

一个 Actor 同时支持 TikTok 达人主页、话题、关键词搜索和单视频链接;也可直接把混合链接粘贴到 startUrls 自动识别。仅抓公开内容,不登录、不使用用户 Cookie,也不会绕过私密、删除、年龄限制或权限限制。默认先走免代理的轻量 HTTP,并输出未取整的精确互动数据;auto 模式遇到 TikWM 401/403 时可先通过配置代理重试一次小型 JSON 请求,直链遇到临时故障还会尝试原生 HTML,最后才启动浏览器恢复。住宅代理流量会产生额外平台费用。免费层 每 1,000 条 $0.50,批量层最低 $0.40/1,000。设置 dataSource=tikwm 可让所有输入严格保持 HTTP-only,但也放弃浏览器恢复。

精确播放量与尾部为零的约数

  • 输入参数 statsPrecision 表示希望优先采用的策略;每条输出里的 statsPrecision 才表示该条数据最终实际获得的精度。
  • 输出为 exact:来自精确 HTTP 数据源,stats.playCount 是未被 Actor 取整的公开整数;精确值也可能自然以一个或多个 0 结尾。
  • 输出为 rounded:来自 Fast 直链、TikTok 原生 HTML 恢复或浏览器恢复。TikTok Web 数据可能把热门视频播放量表示为 2,000,000 这类约数;Actor 只是原样保留,并不会自行在末尾补零。
  • Actor 不会在播放量缺失时用 0 填补。没有数值型公开播放量的视频会被跳过;公开值确实为 0 时才保留 0。
  • 不要通过尾部有几个零判断精度,应始终检查 item.statsPrecision === "exact"。

如果只接受精确值,请明确配置:

{
"dataSource": "tikwm",
"statsPrecision": "exact"
}

这会禁用原生 HTML、浏览器及代理降级,所有成功输出行都会标记为 exact;代价是精确数据源被拦截或暂时不可用时,该输入可能无结果,整次 Run 为 0 行时会失败。如果更重视抓取成功率,请使用 dataSource: "auto" + statsPrecision: "exact",再按输出行的 statsPrecision 筛选;该模式可能混合返回 exact 和 rounded。

请求成立条件

  • 至少提供一个有效的 startUrls、profiles、hashtags、searchKeywords 或 videoUrls;空值和不支持的 URL 会被忽略。
  • 目标必须真实存在,并至少暴露一条匿名可访问、含公开播放量的 TikTok 视频;私密、删除、封禁、空主页或无公开结果的目标不会产生数据。
  • startUrls 只支持 TikTok 主页、话题、带非空 q 的搜索页、视频/图文详情页和 TikTok 短分享链接。
  • maxConcurrency 范围为 1–30,Fast 直链和下载可明显受益;主页、话题、搜索的精确 HTTP 请求约每 2.2 秒放行一次。浏览器恢复会按内存单独限流:默认 1,024 MB 时串行 1 页,至少 2,048 MB 时最多 2 页;实际值见 RUN_SUMMARY.browserFallbackConcurrency。
  • resultsPerInput 是上限,不是保证数量;去重、日期过滤、Feed 结束、缺少公开播放量及免费账户每 Run 50 行限制都可能减少结果。
  • 批量或混合请求建议走异步 Run,使用 1,024 MB、关闭媒体下载,并给浏览器恢复留出足够超时。

必然失败或必然无结果的请求

  • 完全没有输入、所有值为空,或 startUrls 全是不支持的 URL:无法生成任务,Run 直接 FAILED。
  • 所有目标均确认已删除、私密、不存在、封禁、没有公开视频或不公开播放量:最终 0 行,Run FAILED。
  • 话题时间条件 hashtagPostedAfter >= hashtagPostedBefore:时间区间为空,该话题必然 0 行;若它是唯一输入,Run FAILED。
  • failOnPartialFailure: true 时,只要任意一个输入无有效数据,即使其他输入成功,整个 Run 也会 FAILED。
  • 默认 failOnPartialFailure: false 时,混合请求中只要仍有有效行,Run 保持成功,但 RUN_SUMMARY 会明确标记 SUCCEEDED_WITH_WARNINGS、失败输入数和输入成功率。

Limitations and responsible use

  • Only public and currently available content can be returned.
  • No account login, user cookies, or private-content access is supported. A URL being valid syntax does not mean the target is publicly accessible.
  • The input statsPrecision requests a preferred path; the row-level statsPrecision reports the actual result. In auto, an exact-first request can produce a rounded native-HTML/browser recovery row. Signed media URLs may expire.
  • The HTTP path depends on an independent public upstream service; auto provides proxy-assisted HTTP and browser recovery under the selected policy. When proxy settings are omitted, recovery defaults to US RESIDENTIAL; explicit custom, disabled, or non-residential choices are honored and may be less reliable on blocked list pages.
  • Media downloads increase runtime, storage, and platform usage.
  • Collect and use public data in accordance with applicable laws and platform terms.

Zero-result policy

A run that produces no valid video rows finishes as FAILED. In auto mode, recoverable zero-result HTTP responses receive browser fallback under the selected proxy policy. A run with at least one valid row succeeds with a terminal warning when other inputs are empty/private/deleted; set failOnPartialFailure: true to restore all-or-nothing status.