Tiktok Trending Hashtags Analytics Scraper avatar

Tiktok Trending Hashtags Analytics Scraper

Pricing

from $4.99 / 1,000 results

Go to Apify Store
Tiktok Trending Hashtags Analytics Scraper

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

API Empire

Maintained by Community

Actor stats

1

Bookmarked

42

Total users

17

Monthly active users

3 days ago

Last modified

Share

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.

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

InputStatusFlag written on every row
analytics_periodNo effect. TikTok scopes the popularity curve by the board window (top100_period) and exposes no second period parameter.analyticsPeriodRequested (your value), analyticsPeriodSupported: false
top100_industryNo 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_boardNo 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.

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 TypeKey FieldsJSON Field Names
Trending hashtagName, board rank, video views, posts, hashtag IDhashtag_name, rank, rankInt, video_views, videoViewsInt, publish_cnt, publishCntInt, hashtag_id
Popularity curveDaily trend points, curve span, completenessanalytics.trend, trendPointCount, trendFirstDate, trendLastDate, trendComplete
Top creatorsCreator handles attached to the hashtag, creator countanalytics.creators, topCreatorHandles, creatorCount
Industry tagsTikTok's own industry IDs for the hashtagindustryIds, industryIdCount, analytics.industry_ids
Coverage and provenanceRegion served vs requested, window served vs requested, which inputs were honoured, source URLregionRequested, 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.

FeatureOfficial TikTok APIsTikTok Trending Hashtags Analytics Scraper
Approval processResearch API: application and institutional eligibility reviewNone — run it from Apify Console
Who may use itResearch API: approved researchers in eligible regionsAnyone with an Apify account
Login / OAuthDisplay API: end-user OAuth requiredNone — anonymous requests only
Trending-board rankingsNot the purpose of either surfacePrimary output: rank, video_views, publish_cnt
Popularity curve per hashtagNot exposed as a trending-board curveanalytics.trend with trendFirstDate / trendLastDate
Coverage transparencyDocumented in TikTok's own developer docsPer-row flags: countrySupported, periodAliasApplied, industryFilterSupported
Output shapeTikTok's documented API schemaOne 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.

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.

This Actor runs on Apify. Start it from the Apify Console or call it through the Apify API.

  1. Open TikTok Trending Hashtags Analytics Scraper on Apify and click Try for free
  2. Pick a Country / region — check it against the 27 supported codes above, or accept that you will get the US board with countrySupported: false
  3. Pick a Board window (days): "7", "30" or "90" are real; "120" is served as 7
  4. Choose a Result typetop100_with_analytics for ranking plus curve and creators, top100 for the ranking alone, or analytics plus a hashtag_list to keep only named tags
  5. 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.

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.

ParameterRequiredTypeDescriptionExample Value
result_typeNostringWhich 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"
countryNostringCountry / 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_periodNostringBoard window in days. Enum "7", "30", "90", "120". "120" does not exist upstream and is served as 7 days. Default "7"."30"
analytics_periodNostringAccepted, no effect — kept for backwards compatibility. Enum "7", "30", "120", "365", "1095". Default "30"."30"
top100_industryNostringAccepted, no effect — kept for backwards compatibility. Nullable. Enum is "" plus the 20 industry names listed above. Default "".""
top100_new_on_boardNobooleanAccepted, no effect — kept for backwards compatibility. Default false.false
hashtag_listNoarrayHashtag 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_hashtagsNointegerUpper bound on the rows saved. Minimum 1, maximum 500. Default 10. TikTok's own board ceiling is lower — see below.10
proxyConfigurationNoobjectOptional. 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&region=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&region=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&region=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.

FeatureTikTok Trending Hashtags Analytics ScraperThe three listings checked on 25 July 2026
Per-row coverage flagscountrySupported, periodAliasApplied, industryFilterSupported, newOnBoardSupported on every row❌ Not documented on any of the three
Board size stated✅ 3 hashtags per country + window, measured 2026-07-23codebyte 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 publishedTwo of the three state "40+ countries"; none publishes a served-vs-fallback split
Uncharged failure rowsrowType: "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 ApifyClient
client = 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.

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.

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.

Scraper NameWhat it extracts
TikTok Trending Hashtags Scraper - Find New & Rising TagsNew and rising tag detection on the trending board
TikTok Video ScraperTikTok video records and their metrics
TikTok Comments Scraper With Commenter Profile & ContactsComment threads with commenter profile details
TikTok Profile Scraper With Bio Link & Contact LeadsCreator 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.