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. Native and extended paths emit one row schema: permalink is always url (a watch URL never stays in videoUrl), author is the full eight-key card (nulls when unknown — never a four-key shell), and caption / publishedAt / thumbnailUrl / durationSeconds / mediaUrlsExpireAt / hasWatermark / locationCreated are always keyed. Unread engagement counters are null with *IsApproximate: null — never 0 flagged exact. hasMore is true only when nextCursor is present. Deadline is 110s: timeout is 502 UPSTREAM_UNAVAILABLE at 0 credits (never a billed 200 past Cloudflare). Flat 2 credits per call.
What you get
- One row schema on native and extended — url + videoUrl do not swap by path
- Unread likes/saves are null, not exact zero
- hasMore true only when nextCursor is present
- 110s deadline → 502 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
}
}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).totalReturnedNumber of items returned in this response.nextCursorPass back as cursor for the next page of videos using this sound. Null when the page cannot continue.hasMoreTrue only when nextCursor is present. Extended pages have no cursor, so hasMore is false — 69 rows is not a promise of a next page.sourcenative | extended | cache — never a vendor name.
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.
Stages
The stages object contains:
kindKind. Example: "cascade".nativeStatusNative status. Example: "ok".apifyStatusApify status. Example: "skipped".
Timings
The timings object contains:
pathPath. Example: "native".nativeMsNative ms. Example: 14029.apifyMsApify ms. Example: 0.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 | Max items to return (default 20, max 200). 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 proxies, 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.
Why did url and author keys change between two identical calls?+
Native (~14s) and extended (~160s) used to emit different objects — videoUrl vs url, a four-key null author vs a full card. Both paths now share one schema.
hasMore is null / I cannot page. Is 69 everything?+
hasMore is a boolean and is true only when nextCursor is present. Extended pages do not cursor, so hasMore is false — raise limit on a fresh call or wait for native. Do not treat totalReturned as a page size.
Why did a 160s call cost 2 credits when my browser already hung?+
The origin used to finish past Cloudflare's ~125s read timeout, log a 200, and debit 2 credits — the same PH-1 class as instagram/comments. The route is hard-capped at 110s: timeout is 502 UPSTREAM_UNAVAILABLE at 0 credits. Native usually answers in ~14s.
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.