Tiktok Trending Hashtags Analytics Scraper
Pricing
from $4.99 / 1,000 results
Tiktok Trending Hashtags Analytics Scraper
Tiktok Trending Hashtags Analytics Scraper delivers real-time analytics for trending TikTok hashtags. Extract views, growth, engagement signals, related tags, and performance insights. Ideal for research, content planning, and workflows needing accurate hashtag analytics.
Pricing
from $4.99 / 1,000 results
Rating
0.0
(0)
Developer
API Empire
Maintained by CommunityActor stats
1
Bookmarked
42
Total users
17
Monthly active users
3 days ago
Last modified
Categories
Share
TikTok Trending Hashtags Scraper — Ranks, Trend Curves, Creators
TikTok Trending Hashtags Analytics Scraper reads TikTok Creative Center's public trending-hashtag board for one country and one time window and returns every hashtag on it as typed JSON: board rank, video views, post count, hashtag ID, the daily popularity curve, TikTok's industry IDs and the top creators shipped with each row. No TikTok account, login or cookie. Every row also carries coverage flags recording which of your inputs TikTok honoured and which it silently ignored, so you can tell a real regional board from a US fallback before you build on it.
⚠️ Read the coverage section below before your first run. Four inputs on this Actor are accepted but have no effect upstream, and 49 of the 76 country values in the dropdown are not TikTok trending-board regions. Both facts are reported per row instead of being hidden.
What is TikTok Trending Hashtags Analytics Scraper?
TikTok Trending Hashtags Analytics Scraper is an Apify Actor that fetches one slice of TikTok Creative Center's public trending-hashtag board — one country plus one time window — and flattens every hashtag on that slice into a dataset row. It returns three kinds of data that ship inline with the board row: the hashtag itself (rank, views, posts, ID), its daily popularity curve, and the top creators TikTok attaches to it, plus the raw industry IDs TikTok tags each hashtag with.
No TikTok account, login, cookie or session is used. The Actor sends anonymous requests to the same public page loader that powers the Creative Center trends page in a browser.
- Scrape trending hashtags:
hashtag_name,rank,video_views,publish_cnt,hashtag_id - Scrape the daily popularity curve per hashtag:
analytics.trend,trendPointCount,trendFirstDate,trendLastDate - Scrape the top creators per hashtag:
analytics.creators,topCreatorHandles,creatorCount - Scrape TikTok's industry tags per hashtag:
industryIds,industryIdCount - Export as JSON, CSV or Excel — no proxy management, no HTML parsing
⚠️ Which inputs TikTok actually honours
This is the part most TikTok hashtag scrapers leave out. The Actor accepts every value in every dropdown, but TikTok's trend loader honours only some of them. Nothing is silently dropped: what the run asked for and what TikTok served are both written onto every row.
Four inputs are accepted and ignored
| Input | Status | Flag written on every row |
|---|---|---|
analytics_period | No effect. TikTok scopes the popularity curve by the board window (top100_period) and exposes no second period parameter. | analyticsPeriodRequested (your value), analyticsPeriodSupported: false |
top100_industry | No effect. TikTok's trend loader accepts no industry parameter — 25 spellings tested, byte-identical rows — and this Actor does no client-side filtering. Rows still carry the raw industryIds TikTok attaches. | industryRequested (your value), industryFilterSupported: false |
top100_new_on_board | No effect. TikTok returns identical rows with and without it and publishes no field marking a new entry (rankDiffType was absent from 0/243 live rows). | newOnBoardRequested (your value), newOnBoardSupported: false |
top100_period: "120" | Not a real upstream window. TikTok serves the 7-day board for it. | periodRequested: 120, periodUsed: 7, periodAliasApplied: true |
Real board windows are "7", "30" and "90". The popularity curve length follows the window you get, not the one you asked for.
The full top100_industry enum — all accepted, all without effect — is: "" (no filter), "Apparel & Accessories", "Baby, Kids & Maternity", "Beauty & Personal Care", "Business Services", "Education", "Financial Services", "Food & Beverage", "Games", "Healthcare", "Home Improvement", "Household Products", "Life Services", "News & Entertainment", "Pets", "Real Estate", "Software & Apps", "Sports & Outdoor", "Tech & Electronics", "Travel", "Vehicle & Transportation".
Country coverage is partial
TikTok publishes a trending board for 27 regions. The country dropdown carries 76 values because the historical input contract did; the other 49 are accepted and answered with the US board.
Served by TikTok (27): US FR DE IT ES GB AR AU BR CA CO EG ID IL JP KR MY MX PH SA SG ZA TW TH TR AE VN
Accepted, but served the US board (49): ALL AL AT BD BE BG BH BY CH CL CN CZ DK EE FI GR HK HR HU IE IN IQ IS JO KH KW KZ LB LT LU LV MA MN MO NG NL NO NZ OM PE PK PL PT QA RO SE SK UA UZ
"ALL" is not a TikTok region at all — it is in the list for backwards compatibility and resolves to the US board like the rest.
Pick one of the 49 and the run does not fail and does not invent a regional board. It logs a warning naming all 27 supported codes, then writes regionRequested (what you asked for), regionUsed: "US", countrySupported: false and countryFallbackApplied: true onto every row. Filter on countrySupported to keep only genuine regional data.
What data does TikTok Trending Hashtags Analytics Scraper collect?
Every run returns several related data types from a single request: the trending hashtag, its popularity curve, its top creators, its industry tags, and the coverage record for the run itself.
| Data Type | Key Fields | JSON Field Names |
|---|---|---|
| Trending hashtag | Name, board rank, video views, posts, hashtag ID | hashtag_name, rank, rankInt, video_views, videoViewsInt, publish_cnt, publishCntInt, hashtag_id |
| Popularity curve | Daily trend points, curve span, completeness | analytics.trend, trendPointCount, trendFirstDate, trendLastDate, trendComplete |
| Top creators | Creator handles attached to the hashtag, creator count | analytics.creators, topCreatorHandles, creatorCount |
| Industry tags | TikTok's own industry IDs for the hashtag | industryIds, industryIdCount, analytics.industry_ids |
| Coverage and provenance | Region served vs requested, window served vs requested, which inputs were honoured, source URL | regionRequested, regionUsed, regionName, countrySupported, countryFallbackApplied, periodRequested, periodUsed, periodAliasApplied, analyticsPeriodSupported, industryFilterSupported, newOnBoardSupported, boardRowsAvailable, boardTotalCount, sourceUrl, scrapedAt |
Need more TikTok data?
This Actor reads the trending board and stops there — deliberately. If you want new and rising tag detection on top of the board, TikTok Trending Hashtags Scraper - Find New & Rising Tags covers that angle. To go from a hashtag to the videos and people behind it, TikTok Video Scraper pulls video records, TikTok Comments Scraper With Commenter Profile & Contacts returns comment threads with commenter details, and TikTok Profile Scraper With Bio Link & Contact Leads builds creator records from the handles in topCreatorHandles.
How does this differ from the official TikTok APIs?
TikTok's official surfaces are approval-gated or account-scoped; this Actor reads the same public Creative Center board any anonymous visitor can load. The TikTok Research API requires an application and, per TikTok's published eligibility terms, is offered to approved researchers at qualifying academic and non-profit institutions in eligible regions. The TikTok Display API returns a user's own profile and videos after that user completes an OAuth login — it is not a market-intelligence surface.
| Feature | Official TikTok APIs | TikTok Trending Hashtags Analytics Scraper |
|---|---|---|
| Approval process | Research API: application and institutional eligibility review | None — run it from Apify Console |
| Who may use it | Research API: approved researchers in eligible regions | Anyone with an Apify account |
| Login / OAuth | Display API: end-user OAuth required | None — anonymous requests only |
| Trending-board rankings | Not the purpose of either surface | Primary output: rank, video_views, publish_cnt |
| Popularity curve per hashtag | Not exposed as a trending-board curve | analytics.trend with trendFirstDate / trendLastDate |
| Coverage transparency | Documented in TikTok's own developer docs | Per-row flags: countrySupported, periodAliasApplied, industryFilterSupported |
| Output shape | TikTok's documented API schema | One flat row per hashtag, same keys every run |
Check TikTok's current developer documentation for the exact eligibility criteria, scopes and rate limits before choosing — those terms change and are not reproduced here. Use the Research API when you need TikTok-sanctioned access to user-level and video-level data for published research. Use this Actor when you need the public trending board as structured JSON, today, without an approval cycle.
Why do teams scrape TikTok trending hashtags?
Trending-board data is aggregate marketing intelligence: what is rising, how fast, in which market, and who is riding it. Four groups use it differently.
For marketers and brand teams
Trend timing is the whole game. Run the board for your market on a schedule and diff rank and videoViewsInt per hashtag_name between runs to see whether a tag is climbing or already peaking — analytics.trend gives you the daily shape rather than a single snapshot, so you can tell a genuine rise from a one-day spike. industryIds tells you which vertical TikTok itself associates with the tag, which is a faster relevance check than eyeballing the videos. topCreatorHandles gives you named creators already producing inside that trend for outreach shortlists.
For AI engineers and agent builders
The row is already agent-shaped: flat, typed, stable keys, no HTML. Index hashtag_name, industryIds and analytics.trend into a vector store or a time-series table so an agent can answer "which tags are rising in Japan this week and what industries do they map to" against live board data instead of a stale export. Because coverage is declared in-band, a tool wrapper can refuse to answer on fallback data by checking countrySupported and periodAliasApplied — the agent never has to guess whether the country it asked for is the country it got.
For researchers and analysts
Everything returned is aggregate platform metadata — hashtag names, view and post counts, a normalised popularity curve, industry tags — published by TikTok on its own public marketing surface. That makes it usable for culture, media and market studies without touching individual user records. regionUsed, periodUsed, sourceUrl and scrapedAt on every row give you the provenance trail a methods section needs, and boardTotalCount records how many rows TikTok said the board held at capture time.
For developers building data products
Schedule the Actor per market, push rows into your warehouse, and build on stable keys. The historical contract fields (hashtag_id, hashtag_name, video_views, publish_cnt, rank, analytics) are never renamed or dropped, and every added field is additive. Uncharged accounting rows mean an empty board or a blocked run lands in your pipeline as a typed row carrying an errorReason, rather than as a silent zero-row success you have to detect downstream.
How to scrape TikTok trending hashtags (step by step)
This Actor runs on Apify. Start it from the Apify Console or call it through the Apify API.
- Open TikTok Trending Hashtags Analytics Scraper on Apify and click Try for free
- Pick a Country / region — check it against the 27 supported codes above, or accept that you will get the US board with
countrySupported: false - Pick a Board window (days):
"7","30"or"90"are real;"120"is served as 7 - Choose a Result type —
top100_with_analyticsfor ranking plus curve and creators,top100for the ranking alone, oranalyticsplus ahashtag_listto keep only named tags - Click Start, then export the dataset as JSON, CSV or Excel — or read it through the Apify API
No input is marked required. Running with defaults gives you the US 7-day board with full analytics.
What to do when TikTok changes its structure
The Actor is maintained, and the output schema is stable: the six historical contract fields keep their names and types, and new information arrives as additional keys rather than as renames. Changes on TikTok's side are absorbed inside the Actor, so integrations reading hashtag_name, rank or analytics.trend keep working.
What changed in TikTok trending-hashtag scraping recently?
Two changes measured against the live Creative Center surface on 2026-07-23 and recorded in this Actor's source explain why older TikTok hashtag scrapers return empty datasets.
The loader route became TLS/JA3 fingerprint gated. Any plain HTTP client — including Playwright's page.request, which uses Node's HTTP stack rather than the browser's TLS — is answered with HTTP 200 and a 49-byte empty body, {"dehydratedState":{"mutations":[],"queries":[]}}. The same URL and headers sent through curl_cffi with a Chrome impersonation profile return the full payload. A DIY scraper that only checks status codes sees a green 200 and writes zero rows without ever knowing it was refused.
The region parameter was renamed. The live surface reads region=. The older countryCode= parameter is unrecognised: countryCode=JP returns the US board and echoes countryCode:"US". Any scraper still sending countryCode is quietly serving US data for every market.
The same measurement pass found the board itself capped at 3 hashtags per country and window (totalCount:3 on 81/81 slices), with limit, page, pageSize and offset all ignored server-side. This Actor sends region=, impersonates Chrome at the TLS layer, and treats a tiny 200 body as a block rather than as an empty board. Maintenance tracks the loader route as it moves.
⬇️ Input
Every parameter is optional. Values come straight from the Actor's input schema — same names, same types, same defaults, same bounds.
| Parameter | Required | Type | Description | Example Value |
|---|---|---|---|---|
result_type | No | string | Which shape to return. "top100" = board ranking only, analytics comes back as an empty object. "top100_with_analytics" = ranking plus the popularity curve, industry IDs and top creators. "analytics" = the same analytics shape, restricted to the names in hashtag_list (they must be on today's live board — this Actor reads the board, it cannot look up an arbitrary hashtag). Default "top100_with_analytics". | "top100_with_analytics" |
country | No | string | Country / region board to read. 76 values accepted; only 27 are real TikTok trending-board regions, the other 49 are served the US board and flagged. Default "US". | "JP" |
top100_period | No | string | Board window in days. Enum "7", "30", "90", "120". "120" does not exist upstream and is served as 7 days. Default "7". | "30" |
analytics_period | No | string | Accepted, no effect — kept for backwards compatibility. Enum "7", "30", "120", "365", "1095". Default "30". | "30" |
top100_industry | No | string | Accepted, no effect — kept for backwards compatibility. Nullable. Enum is "" plus the 20 industry names listed above. Default "". | "" |
top100_new_on_board | No | boolean | Accepted, no effect — kept for backwards compatibility. Default false. | false |
hashtag_list | No | array | Hashtag names without the # sign, one per line. Used only when result_type is "analytics". Names are matched against the live board for the country and window you selected; anything not on today's board is skipped with a warning and no row is invented for it. Default []. | ["lemon8", "grwm"] |
total_hashtags | No | integer | Upper bound on the rows saved. Minimum 1, maximum 500. Default 10. TikTok's own board ceiling is lower — see below. | 10 |
proxyConfiguration | No | object | Optional. Apify Proxy or your own proxy URLs. The board is selected by the region= parameter, not by your exit IP, so a proxy is optional here. Default {"useApifyProxy": true}. | {"useApifyProxy": true} |
Common pitfall: setting result_type to "analytics" and expecting arbitrary hashtag lookups. hashtag_list is a filter over today's board, not a search. A tag that is not currently trending in the country and window you chose produces no row — see the FAQ for exactly what you get instead.
Example input
{"result_type": "top100_with_analytics","country": "US","top100_period": "7","analytics_period": "30","top100_industry": "","top100_new_on_board": false,"hashtag_list": [],"total_hashtags": 10,"proxyConfiguration": { "useApifyProxy": true }}
⬆️ Output
Every row is flat, typed JSON with the same 40 top-level keys in the same order, run after run. Keys are never omitted: a value that is absent comes back as null, [] or {}, so downstream code never needs a presence check. Export as JSON, CSV or Excel, or read the dataset through the Apify API.
Two naming details are preserved rather than tidied. The six historical contract fields are snake_case (hashtag_id, hashtag_name, video_views, publish_cnt, rank, analytics) while everything added since is camelCase — the mix is the contract, not an oversight. And rank is coerced to an integer at the top level while analytics.rank keeps the raw string TikTok sends, because that is what the original shape did. Use rankInt, videoViewsInt and publishCntInt when you want guaranteed numbers.
Board ranking with analytics (result_type: "top100_with_analytics")
The default shape. All 40 keys, analytics populated.
{"hashtag_id": "73422076","hashtag_name": "lemon8","video_views": "109725286","publish_cnt": "33723","rank": 2,"analytics": {"video_views": "109725286","publish_cnt": "33723","rank": "2","industry_ids": [22000000000],"trend": [{ "timestamp": 1752969600 },{ "timestamp": 1753056000 },{ "timestamp": 1753142400 },{ "timestamp": 1753228800 },{ "timestamp": 1753315200 },{ "timestamp": 1753401600 },{ "timestamp": 1753488000 }],"creators": [{ "handleName": "dailytrendlab" },{ "handleName": "the.styleroom" },{ "handleName": "citybreakfastclub" }]},"videoViewsInt": 109725286,"publishCntInt": 33723,"rankInt": 2,"industryIds": [22000000000],"industryIdCount": 1,"trendPointCount": 7,"trendComplete": true,"trendFirstDate": "2026-07-20","trendLastDate": "2026-07-26","creatorCount": 3,"topCreatorHandles": "dailytrendlab, the.styleroom, citybreakfastclub","rowType": "hashtag","resultType": "top100_with_analytics","regionRequested": "US","regionUsed": "US","regionName": "United States","countrySupported": true,"countryFallbackApplied": false,"periodRequested": 7,"periodUsed": 7,"periodAliasApplied": false,"analyticsPeriodRequested": "30","analyticsPeriodSupported": false,"industryRequested": null,"industryFilterSupported": false,"newOnBoardRequested": false,"newOnBoardSupported": false,"totalHashtagsRequested": 10,"boardRowsAvailable": 3,"boardTotalCount": 3,"sourceUrl": "https://ads.tiktok.com/creative/creativeCenter/trends/hashtag?__loader=creativeCenter%2Ftrends%2F%28tab%29%2Fpage&__ssrDirect=true®ion=US&period=7","scrapedAt": "2026-07-25T09:14:02.481230+00:00","errorReason": null,"errorMessage": null}
Entries inside analytics.trend and analytics.creators are TikTok's own objects, forwarded unchanged. The Actor reads timestamp from a curve point (to derive trendFirstDate and trendLastDate) and handleName from a creator (to build topCreatorHandles); any other keys TikTok ships inside those objects arrive with them.
Board ranking only (result_type: "top100")
The same 40 keys, with one difference: analytics is an empty object. The flattened analytics fields still populate from the same board row, because none of them costs an extra request.
{"hashtag_id": "73422076","hashtag_name": "lemon8","video_views": "109725286","publish_cnt": "33723","rank": 2,"analytics": {},"videoViewsInt": 109725286,"publishCntInt": 33723,"rankInt": 2,"industryIds": [22000000000],"industryIdCount": 1,"trendPointCount": 7,"trendComplete": true,"trendFirstDate": "2026-07-20","trendLastDate": "2026-07-26","creatorCount": 3,"topCreatorHandles": "dailytrendlab, the.styleroom, citybreakfastclub","rowType": "hashtag","resultType": "top100","regionRequested": "US","regionUsed": "US","regionName": "United States","countrySupported": true,"countryFallbackApplied": false,"periodRequested": 7,"periodUsed": 7,"periodAliasApplied": false,"analyticsPeriodRequested": "30","analyticsPeriodSupported": false,"industryRequested": null,"industryFilterSupported": false,"newOnBoardRequested": false,"newOnBoardSupported": false,"totalHashtagsRequested": 10,"boardRowsAvailable": 3,"boardTotalCount": 3,"sourceUrl": "https://ads.tiktok.com/creative/creativeCenter/trends/hashtag?__loader=creativeCenter%2Ftrends%2F%28tab%29%2Fpage&__ssrDirect=true®ion=US&period=7","scrapedAt": "2026-07-25T09:14:02.481230+00:00","errorReason": null,"errorMessage": null}
result_type: "analytics" produces the same shape as top100_with_analytics, with resultType set to "analytics" and only the board rows whose hashtag_name matched your hashtag_list.
Uncharged accounting row (rowType: "accounting")
When a run produces no hashtag rows, it writes one typed accounting row instead of finishing as a silent zero. It carries the same 40 keys with the data fields nulled, and it is never charged.
{"hashtag_id": null,"hashtag_name": null,"video_views": null,"publish_cnt": null,"rank": null,"analytics": {},"videoViewsInt": null,"publishCntInt": null,"rankInt": null,"industryIds": [],"industryIdCount": 0,"trendPointCount": 0,"trendComplete": false,"trendFirstDate": null,"trendLastDate": null,"creatorCount": 0,"topCreatorHandles": null,"rowType": "accounting","resultType": "analytics","regionRequested": "US","regionUsed": "US","regionName": "United States","countrySupported": true,"countryFallbackApplied": false,"periodRequested": 7,"periodUsed": 7,"periodAliasApplied": false,"analyticsPeriodRequested": "30","analyticsPeriodSupported": false,"industryRequested": null,"industryFilterSupported": false,"newOnBoardRequested": false,"newOnBoardSupported": false,"totalHashtagsRequested": 10,"boardRowsAvailable": 3,"boardTotalCount": 3,"sourceUrl": "https://ads.tiktok.com/creative/creativeCenter/trends/hashtag?__loader=creativeCenter%2Ftrends%2F%28tab%29%2Fpage&__ssrDirect=true®ion=US&period=7","scrapedAt": "2026-07-25T09:14:03.117402+00:00","errorReason": "filtered_empty","errorMessage": "Your hashtag_list matched none of the 3 hashtag(s) on the live US/7d board. Nothing was fabricated and nothing was charged."}
errorReason takes one of four values: "board_empty" (the loader answered with a full payload but the board carried no hashtag rows), "filtered_empty" (your hashtag_list matched nothing on the board), "engine_blocked" (the loader refused at the transport layer), or "unexpected_error".
Which rows are charged
This Actor charges per event. Exactly one event exists, row_result, and it fires only when a real hashtag row is pushed. Accounting rows are pushed with charging disabled — an empty board, an unmatched hashtag_list or a transport-layer block costs you nothing and still leaves a typed, inspectable row in the dataset.
To keep only billable data rows in your pipeline, filter on:
rows = [r for r in items if r["rowType"] == "hashtag"]
The run log closes with the split, for example Done. 3 charged hashtag row(s), 0 uncharged accounting row(s).
How does this compare to other TikTok hashtag scrapers?
Checked on the Apify Store on 25 July 2026. codebyte/tiktok-trending-hashtags-analytics is the most established of the three, with a README documenting the same three result_type modes and a richer analytics blob — audience_interests, audience_countries, audience_ages_readable, related_hashtags, related_items and longevity — plus country_info, industry_info, is_promoted, rank_diff_type and rank_change_readable on the ranking row. Its custom-list input key is hashtags, not hashtag_list. api-empire/tiktok-trending-hashtags-analytics-scraper and scrapeflow/tiktok-trending-hashtags-analytics-scraper publish byte-identical READMEs to each other.
| Feature | TikTok Trending Hashtags Analytics Scraper | The three listings checked on 25 July 2026 |
|---|---|---|
| Per-row coverage flags | ✅ countrySupported, periodAliasApplied, industryFilterSupported, newOnBoardSupported on every row | ❌ Not documented on any of the three |
| Board size stated | ✅ 3 hashtags per country + window, measured 2026-07-23 | codebyte documents "top 100 trending hashtags"; the other two document "up to 500 hashtags per run" |
| Which inputs have no effect | ✅ Named in the schema and flagged per row | ❌ Not documented; two of the three list industry filtering as a headline feature |
| Country coverage | ✅ 27 served, 49 fall back to US, both lists published | Two of the three state "40+ countries"; none publishes a served-vs-fallback split |
| Uncharged failure rows | ✅ rowType: "accounting" with a typed errorReason | ❌ Not documented on any of the three |
If you are building an AI agent or a RAG pipeline, the coverage-flag row is the decision-maker: an agent that cannot tell a Japanese board from a US fallback will confidently report the wrong market. Parsing HTML inside an agent loop is a reliability failure mode, not a feature — every row here is typed JSON with fixed keys.
How many results can you scrape?
total_hashtags accepts 1 to 500 with a default of 10 — but that ceiling is the input schema's, not TikTok's. The public trend board serves a hard maximum of 3 hashtags per country and window, measured as totalCount:3 on 81 of 81 slices tested on 2026-07-23, and the server ignores limit, page, pageSize, size and offset entirely. Setting total_hashtags above 3 is accepted and logged with a warning; it does not add rows.
There is no pagination to configure, because there is no second page to fetch. The Actor makes one request per run for one (region, period) slice and saves up to total_hashtags rows from it. boardRowsAvailable records how many rows the board actually carried and boardTotalCount records the totalCount TikTok reported — compare both against totalHashtagsRequested to see whether your cap or TikTok's was the binding one.
To cover more ground, run the Actor once per country and window on an Apify schedule and union the datasets.
How does it handle TikTok's TLS gate and blocking?
The Creative Center loader route is fingerprint gated, so the Actor requests it through curl_cffi with a Chrome 131 impersonation profile rather than a default HTTP client signature, sending the same accept, referer and x-requested-with headers a browser sends.
Failure handling is layered. Each fetch retries up to 3 times with exponential backoff and a 45-second request timeout. A response is treated as refused when the status is not 200, when the body is 200 bytes or smaller, or when the JSON fails to parse — so the 49-byte empty-payload signature is caught as a block rather than parsed into zero rows. If a proxied request comes back refused, the Actor retries the same slice directly and says so in the log. If every attempt fails, it raises, sets a run status message explaining that the refusal happened at the TLS layer and is not caused by your country or window, and writes an uncharged engine_blocked accounting row.
Proxies are optional: the board is selected by the region= URL parameter, not by your exit IP. proxyConfiguration defaults to {"useApifyProxy": true}, and if no usable proxy configuration can be built the run continues directly with a warning rather than failing.
Integrate this scraper and automate your workflow
TikTok Trending Hashtags Analytics Scraper is an Apify Actor, so it works with any language or tool that can send an HTTP request.
REST API integration
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("<YOUR_USERNAME>/tiktok-trending-hashtags-analytics-scraper-pay-per-events").call(run_input={"result_type": "top100_with_analytics","country": "JP","top100_period": "7","total_hashtags": 10,"proxyConfiguration": {"useApifyProxy": True},})for row in client.dataset(run["defaultDatasetId"]).iterate_items():if row["rowType"] != "hashtag":print("no data:", row["errorReason"], row["errorMessage"])elif row["countrySupported"]:print(row["rank"], row["hashtag_name"], row["videoViewsInt"], row["topCreatorHandles"])
Works in Python, Node.js, Go, Ruby, cURL.
Automation platforms (n8n, Make, LangChain)
In n8n, use the Apify node — or an HTTP Request node pointed at the Apify run endpoint with your token — and pass the same JSON input shown above; an IF node on rowType splits data rows from accounting rows before anything downstream sees them. In Make, the Apify module supports run-and-wait, so a weekly board sweep can feed a Google Sheets or Airtable step directly. In LangChain, wrap the Apify run call as a tool and expose country and top100_period as its arguments, returning only the rowType == "hashtag" rows to the model. Apify schedules and webhooks handle recurrence and downstream triggers, so a daily per-market sweep needs no code.
Is it legal to scrape TikTok trending hashtags?
Scraping publicly published marketing-intelligence data is broadly treated as permissible where no authentication is bypassed, and this Actor reads only TikTok Creative Center — TikTok's own public marketing surface — with no account, cookie or session.
What it returns is aggregate business data: hashtag names, view and post counts, a normalised popularity curve and TikTok's own industry tags. These are platform metrics, not personal records, so GDPR and equivalent personal-data regimes do not attach to them the way they would to a profile scraper. The obligations that do apply are contractual and database-related: TikTok's terms of service, and local database or unfair-competition rules covering systematic reuse of a compiled dataset. One caveat: the top-creator block (analytics.creators, topCreatorHandles) names public creator accounts, so treat that sub-object with the same care you would give any public profile handle.
Consult legal counsel for commercial use cases involving bulk personal data, or before republishing the board as a competing dataset.
❓ Frequently asked questions
Does this scraper work without a TikTok account?
Yes. No TikTok account, login, cookie or session is used. The Actor sends anonymous requests to the public Creative Center page loader. The only credential you need is your Apify token.
How often is the scraped data updated?
Every run fetches live. Nothing is cached between runs — the Actor makes one request to the loader per run and writes what TikTok returns at that moment, stamped with scrapedAt. Put it on an Apify schedule if you want a daily or weekly series.
What happens when a hashtag in hashtag_list is not on today's board?
Nothing is returned for it, and nothing is invented. hashtag_list filters the live board for the country and window you chose; it is not a lookup. Unmatched names are logged with a warning naming each one. If none of your names match, the run writes a single uncharged accounting row with errorReason: "filtered_empty" and a message stating how many board rows it compared against. Since the board holds at most 3 hashtags per slice, most arbitrary lists will match nothing — run top100_with_analytics first to see what is actually on the board.
What happens if I select a country TikTok does not serve?
The run succeeds and returns the US board, clearly labelled. Only 27 of the 76 dropdown values are real TikTok trending-board regions. Pick one of the other 49 and the Actor logs a warning listing all 27 supported codes, then writes regionRequested with your code, regionUsed: "US", countrySupported: false and countryFallbackApplied: true on every row. Filter on countrySupported to drop fallback data automatically.
Why do I only get three hashtags when I asked for more?
Because that is the whole board. TikTok serves a maximum of 3 hashtags per country and window — totalCount:3 on 81 of 81 slices measured on 2026-07-23 — and ignores limit, page, pageSize and offset. A total_hashtags of up to 500 is accepted and logged, but it caps rather than extends. Compare totalHashtagsRequested, boardRowsAvailable and boardTotalCount on any row to confirm.
Which rows am I charged for?
Only real hashtag rows, under the single row_result event. Accounting rows — the ones written when the board is empty, your filter matched nothing, or the loader refused the request — are pushed uncharged. Filter with row["rowType"] == "hashtag" to isolate the charged rows.
Can I scrape private TikTok accounts or restricted hashtag data?
No. This Actor reads one public surface: the Creative Center trending-hashtag board. It does not open user profiles, private accounts, login-gated Creative Center reports or any TikTok Ads Manager data. If it is not published on the public trends board, it is not in the output.
Does this work for AI agent workflows and LLM pipelines?
Yes. It is callable as a standard HTTP endpoint through the Apify API, so LangChain, CrewAI, n8n or a hand-written tool definition can invoke it and receive typed, normalized JSON with fixed key names — no HTML, no selectors, no parsing step before the model sees it. The coverage flags are what make it safe inside an agent loop: a tool wrapper can check countrySupported and periodAliasApplied and decline to answer on fallback data rather than reporting the wrong market with confidence.
How does it handle TikTok's anti-bot defences, and do I need my own proxies?
TikTok's defence on this route is a TLS/JA3 fingerprint gate, not a captcha and not an IP block — a mismatched client gets HTTP 200 with a 49-byte empty body. The Actor answers it with Chrome 131 TLS impersonation and browser headers, retries up to 3 times with exponential backoff, and treats any body of 200 bytes or less as a refusal. You do not need to manage proxies: the board is selected by the region= parameter rather than your exit IP, proxyConfiguration defaults to Apify Proxy, and a failed proxied request is retried directly and logged.
How does this compare to other TikTok trending hashtags scrapers?
Checked on the Apify Store on 25 July 2026, codebyte/tiktok-trending-hashtags-analytics documents the same three result_type modes with a deeper analytics blob — audience ages, audience countries, related hashtags and related videos — and takes its custom list under the key hashtags. api-empire/tiktok-trending-hashtags-analytics-scraper and scrapeflow/tiktok-trending-hashtags-analytics-scraper publish byte-identical READMEs, both headlining industry filtering, "40+ countries" and "up to 500 hashtags per run". None of the three documents which inputs the upstream loader ignores, or which countries fall back to the US board. That is this Actor's difference: the same board data, plus a per-row record of exactly what TikTok honoured.
What happens when TikTok changes its structure or blocks the scraper?
The Actor is maintained, and the output schema stays stable on your end — the six historical contract fields keep their names and types, and new information is added as new keys rather than as renames. When the loader refuses a request outright you get an uncharged engine_blocked accounting row and a run status message saying the refusal happened at the TLS layer, rather than a silent empty dataset you have to notice yourself.
🔗 Related scrapers
| Scraper Name | What it extracts |
|---|---|
| TikTok Trending Hashtags Scraper - Find New & Rising Tags | New and rising tag detection on the trending board |
| TikTok Video Scraper | TikTok video records and their metrics |
| TikTok Comments Scraper With Commenter Profile & Contacts | Comment threads with commenter profile details |
| TikTok Profile Scraper With Bio Link & Contact Leads | Creator profiles, bio links and contact details |
💬 Your feedback
Found a bug, or need a field that TikTok ships in the board row but the Actor does not surface yet? Open an issue on the Actor's Issues tab. Reports that include the exact input JSON, the country and the window are the fastest to reproduce and fix.