TikTok Trending Feed API
For You by default; pass orderBy/period/page for Creative Center popular videos (like/hot/comment/repost) with totalCount. Flat 2 credits.
GET request to /v1/tiktok/trending-feed that responds with clean JSON and costs 2 credits. Pass cache=true for a free 24h cache hit; default is always fresh. Start with 100 free credits — no credit card.What is the TikTok Trending Feed API?
Default: TikTok For You / recommend feed with rank, publishedAt, caption (null when empty), mediaType, durationSeconds, thumbnailUrl, author{}, and engagement{}. mediaType is photo only when the canonical url contains /photo/ (or durationSeconds is null and the payload is an image post) — never because videoUrl is omitted. Session-cookie-bound web URLs (tk=tt_chain_token, or the same check hidden in a base64 policy= param) 403 for callers and are never shipped — when only those exist, videoUrl is omitted and you open the post via url; that row is still a video. author.followers is read from the feed author card when present, then hydrated from /api/user/detail for unique handles still null (8s budget). Photo rows ship images[] + imageCount (numbered-dict slides and bitrate_images included; item/detail when the feed shipped one image). videoUrlExpiresAt / thumbnailUrlExpiresAt are the split CDN windows (~36h on play URLs — the shortest in the catalogue). Envelope matches instagram/trending-reels: platform, country, countryCode, cached, source (for_you | creative_center | cache), totalReturned, requested, hasMore, nextCursor (always null — For You has no stable cursor), truncatedReason (single_page_only when the For You page filled; chart-page on a filled Creative Center page), fetchedAt, timings{path,fetchMs,hydrateMs,totalMs}. hasMore is true with nextCursor null only when truncatedReason names the cap — same rule as truth-social/user-posts. engagement always keys views/likes/comments/shares/saves/downloads plus *IsApproximate on each. Pass orderBy (hot|like|comment|repost — unknown values are 400; vv/views are aliases of hot and the response echoes hot), period (7|30|120), page, or countryCode to switch to the TikTok Creative Center popular-videos chart. A chart miss falls through to For You posts inside the period window, re-sorted by the requested metric (note says so). Hard 110s deadline. A wall with a 6h last-good page is labelled stale 200 at 0 credits; a miss with no snapshot is 502 UPSTREAM_UNAVAILABLE at 0 credits — never a billed 200 the proxy cannot deliver. country / countryCode is the chart market in Creative Center mode; on For You it is a region-availability hint. Flat 2 credits per call.
What you get
- For You richness: engagement{} + author.followers + rank
- Split videoUrlExpiresAt / thumbnailUrlExpiresAt (~36h play URLs)
- Photo carousels: images[] + imageCount
- Envelope aligned with instagram/trending-reels (hasMore / requested / truncatedReason)
- orderBy / period / countryCode / page → Creative Center chart (fallthrough re-sorted)
- Flat 2 credits
Try it
Fill in the parameters below and copy a ready-to-run request, or open the live Playground to run it against your account (no API key paste).
Parameters
curl "https://api.captapi.com/v1/tiktok/trending-feed" \
-H "Authorization: Bearer capt_live_..."
# or: -H "x-api-key: capt_live_..."Edit the parameters and the code updates instantly. Switch languages and hit copy.
Example response
{
"success": true,
"data": {
"platform": "tiktok",
"country": "US",
"countryCode": "US",
"cached": false,
"totalReturned": 2,
"requested": 20,
"hasMore": false,
"nextCursor": null,
"truncatedReason": null,
"fetchedAt": "2026-08-03T11:30:00.000Z",
"results": [
{
"url": "https://www.tiktok.com/@adamjones73/video/7660991836407811358",
"id": "7660991836407811358",
"coverUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oERcgNIQQgASfTiefnLoipqrkyeCfiAGGKmNEI~tplv-tiktokx-origin.image?dr=9636&x-expires=1785517200&x-signature=FF%2Fhr528f3arMCaHqCr9%2BeBIue0%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
"author": "adamjones73",
"authorName": "Adam",
"views": 5400000,
"likes": 823500,
"comments": 4301,
"shares": 147900,
"rank": 1,
"caption": "#gta #viral #fyp",
"platform": "tiktok",
"createTime": 1783713660,
"publishedAt": "2026-07-10T20:01:00.000Z",
"mediaType": "video",
"thumbnailUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oERcgNIQQgASfTiefnLoipqrkyeCfiAGGKmNEI~tplv-tiktokx-origin.image?dr=9636&x-expires=1785517200&x-signature=FF%2Fhr528f3arMCaHqCr9%2BeBIue0%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
"isAd": false
},
{
"url": "https://www.tiktok.com/@123court/video/7655473367125855519",
"id": "7655473367125855519",
"coverUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oIMffQHCCga9fWiRXUy8JOfP3WVUFGAL7oQtAQ~tplv-tiktokx-origin.image?dr=9636&x-expires=1785517200&x-signature=zF4ZAiNfBFLlLm4zu51g3NjykhI%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
"author": "123court",
"authorName": "123 Court",
"views": 3600000,
"likes": 133800,
"comments": 1872,
"shares": 8999,
"rank": 2,
"caption": "Engaged Mom Demands More Money, But Judge Finds Out The Shocking Truth! #CourtroomDrama #FamilyCourt #ChildSupport #ChildSupportCourt #JudgeJules #InstantKarma #Backfired #CaughtInTheAct #PlotTwist #TruckDriverLife #CoParenting #SplitCustody #SiblingDrama #RevengeBackfires",
"platform": "tiktok",
"createTime": 1782428791,
"publishedAt": "2026-06-25T23:06:31.000Z",
"mediaType": "video",
"thumbnailUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oIMffQHCCga9fWiRXUy8JOfP3WVUFGAL7oQtAQ~tplv-tiktokx-origin.image?dr=9636&x-expires=1785517200&x-signature=zF4ZAiNfBFLlLm4zu51g3NjykhI%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
"isAd": false
}
]
}
}Billing metadata is returned in response headers: X-Captapi-Credits (credits charged), X-Captapi-Cache (hit or miss), and X-Captapi-Source. Failed requests (4xx/5xx) are never charged. See the full list of error codes in the error reference.
Response structure
A successful call returns success and a data object with the following fields:
Top-level fields
platformPlatform identifier for this response (matches the endpoint's platform).countryCountry for the request context. On popular-creators top-level: ISO feed market you queried (e.g. US) — not each creator's home country (see region).countryCodeISO-3166 alpha-2 (same as country on this endpoint).cachedtrue on a cache hit when cache=true. Default fetch is fresh.source"for_you" (default recommend feed) or "creative_center" (popular-videos chart). A chart miss falls through to for_you with note set.totalReturnedNumber of items returned in this response.requestedThe limit you asked for.hasMoreTrue when this page filled the requested limit. nextCursor stays null on For You — then truncatedReason is single_page_only. Never true without a cursor unless that reason (or chart-page) is set.nextCursorAlways null on For You (no stable cursor). Creative Center uses the page query, not a cursor.truncatedReasonsingle_page_only when the For You page filled limit (more exist, unreachable). chart-page when a Creative Center page filled. null when the page is short.fetchedAtWhen this request completed (ISO-8601). There is no scrapedAt / createTime twin.periodLookback days (7, 30, or 120). Present in chart mode. Every publishedAt is inside this window.pageCreative Center page. Present in chart mode.orderByPublic sort: hot | like | comment | repost. vv is accepted as an alias of hot and echoed as hot. On fallthrough the list is actually sorted by this metric.notePresent on For You fallthrough: chart unavailable, period window applied, list sorted locally by orderBy.
Results
Each item in results contains:
urlCanonical URL of the item.idId of this results item.coverUrlCover image URL.authorAuthor object {id, secUid, username, displayName, url, followers, verified, profileImage}. Not a handle string — the pre-TK-C author/authorName pair is gone.authorNameName of the author.viewsView count when the platform exposes one.likesLike count (number).commentsComment count.sharesShare count. On analytics endpoints: null when the platform has no public share metric (stable schema). On single-platform endpoints the key is omitted instead.rankRank position in the list.captionAlways keyed. Null when the post has no caption — not omitted.platformPlatform identifier for this response (matches the endpoint's platform).createTimeWhen the account was created (ISO 8601).publishedAtPublish date (ISO 8601) when the platform exposes an absolute timestamp.mediaType"video" | "photo". Photo only when url contains /photo/ (or durationSeconds is null on an image post). Not inferred from videoUrl — session-bound play URLs are omitted on videos.thumbnailUrlThumbnail image URL.isAdWhether the item is a paid promotion.
Timings
The timings object contains:
pathPath. Example: "for_you".totalMsTotal ms. Example: 32775.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| country | string | No | Two-letter ISO country (default US). For You: region-availability hint. Creative Center mode: chart market. |
| countryCode | string | No | Alias of country. Wins when both are set. |
| orderBy | string | No | Creative Center sort: hot (views), like, comment, or repost. Unknown values are 400. vv/views/plays are aliases of hot — the response echoes the public name. Setting this (or period / page>1) switches from For You to the popular-videos chart. On a For You fallthrough the same sort is applied locally. |
| period | integer | No | Lookback days: 7, 30, or 120 (180→120). Triggers chart mode. Every returned publishedAt is inside this window — a For You fallthrough is filtered the same way. |
| page | integer | No | Creative Center page (default 1). page>1 triggers chart mode. |
| limit | integer | No | Max items to return (default 20, max 200). Flat 2 credits per call. |
| cache | boolean | No | Set true to serve from the 24h response cache (0 credits on hit). Default false — always fetch fresh. |
Authentication: send your key as Authorization: Bearer capt_live_.... A typical call costs 2 credits. Pass cache=true for a free 24h cache hit; default is always fresh.
How it works
- 1. Sign up — get 100 free credits, no card required.
- 2. Create a key from your dashboard.
- 3. Send one request to
/v1/tiktok/trending-feedand parse the JSON response.
Use cases
Trend Discovery
Sample what's circulating in TikTok's trending feed for a region.
Content Research
Inspect captions, sounds, and engagement on trending posts.
Frequently asked questions
What does the TikTok Trending Feed API do?+
The TikTok Trending Feed API lets you list items in bulk with metadata from a public TikTok trending feed using one GET request to /v1/tiktok/trending-feed. It returns clean JSON — no OAuth or infrastructure setup required.
How many credits does the TikTok Trending Feed API cost?+
Each successful call costs 2 credits. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Failed or empty results are never charged.
Do I need a TikTok API key or OAuth?+
No. A single Captapi key works across every platform Captapi supports — YouTube, TikTok, Instagram, Facebook, Twitter/X, Reddit, Threads, Bluesky, Pinterest, LinkedIn, Rumble, Spotify, Kwai, and more. We handle proxies, rate limits, retries, and authentication for you.
Why was I billed when the browser timed out?+
The origin used to finish past Cloudflare's ~125s read timeout, log a 200, and debit 2 credits after the connection was already dead (385s and 430s rows in request history). The endpoint now has the same 110s deadline as popular-hashtags. A wall with a 6h last-good page is labelled stale 200 at 0 credits (stale=true, source=cache). A miss with no snapshot is 502 UPSTREAM_UNAVAILABLE, 0 credits, with timings.totalMs.
Does orderBy=vv sort by views?+
vv is accepted as an alias of hot (Creative Center's internal key) and the response echoes orderBy=hot. Unknown tokens are 400. On a Creative Center hit the chart is already sorted. On a For You fallthrough the list is re-sorted locally by that metric and the note says so — rank is not a raw array index of an unsorted feed.
Why is mediaType photo on a /video/ URL?+
It isn't anymore. mediaType used to track whether we extracted a playable videoUrl. Session-bound play URLs are deliberately omitted, so that labelled roughly half the feed as photo. mediaType is now photo only when the canonical url contains /photo/, or durationSeconds is null on an image post. A 126-second /video/ row with no videoUrl is a video.
Why is author.followers null?+
The signed mobile For You card often omits follower_count. We read author / authorStats / nested author.stats (including compact strings like 12.3K), then hydrate unique still-null handles from /api/user/detail (8s budget, not a second FYP page — those items never overlap). Null means the feed omitted the count and user/detail missed or timed out for that creator.
Can I page the For You feed?+
No. A filled page is hasMore true, nextCursor null, truncatedReason=single_page_only — more exist and are unreachable. hasMore is never true without a cursor unless that reason is set (same rule as truth-social/user-posts). A short page is hasMore false. Creative Center mode uses page + pagination.totalCount (truncatedReason=chart-page when the chart page filled).
Is the TikTok Trending Feed API suitable for production use?+
Yes. It is a stable REST endpoint with predictable JSON and automatic retries. Pass cache=true to serve from the 24h cache (0 credits on hit); default is always fresh. Selected profile endpoints also accept cacheMaxAge=1d|3d|7d|14d|30d. Use it for analytics, monitoring, and content automation.
More TikTok APIs
Ready to use the TikTok Trending Feed API?
Sign up, grab your key, and make your first call in 60 seconds.