TikTok Profile Scraper — Creator Data & Performance Extraction
Pricing
from $40.00 / 1,000 profile scrapeds
TikTok Profile Scraper — Creator Data & Performance Extraction
Pull real TikTok creator numbers at scale — followers, engagement, video performance, growth velocity — with a 3-tier fallback that keeps working when TikTok fights back. Bulk usernames in, clean rows out. You only pay for profiles that actually return.
Pricing
from $40.00 / 1,000 profile scrapeds
Rating
0.0
(0)
Developer
Creator Fusion
Maintained by CommunityActor stats
0
Bookmarked
65
Total users
5
Monthly active users
5 days ago
Last modified
Categories
Share
TikTok Profile Scraper — Followers, Likes & Video Stats API for AI Agents
Extract public TikTok profile data — followers, likes, videos, bio, verified status, and stable user IDs — and get typed JSON rows back (full output schema below). Built for AI agents, data pipelines, and creator-intelligence workflows that need a row every run: a three-tier fallback (full page → embed → oEmbed) keeps returning real stats when TikTok blocks the primary path, deterministic field names never drift between runs, and failures fail loud instead of billing you for silent empty rows.
Why agents use this actor
- Deterministic typed output — every row follows the dataset schema below; field names and types never change between runs.
- Clear error semantics — invalid input or zero successful profiles exits non-zero with a status message. Failed profiles are listed in the
SUMMARYkey-value record, never mixed into the dataset, and you are never billed for them. - No auth needed — scrapes public profile pages; no TikTok account, cookies, or session tokens required.
- Cost-predictable — you pay per successful profile row plus proxy traffic, so autonomous budget guards work.
- Rate-limit handling built in — per-profile retries with backoff, anti-bot detection, and a two-stage fallback (embed page, then oEmbed) so blocked page requests still return real follower/like counts wherever possible.
Input schema
| Field | Type | Required | Default | Description |
|---|---|---|---|---|
usernames | array of strings | no* | — | TikTok usernames to scrape (without @). |
urls | array of strings | no* | — | TikTok profile URLs (alternative to usernames). |
username | string | no* | — | Convenience field for one profile. Equivalent to one entry in usernames. |
url | string | no* | — | Convenience field for one profile URL. Equivalent to one entry in urls. |
profileUrls | array of strings | no* | — | Alias for urls. |
proxyConfiguration | object | no | Apify residential | Proxy settings. Defaults to Apify residential proxy (billed to your account) — TikTok blocks datacenter IPs and direct connections, so residential is required for full profile data. |
maxRetries | integer | no | 3 | Retry attempts per profile (1–10). |
delayBetweenRequests | integer | no | 1000 | Delay in ms between profiles (0–10000). |
navigationTimeoutMs | integer | no | 25000 | Per-request timeout in ms (5000–120000). |
* At least one of usernames, urls, username, url, or profileUrls must yield a valid TikTok username, otherwise the run fails fast with exit code 1. All inputs are deduplicated; @ prefixes and full URLs are normalized automatically.
Minimal input:
{ "usernames": ["tiktok"] }
Output schema
One dataset row per successfully scraped profile. Three extraction modes share the same field set:
http-script— full data parsed from the TikTok page's embedded JSON. All fields populated when available.embed— the profile page was blocked, so data comes from TikTok's embed surface (tiktok.com/embed/@user). Returns real stats:followers,following,likes,nickname,bio,verified,private,userId.videos,avatarUrl, andsecUidmay benull.oembed-fallback— both page and embed surfaces blocked; data comes from TikTok's public oEmbed API. Returns a partial row:nickname,avatarUrl(sometimes), and identity fields only — all count fields (followers,following,likes,videos) andbio,verified,private,secUid,userIdarenull.
| Field | Type | Nullable | Description |
|---|---|---|---|
success | boolean | no | Always true for dataset rows. Failures never enter the dataset (see Error semantics). |
extractionMode | string | no | "http-script", "embed", or "oembed-fallback". |
username | string | no | Unique handle, lowercase, without @. |
sourceUrl | string | no | Canonical profile URL. |
nickname | string | yes | Display name. |
bio | string | yes | Profile bio text. Null in oembed-fallback mode. |
verified | boolean | yes | Verified badge. Null in oembed-fallback mode. |
private | boolean | yes | Private account flag. Null in oembed-fallback mode. |
followers | number | yes | Follower count. Null in oembed-fallback mode. |
following | number | yes | Following count. Null in oembed-fallback mode. |
likes | number | yes | Total likes (hearts) across all videos. Null in oembed-fallback mode. |
videos | number | yes | Public video count. Null in oembed-fallback mode. |
avatarUrl | string | yes | Profile picture URL (largest variant available). |
secUid | string | yes | TikTok's stable secure user ID. Null in oembed-fallback mode. |
userId | string | yes | TikTok's internal numeric user ID (as string). Null in oembed-fallback mode. |
scrapedAt | string | no | ISO 8601 scrape timestamp. |
Example row, http-script mode:
{"success": true,"extractionMode": "http-script","username": "tiktok","sourceUrl": "https://www.tiktok.com/@tiktok","nickname": "TikTok","bio": "The world's destination for short-form video.","verified": true,"private": false,"followers": 89200000,"following": 3,"likes": 358400000,"videos": 1024,"avatarUrl": "https://p16-sign-va.tiktokcdn.com/tos-maliva-avt-0068/...","secUid": "MS4wLjABAAAAv7iSuuXDJGDvJkmH_vz1qkDZYo1apxgzaxdBSeIuPiM","userId": "107955","scrapedAt": "2026-08-15T04:10:08.912Z"}
Example row, oembed-fallback mode (real output):
{"success": true,"extractionMode": "oembed-fallback","username": "charlidamelio","sourceUrl": "https://www.tiktok.com/@charlidamelio","nickname": "charli d’amelio","bio": null,"verified": null,"private": null,"followers": null,"following": null,"likes": null,"videos": null,"avatarUrl": null,"secUid": null,"userId": null,"scrapedAt": "2026-08-15T04:10:08.912Z"}
Error semantics
- Bad input (no valid usernames/URLs): run fails immediately with exit code 1 and status message
No valid TikTok usernames or URLs in input.... No dataset items, nothing billed. - Per-profile failure: each profile gets up to
maxRetriesattempts with linear backoff, then an embed-page fallback (real stats) and finally an oEmbed fallback. If everything fails, the profile is recorded in theSUMMARYkey-value record underfailures(withusername,sourceUrl,error) — not in the dataset, so failed profiles cost nothing. - Zero successes: run exits with code 1 and status
0/N profiles scraped - <first error>. A SUCCEEDED run always contains at least one dataset row. - Partial success: run succeeds; check the
SUMMARYrecord (requested,succeeded,failed,failures,finishedAt) to decide what to retry.
Retry guidance for agents: a SUCCEEDED run with extractionMode: "oembed-fallback" rows means TikTok blocked full extraction — re-running later or with a different residential proxy country often recovers the full row.
Use from AI agents (MCP)
{"mcpServers": {"apify": {"url": "https://mcp.apify.com/?tools=apricot_blackberry/tiktok-profile-scraper","headers": { "Authorization": "Bearer <YOUR_APIFY_TOKEN>" }}}}
Works in Claude, Cursor, ChatGPT deep research connectors, and any MCP client; the input schema above is the tool's parameter schema.
Use from code
curl:
curl -X POST "https://api.apify.com/v2/acts/apricot_blackberry~tiktok-profile-scraper/run-sync-get-dataset-items?token=$APIFY_TOKEN" \-H "Content-Type: application/json" \-d '{"usernames": ["tiktok"]}'
JavaScript (apify-client):
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: process.env.APIFY_TOKEN });const run = await client.actor('apricot_blackberry/tiktok-profile-scraper').call({usernames: ['tiktok'],});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
Python (apify_client):
from apify_client import ApifyClientclient = ApifyClient(os.environ["APIFY_TOKEN"])run = client.actor("apricot_blackberry/tiktok-profile-scraper").call(run_input={"usernames": ["tiktok"]})items = client.dataset(run["defaultDatasetId"]).list_items().itemsprint(items)
Use from automation platforms
- n8n / Make / Zapier: use the native Apify integration and pick
TikTok Profile Scraper(apricot_blackberry) by name. - LangChain / LlamaIndex: use the Apify tool/actor wrappers with actor ID
apricot_blackberry/tiktok-profile-scraper. - Webhooks: Apify can fire a webhook on
ACTOR.RUN.SUCCEEDED/FAILEDfor this actor, so downstream pipelines pick up new profile rows without polling.
Pricing
Pay per event: $0.10 actor start + $0.04 per successfully scraped profile, plus proxy traffic. Residential proxy is used by default and is billed to your account — TikTok blocks datacenter IPs, so this is required for full profile data. Failed profiles produce no dataset rows and are not billed.
Use cases
- Creator talent scouts: track emerging TikTok creators and follower growth over time by running daily and diffing
followers. - Marketing teams: qualify creators for partnerships with real follower, likes, and video counts.
- Competitive intelligence: monitor competitor accounts and engagement footprints.
- Cross-platform pipelines:
secUid/userIdare stable identifiers you can join against other TikTok datasets.
FAQ
Why are some rows missing follower counts?
Those rows have extractionMode: "oembed-fallback" — TikTok blocked the full page request and the actor fell back to TikTok's public oEmbed API, which only exposes name and avatar. Re-run later or with a different proxy country to recover full rows.
Do I need a TikTok account or cookies? No. Only public profile data is scraped.
Can I pass profile URLs instead of usernames?
Yes — urls, profileUrls, or single url all accept https://www.tiktok.com/@username links.
What happens if a username doesn't exist?
It ends up in the SUMMARY record's failures list with the error; it never appears in the dataset and is not billed.
Changelog
See ./CHANGELOG.md. Latest: output dataset schema added, agent-first documentation, MCP integration instructions, input aliases (url, profileUrls, navigationTimeoutMs) exposed in the input schema.
Built by Creator Fusion — OSINT tools that actually work.