with one click
tiktok-research
// Research TikTok metadata, creators, comments, trends, and benchmark data for organic platform analysis.
// Research TikTok metadata, creators, comments, trends, and benchmark data for organic platform analysis.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | tiktok-research |
| description | Research TikTok metadata, creators, comments, trends, and benchmark data for organic platform analysis. |
| metadata | {"postplus":{"familyId":"tiktok","familyName":"TikTok"}} |
Use this skill for TikTok metadata research:
Follow shared routing and guidance rules in:
postplus-shared public skill rulespostplus-shared research preferencesRead these references before implementation:
${CLAUDE_SKILL_DIR}/references/actor-selection.md${CLAUDE_SKILL_DIR}/references/normalized-schema.md${CLAUDE_SKILL_DIR}/references/tool-contracts.mdDo not treat generic "TikTok research" requests as plain web search unless the user clearly wants external articles, policy, or news.
When using free-tier collection credits, prefer:
Do not brute-force full-market collection first. Sample, inspect, refine, then expand.
Current bounded-first-pass rule:
limit as the target shortlist or candidate goal, not as the per-query scrape sizebuild_tiktok_actor_input.mjs keep first-pass resultsPerPage / maxProfilesPerQuery bounded unless you explicitly need a broader second passtiktok-scraper, default to searchSection: "/video" for content-first creator discovery unless you intentionally want account-search behavior${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs${CLAUDE_SKILL_DIR}/scripts/build_tiktok_actor_input.mjs${CLAUDE_SKILL_DIR}/scripts/normalize_tiktok_dataset.mjs${CLAUDE_SKILL_DIR}/scripts/rank_tiktok_accounts.mjs${CLAUDE_SKILL_DIR}/scripts/expand_tiktok_creator_graph.mjs${CLAUDE_SKILL_DIR}/scripts/analyze_tiktok_dataset.mjs${CLAUDE_SKILL_DIR}/scripts/collect_top_video_comments.mjs${CLAUDE_SKILL_DIR}/scripts/analyze_tiktok_comments.mjs${CLAUDE_SKILL_DIR}/scripts/generate_tiktok_report.mjs${CLAUDE_SKILL_DIR}/templates/ — sample hashtag, search, and competitor input filesIn the PostPlus runtime, follow postplus-shared public skill rules.
TikTok-specific runtime notes:
${CLAUDE_SKILL_DIR}; do not rely on bare scripts/..., references/..., templates/..., or skills/20-research/tiktok-research/... paths that depend on the current working directory.items[].authorUsernameNode 18+ is required. This workspace already has Node available.
tiktok-scrapertiktok-user-search-scrapertiktok-profile-scrapertiktok-scrapertiktok-video-scrapertiktok-hashtag-scrapertiktok-comments-scrapertiktok-scrapertiktok-scraper-apitiktok-shop-creatorsTreat these as defaults, not hard requirements.
PostPlus runtime note:
tiktok-profile-scraper (secondary provider) remains shelved for current PostPlus runtime
runs. Do not route to it until billing adds and verifies a provider cost
rule.Start from the user's real collection surface, not from one favorite actor.
tiktok-scraper firsttiktok-user-search-scrapertiktok-profile-scrapertiktok-profile-scrapertiktok-scrapertiktok-hashtag-scrapertiktok-video-scrapertiktok-comments-scrapertiktok-comments-scrapertiktok-scrapertiktok-shop-creatorsDo not use TikTok Shop actors for generic creator discovery.
Do not use Creative Center ad actors as if they were organic creator data.
If the user wants paid ad intelligence, route to tiktok-ad-research.
If the user specifically wants TikTok music or sound discovery, route to:
tiktok-researchtiktok-music-sound-collector when releasedtiktok-music-archive-downloaderFor multi-step TikTok music workflows, read postplus-shared TikTok music workflow.
For TikTok creator discovery, do not default to plain user search when the brief includes:
5k-10kPrefer this order:
Use tiktok-user-search-scraper as a supplement, not the default first pass, unless the user explicitly wants account-search recall.
When the request is expressed as a research goal instead of actor JSON:
task, queries, hashtags, usernames, urls, limit, country${CLAUDE_SKILL_DIR}/scripts/build_tiktok_actor_input.mjsThis keeps the workflow stable even when actor input shapes differ.
Bounded brief rule:
limit set to the candidate or shortlist goal, not the per-query scrape sizeresultsPerPage, maxProfilesPerQuery, commentsPerPost, or scrapeRelatedVideos when the current step truly needs themInside the PostPlus runtime, prefer this order:
build_tiktok_actor_input.mjs directly with repeated flags such as:
--query--hashtag--username--url--limit--country--actor--output.postplus/ directory.postplus/.postplus/Direct-output rule:
${CLAUDE_SKILL_DIR}/scripts/build_tiktok_actor_input.mjs --output <actor-input.json> creates that actor-input file itselfRead or Write the actor-input output path before running that scriptFallback only when the direct flag path is genuinely awkward:
.postplus/ directory with the Write toolbuild_tiktok_actor_input.mjs against that .postplus/*.json briefFor a clear request like:
Find 20 TikTok KOLs suitable for selling skincare devices, prioritize micro and mid-tier accounts, and give me a shortlist for further filtering.default to this first move:
${CLAUDE_SKILL_DIR}/scripts/build_tiktok_actor_input.mjs with --query, --limit, --actor, and --output.postplus/${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs against that output fileDo not start by reading or writing a new .postplus/*.json file when the direct actor-input path already fits.
For creator discovery from a normalized videos dataset:
.items[].authorUsername.postplus/collection_actor_run.mjs with tiktok-profile-scraperrank_tiktok_accounts.mjs --profiles <profiles-normalized.json> --videos <videos-normalized.json>Do not call rank_tiktok_accounts.mjs with only --videos.
If you collect ranked results in multiple batches:
jq -s 'map(.items) | add | sort_by(-.followersCount) | .[0:20]' file-a.json file-b.json
Build input:
node ${CLAUDE_SKILL_DIR}/scripts/build_tiktok_actor_input.mjs \
--brief ${CLAUDE_SKILL_DIR}/templates/hashtags.json \
--actor tiktok-scraper \
--output <work-folder>/.postplus/hashtags-input.json
Run actor:
node ${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs \
--collection-key tiktok-videos \
--input <work-folder>/.postplus/hashtags-input.json \
--output <work-folder>/.postplus/hashtags.json
Then summarize:
node ${CLAUDE_SKILL_DIR}/scripts/normalize_tiktok_dataset.mjs \
--input <work-folder>/.postplus/hashtags.json \
--actor tiktok-scraper \
--dataset-type videos \
--output <work-folder>/.postplus/hashtags-normalized.json
node ${CLAUDE_SKILL_DIR}/scripts/analyze_tiktok_dataset.mjs \
--input <work-folder>/.postplus/hashtags-normalized.json
Build input:
node ${CLAUDE_SKILL_DIR}/scripts/build_tiktok_actor_input.mjs \
--brief ${CLAUDE_SKILL_DIR}/templates/searches.json \
--actor tiktok-scraper \
--output <work-folder>/.postplus/searches-input.json
Run actor:
node ${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs \
--collection-key tiktok-videos \
--input <work-folder>/.postplus/searches-input.json \
--output <work-folder>/.postplus/searches.json
Then summarize:
node ${CLAUDE_SKILL_DIR}/scripts/normalize_tiktok_dataset.mjs \
--input <work-folder>/.postplus/searches.json \
--actor tiktok-scraper \
--dataset-type videos \
--output <work-folder>/.postplus/searches-normalized.json
node ${CLAUDE_SKILL_DIR}/scripts/analyze_tiktok_dataset.mjs \
--input <work-folder>/.postplus/searches-normalized.json
{
"profiles": ["grammarly", "notionhq", "raycastapp"],
"resultsPerPage": 10
}
node ${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs \
--collection-key tiktok-profiles \
--input <work-folder>/.postplus/competitors.json \
--output <work-folder>/.postplus/competitors-results.json
Then normalize and rank:
node ${CLAUDE_SKILL_DIR}/scripts/normalize_tiktok_dataset.mjs \
--input <work-folder>/.postplus/competitors-results.json \
--actor tiktok-profile-scraper \
--dataset-type profiles \
--output <work-folder>/.postplus/competitors-profiles-normalized.json
node ${CLAUDE_SKILL_DIR}/scripts/rank_tiktok_accounts.mjs \
--profiles <work-folder>/.postplus/competitors-profiles-normalized.json
{
"searchQueries": ["ai tools", "productivity workflow", "gmail tips"],
"maxProfilesPerQuery": 8
}
node ${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs \
--collection-key tiktok-users \
--input <work-folder>/.postplus/creator-search.json \
--output <work-folder>/.postplus/creator-search-results.json
node ${CLAUDE_SKILL_DIR}/scripts/normalize_tiktok_dataset.mjs \
--input <work-folder>/.postplus/creator-search-results.json \
--actor tiktok-user-search-scraper \
--dataset-type user-search \
--output <work-folder>/.postplus/creator-search-normalized.json
node ${CLAUDE_SKILL_DIR}/scripts/rank_tiktok_accounts.mjs \
--profiles <work-folder>/.postplus/creator-search-normalized.json
Use this when the request cares about small creators, real topical activity, or content fit more than user-search ranking.
node ${CLAUDE_SKILL_DIR}/scripts/collection_actor_run.mjs \
--collection-key tiktok-videos \
--input <work-folder>/.postplus/topic-video-search.json \
--output <work-folder>/.postplus/topic-video-search-raw.json
node ${CLAUDE_SKILL_DIR}/scripts/normalize_tiktok_dataset.mjs \
--input <work-folder>/.postplus/topic-video-search-raw.json \
--actor tiktok-scraper \
--dataset-type videos \
--output <work-folder>/.postplus/topic-video-search-normalized.json
node ${CLAUDE_SKILL_DIR}/scripts/expand_tiktok_creator_graph.mjs \
--input <work-folder>/.postplus/topic-video-search-normalized.json \
--output <work-folder>/.postplus/topic-graph-raw.json \
--top 10 \
--results-per-seed 6
node ${CLAUDE_SKILL_DIR}/scripts/collect_top_video_comments.mjs \
--input <work-folder>/.postplus/searches.json \
--output <work-folder>/.postplus/comments.json \
--collection-key tiktok-comments \
--top 8 \
--max-comments 40
Then summarize:
node ${CLAUDE_SKILL_DIR}/scripts/analyze_tiktok_comments.mjs \
--input <work-folder>/.postplus/comments.json
node ${CLAUDE_SKILL_DIR}/scripts/generate_tiktok_report.mjs \
--keyword-summary <work-folder>/.postplus/searches-summary.json \
--hashtag-summary <work-folder>/.postplus/hashtags-summary.json \
--competitor-summary <work-folder>/.postplus/competitors-summary.json \
--comments-summary <work-folder>/.postplus/comments-summary.json \
--output reports/tiktok-research.md
Escalate to skills/40-creative/video-analysis when:
When the request is broad, ask one short guiding question before running:
Mention that this skill finds good samples first, and video-analysis can read the actual videos later.
Escalate to skills/20-research/tiktok-ad-research when:
This skill is primarily for research, not guaranteed video asset persistence.
If a later workflow needs the actual benchmark videos and the earlier local files are gone:
yt-dlpvideo-analysisDo not assume collection dataset items will always contain reusable mediaUrls or downloadAddr fields.
For each run, extract: