TikTok Music Posts API
List TikTok videos that use a specific sound — caption, author, exact engagement, canonical hashtags, and mentions, with cursor pagination.
GET request to /v1/tiktok/music-posts 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 Music Posts API?
Paste a TikTok music/sound URL and get the public videos that use that sound as structured JSON, straight from TikTok's own music feed (native only — there is no backup path). TikTok serves this feed in short pages of a few videos each, so a call returns what lands within ~35s plus a nextCursor; keep paging to collect more. pagination says where you stand: cursor (more pages — hasMore true), end (TikTok's feed for this sound is exhausted — hasMore false), unavailable (cannot tell — hasMore null, never a false "no more posts"). Coverage is limited to what TikTok's public feed exposes, which can be far below the count shown in the app. Every row has one schema: permalink is always url, author is the full eight-key card, and caption / publishedAt / thumbnailUrl / durationSeconds / mediaUrlsExpireAt / hasWatermark / locationCreated are always keyed. Unread engagement counters are null with *IsApproximate: null — never 0 flagged exact. limit is 1–50 (outside that is a 400). When TikTok's feed refuses us, the answer is 503 UPSTREAM_UNAVAILABLE with Retry-After and the real elapsed time (reason native_unavailable, page_miss or timeout) at 0 credits. Photomode covers are mediaType=photo with a /photo/ permalink. Flat 2 credits per successful call.
What you get
- Native TikTok music feed with a working nextCursor
- pagination: cursor | end | unavailable; hasMore true / false / null to match
- Unread likes/saves are null, not exact zero
- limit 1–50; above is a clear 400
- Feed refusal or timeout → 503 with Retry-After at 0 credits
- 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/music-posts?url=https%3A%2F%2Fwww.tiktok.com%2Fmusic%2Foriginal-sound-7646812079113898783" \
-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": {
"url": "https://www.tiktok.com/music/original-sound-7646812079113898783",
"musicId": "7646812079113898783",
"musicName": "original sound - khaby.lame",
"totalReturned": 2,
"posts": [
{
"platform": "tiktok",
"url": "https://www.tiktok.com/@khaby.lame/video/7646812028874673439",
"id": "7646812028874673439",
"caption": "Thank you, please come again!!!🙋🏿♂️💸#learnfromkhaby #comedy",
"publishedAt": "2026-06-02T14:56:35.000Z",
"durationSeconds": 29.534,
"thumbnailUrl": "https://p16-common-sign.tiktokcdn.com/tos-useast8-p-0068-tx2/oUAHVIiQDac8uC75AEfyALAA1FrTAqEEQ3GRPe~tplv-tiktokx-cropcenter-q:300:400:q70.webp?dr=14782&refresh_token=dae473d0&x-expires=1785171600&x-signature=fF8KccMCj5i1KJP7krB7JRx2xG0%3D&t=bacd0480&ps=933b5bde&shp=d05b14bd&shcp=f6441914&idc=my2&biz_tag=tt_video&s=MUSIC_AWEME&sc=cover",
"mediaType": "video",
"width": 576,
"height": 1024,
"videoUrl": "https://v16-webapp-prime.tiktok.com/video/tos/useast8/tos-useast8-ve-0068c004-tx2/osABAiDgQEbQItAyAFeBfiAXnEBQDEfKGQIgSE/?a=1988&expire=1785171600",
"downloadUrl": "https://v16-webapp-prime.tiktok.com/video/tos/useast8/tos-useast8-ve-0068c004-tx2/osABAiDgQEbQItAyAFeBfiAXnEBQDEfKGQIgSE/?a=1988&expire=1785171600",
"downloadUrlNoWatermark": null,
"hasWatermark": true,
"mediaUrlsExpireAt": "2026-07-27T17:00:00.000Z",
"author": {
"id": "127905465618821121",
"secUid": "MS4wLjABAAAAwAg0rOj4qHjHBN4BQLRlTaNI0dpqRuTrNi-TM0LKNpc",
"username": "khaby.lame",
"displayName": "Khabane lame",
"url": "https://www.tiktok.com/@khaby.lame",
"followers": null,
"verified": true,
"profileImage": "https://p16-common-sign.tiktokcdn.com/tos-maliva-avt-0068/08987e23b94057953fd4f1738694bf5f~tplv-tiktokx-cropcenter-q:1080:1080:q70.webp?dr=10796&idc=my2&ps=87d6e48a&refresh_token=bc21b726&s=MUSIC_AWEME&sc=avatar&shcp=f6441914&shp=d05b14bd&t=223449c4&x-expires=1785171600&x-signature=D%2FanX%2BEAwPGclXui5sL48ejAGUk%3D",
"region": "IT"
},
"engagement": {
"views": 17042375,
"likes": 1550817,
"comments": 16306,
"shares": 16050,
"saves": 62013,
"viewsIsApproximate": false,
"likesIsApproximate": false,
"commentsIsApproximate": false,
"sharesIsApproximate": false,
"savesIsApproximate": false,
"downloads": 7108
},
"hashtags": [
"learnfromkhaby",
"comedy"
],
"mentions": [],
"musicAuthor": "Khabane lame",
"locationCreated": "IT",
"descLanguage": null,
"isAd": false,
"isPaidPartnership": false
},
{
"platform": "tiktok",
"url": "https://www.tiktok.com/@babi_batox/video/7657210703262010631",
"id": "7657210703262010631",
"caption": "Obrigado, volte sempre; THank you, come again #aprender #khaby #comed #badi_xatox #humor",
"publishedAt": "2026-06-30T15:28:22.000Z",
"durationSeconds": 16.467,
"thumbnailUrl": "https://p16-common-sign.tiktokcdn.com/tos-alisg-p-0037/oYw7iFBEEQ6IgRQz9Hf7QL2ARZkHqDcQBBfSBw~tplv-tiktokx-cropcenter-q:300:400:q70.webp?dr=14782&refresh_token=5cbaa5e5&x-expires=1785171600&x-signature=Zg1zQ4AppOFWvrVz6mtVoWf0Bbk%3D&t=bacd0480&ps=933b5bde&shp=d05b14bd&shcp=f6441914&idc=my2&biz_tag=tt_video&s=MUSIC_AWEME&sc=cover",
"mediaType": "video",
"width": 576,
"height": 1024,
"videoUrl": "https://v16-webapp-prime.tiktok.com/video/tos/alisg/tos-alisg-ve-0037/o4ABCDfQEBgIiAfQnEAXyBQDtAyAeGQIgKE/?a=1988&expire=1785171600",
"downloadUrl": "https://v16-webapp-prime.tiktok.com/video/tos/alisg/tos-alisg-ve-0037/o4ABCDfQEBgIiAfQnEAXyBQDtAyAeGQIgKE/?a=1988&expire=1785171600",
"downloadUrlNoWatermark": null,
"hasWatermark": true,
"mediaUrlsExpireAt": "2026-07-27T17:00:00.000Z",
"author": {
"id": null,
"secUid": null,
"username": "babi_batox",
"displayName": "Loreno_Cavela",
"url": "https://www.tiktok.com/@babi_batox",
"followers": null,
"verified": false,
"profileImage": "https://p16-common-sign.tiktokcdn.com/tos-alisg-avt-0068/12b7a3027b147743a04d2dcd50302b61~tplv-tiktokx-cropcenter-q:1080:1080:q70.webp?dr=10796&idc=my2&ps=87d6e48a&refresh_token=06f16ad2&s=MUSIC_AWEME&sc=avatar&shcp=f6441914&shp=d05b14bd&t=223449c4&x-expires=1785171600&x-signature=QOi7%2FEEgi7Th2wcfyTFLX0QLv%2B4%3D",
"region": "BR"
},
"engagement": {
"views": 2334,
"likes": 127,
"comments": 2,
"shares": 0,
"saves": 6,
"viewsIsApproximate": false,
"likesIsApproximate": false,
"commentsIsApproximate": false,
"sharesIsApproximate": false,
"savesIsApproximate": false
},
"hashtags": [
"aprender",
"khaby"
],
"mentions": [],
"musicAuthor": "Khabane lame",
"locationCreated": "BR",
"descLanguage": "pt",
"isAd": false,
"isPaidPartnership": false
}
],
"nextCursor": "20",
"hasMore": true,
"pagination": "cursor"
}
}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
urlCanonical watch permalink. Always this key — never videoUrl for a /@user/video/ id link.musicIdEnvelope-level sound id (single-valued across the page — not repeated per row).musicNameEnvelope-level sound title (single-valued across the page — not repeated per row).totalReturnedRows on this page. Can be below limit: TikTok serves this feed a few videos per page, and a call returns what lands within ~35s.nextCursorPass back as cursor for the next page of videos using this sound. Present only when pagination is cursor.hasMoretrue when pagination is cursor, false when it is end, null when it is unavailable. Breaking change (Oct 2026): was always a boolean, and false used to also mean "cannot page".pagination"cursor" — more pages, pass nextCursor. "end" — TikTok's public feed for this sound is exhausted. "unavailable" — the page cannot tell whether more exist (hasMore null). Always keyed.source"native" on a live call to TikTok's music feed, "cache" when cache=true served a stored page. There is no other path on this endpoint.
Posts
Each item in posts contains:
platformPlatform identifier for this response (matches the endpoint's platform).urlCanonical watch permalink. Always this key — never videoUrl for a /@user/video/ id link.idId of this posts item.captionPost or creative caption when the platform exposes one.publishedAtPublish date (ISO 8601) when the platform exposes an absolute timestamp.durationSecondsLength in seconds for this item (full media length, or a segment span when the endpoint documents a start/end).thumbnailUrlThumbnail image URL.mediaTypeMedia type label for this item (platform-specific enum).widthWidth in pixels.heightHeight in pixels.videoUrlPlayable CDN URL when TikTok exposes one. A watch permalink is moved to url, not left here.downloadUrlCDN media URL when present (not a dedicated download API).downloadUrlNoWatermarkDownload url no watermark.hasWatermarkHas watermark. Example: true.mediaUrlsExpireAtISO-8601 UTC earliest expiry across signed media URLs in this response (expire= / x-expires / TikTok hex path timestamp). Null when no stamp is parseable — never a guess.authorAuthor name or handle.engagementEngagement metrics for the item.hashtagsHashtags extracted from the text.mentionsAccounts mentioned in the text.musicAuthorMusic author. Example: "Khabane lame".locationCreatedISO country where the TikTok video was posted/served (item locationCreated). Not the creator's home country — use authorRegion or /tiktok/profile-region for that.descLanguageLanguage code TikTok assigns to the video caption when exposed.isAdWhether the item is a paid promotion.isPaidPartnershipIs paid partnership. Example: false.
Timings
The timings object contains:
pathPath. Example: "native".nativeMsNative ms. Example: 14029.totalMsTotal ms. Example: 14029.
Parameters
| Name | Type | Required | Description |
|---|---|---|---|
| url | string | Yes | TikTok music/sound URL, e.g. https://tiktok.com/music/name-ID. The URL platform must match this endpoint's platform. Do not pass cross-platform URLs, e.g. YouTube to TikTok, Instagram to Facebook, LinkedIn to X/Twitter, or Pinterest to Rumble. |
| limit | integer | No | Most videos to return (default 20, 1–50; outside that range is a 400). TikTok serves this feed in short pages, so a call can return fewer than limit with a nextCursor to continue. Flat 2 credits per call. |
| cursor | string | No | Pagination cursor. Leave empty for the first page; then pass the nextCursor value returned in the previous response. hasMore is true only when nextCursor is present. |
| 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/music-postsand parse the JSON response.
Use cases
Sound Tracking
List public videos that use a specific TikTok sound.
Trend Monitoring
Watch new posts appear on a sound over time.
Content Sourcing
Pull examples of a sound for research or UGC.
Frequently asked questions
What does the TikTok Music Posts API do?+
The TikTok Music Posts API lets you list items in bulk with metadata from a public TikTok sound or track using one GET request to /v1/tiktok/music-posts. It returns clean JSON — no OAuth or infrastructure setup required.
How many credits does the TikTok Music Posts 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 access, rate limits, retries, and authentication for you.
Why were likes and saves 0 on a 2-million-view video?+
That was an unread counter coerced to 0 and flagged exact. Missing likes/saves are now null with *IsApproximate: null. A real zero (the path sent 0) still reads 0 / false. Do not rank by engagement when the flag is null.
I asked for 20 videos and got 6. Is that everything?+
No — check pagination. TikTok serves this feed a few videos per page, so a call returns what lands within ~35s. pagination: "cursor" means pass nextCursor for more; "end" means TikTok's public feed for this sound is exhausted. That feed can stop far below the count the app shows, so a sound with thousands of uses may only expose a few hundred.
Why is hasMore null?+
hasMore is true with pagination "cursor", false with "end", and null with "unavailable" — when we cannot tell, we say so rather than claim there are no more posts. Before October 2026 hasMore was always a boolean and false could also mean "this page cannot be continued".
I got a 503. Was I charged?+
No. A 503 UPSTREAM_UNAVAILABLE (reason native_unavailable, page_miss or timeout) is 0 credits and the message states how long we actually waited. It is not a bad sound URL: retry after the Retry-After seconds, and for page_miss retry the same nextCursor.
Is the TikTok Music Posts 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 Music Posts API?
Sign up, grab your key, and make your first call in 60 seconds.