# TikTok Sound Lookup: Metadata & Videos Using It (`vexaloom-labs/tiktok-sound-lookup-metadata-and-videos-using-it`) Actor

Look up any TikTok sound by URL or ID and get back its title, creator, duration, cover art, and streaming links, plus every video currently using that sound with captions, hashtags, and engagement counts.

- **URL**: https://apify.com/vexaloom-labs/tiktok-sound-lookup-metadata-and-videos-using-it.md
- **Developed by:** [vexaloom-labs](https://apify.com/vexaloom-labs) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## TikTok Sound Lookup: Metadata & Videos Using It

Give this actor a TikTok sound — by page URL, numeric ID, or a keyword search — and it returns the sound's own metadata and the videos using it. Sound rows carry title, creator and artist, duration, cover art, DSP/streaming IDs, licensing flags, tags and total video count. Video rows carry the author, caption, hashtags, mentions, location, effects, slideshow images and engagement counters. No TikTok login, cookies or API key needed.

### What this actor does

- **Two modes:** `bySound` resolves one or more sound URLs/IDs; `searchSounds` discovers sounds from one or more keywords.
- **Complete sound metadata:** title, author name, credited `artist`/`artists`, owner handle, language, release info, tags, licensing flags, covers and video count.
- **DSP and partner IDs:** `dspLinks` and `externalSongInfo` expose the IDs TikTok holds for Spotify, Apple Music and other partners, without inventing links.
- **Every video using the sound:** request up to 500 per sound, collected 30 at a time and deduplicated by video ID. TikTok can cap the public feed per run, so the actor returns what it can read and reports any shortfall.
- **Slideshow-aware:** photo posts are labelled `postType: "slideshow"` and include their `images` array.
- **Client-side filters:** publish window, minimum plays, minimum likes and one-video-per-creator, applied after collection.
- **Opt-in error rows:** turn on `includeErrorRows` when you want a machine-readable row for each failed input.
- Every empty field is omitted — no nulls or blank placeholders.

### Output per sound (`rowType: "music"`)

- `musicId`, `musicUrl` — sound ID and canonical TikTok page URL
- `musicTitle`, `authorName`, `album` — track identity
- `artist` — credited artist profile snapshot (id, secUid, username, displayName, bio, verified, avatarUrl)
- `artists` — every credited artist TikTok returns
- `ownerHandle`, `ownerNickname` — sound owner identity, when TikTok exposes one
- `duration`, `durationHighPrecision`, `shootDuration` — track length and allowed clip length
- `language`, `createTime`, `createdAt`, `musicReleaseInfo` — release and language metadata
- `isCopyrighted`, `isCommerceMusic`, `isUnlimitedMusic`, `isOriginal`, `isPrivate` — licensing and visibility flags
- `isPgc`, `isAuthorArtist`, `hasCommerceRight`, `commercialRightType` — commercial-use classification
- `playUrl`, `coverLarge`, `coverMedium`, `coverThumb` — signed audio and cover URLs
- `videoCount` — number of videos using the sound (kept as a string for very large counts)
- `dspLinks` — streaming-platform IDs, names and links derived from TikTok's partner data
- `externalSongInfo` — raw partner IDs (partnerName, partnerSongId, externalSongKey, links)
- `tagList`, `themeTags` — mood, genre and theme tags
- `matchedSongId`, `shareMeta` — matched licensed track ID and share text
- `searchKeyword`, `searchPosition` — lineage when the sound came from `searchSounds`
- `author` — creator profile snapshot for the sound
- `rowType: "music"`

### Output per video (`rowType: "post"`)

- `postId`, `postType`, `postUrl` — video identifier, `video` or `slideshow`, and link
- `matchedMusicId` — the sound this video was collected under
- `searchKeyword`, `searchPosition` — search lineage when applicable
- `caption`, `textLanguage`, `createTime`, `createdAt` — caption and publish time
- `locationCreated`, `poi` — country and point-of-interest tag, when present
- `stitchEnabled`, `shareEnabled`, `duetEnabled`, `isAd` — interaction and ad flags
- `playCount`, `likeCount`, `commentCount`, `shareCount`, `collectCount`, `repostCount` — engagement counters
- `hashtags` — `{name, id, isCommerce}` entries
- `mentions` — `{username, userId, secUid, userUniqueId, start, end}` entries from TikTok's mention metadata
- `author` — full author snapshot with bio, avatar and follower/heart/video counts
- `music` — the sound object embedded in the video (id, title, authorName, album, playUrl, coverUrl, dspLinks)
- `video` — width, height, duration, ratio, definition, bitrate, codec, format, size, quality and cover URLs
- `images` — slideshow image URLs with width/height for `postType: "slideshow"`
- `effectStickers` — effects used in the video
- `mediaUrlExpiresAt` — expiry timestamp for signed media URLs
- `rowType: "post"`

### Output per failed input (`rowType: "error"`, opt-in)

- `errorCode` — `invalid_music_input`, `sound_unavailable`, `no_search_results`, `feed_blocked` or `blocked`
- `errorMessage` — plain-language explanation
- `inputValue`, `musicId`, `searchKeyword` — which input failed

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `mode` | string | `bySound` | `bySound` / `searchSounds` |
| `musicUrls` | array | – | Sound page URLs (mode=bySound) |
| `musicIds` | array | – | Numeric sound IDs, 15–20 digits (mode=bySound) |
| `searchQueries` | array | – | Keywords to search (mode=searchSounds) |
| `maxSoundsPerQuery` | integer | `10` | Sounds kept per keyword, 1–30 |
| `maxPostsPerSound` | integer | `30` | Videos per sound, 0–500; `0` means metadata only |
| `includeMusicMetadata` | boolean | `true` | Emit sound metadata rows |
| `includePosts` | boolean | `true` | Emit video rows |
| `includeErrorRows` | boolean | `false` | Emit rows for failed inputs |
| `publishedWithin` | string | `all` | `all` / `day` / `week` / `month` / `year` (video rows) |
| `minPlayCount` | integer | `0` | Drop videos below this play count |
| `minLikeCount` | integer | `0` | Drop videos below this like count |
| `uniqueCreatorsOnly` | boolean | `false` | Keep the highest-play video per author |

#### Example: one sound by URL

```json
{
  "mode": "bySound",
  "musicUrls": ["https://www.tiktok.com/music/original-sound-7595604258835401494"],
  "maxPostsPerSound": 100
}
```

#### Example: several sounds by ID

```json
{
  "mode": "bySound",
  "musicIds": ["6799585653702019073", "7181527934435117058"],
  "maxPostsPerSound": 50,
  "includeErrorRows": true
}
```

#### Example: keyword discovery with filters

```json
{
  "mode": "searchSounds",
  "searchQueries": ["lofi", "phonk", "afrobeats"],
  "maxSoundsPerQuery": 10,
  "maxPostsPerSound": 30,
  "publishedWithin": "month",
  "minPlayCount": 10000,
  "uniqueCreatorsOnly": true
}
```

#### Example: metadata only

```json
{
  "mode": "bySound",
  "musicIds": ["6799585653702019073"],
  "includeMusicMetadata": true,
  "includePosts": false,
  "maxPostsPerSound": 0
}
```

### Use cases

- **A\&R and label teams** tracking how a track spreads and which creators are driving it
- **Brand and campaign teams** checking a sound's licensing flags, DSP IDs and audience before using it
- **Trend researchers** discovering sounds by keyword and pulling the videos that define each trend
- **Rights-management teams** auditing reuse of licensed or copyrighted tracks
- **Creator-discovery platforms** finding the highest-performing video per creator for a sound
- **Music catalogues** enriching tracks with TikTok's artist, release and streaming-partner identifiers

### FAQ

**Do I need a TikTok account or cookies?** No. The actor reads public sound and video data without a login, cookie or API key.

**Where do I find a sound's ID?** Open the sound page on TikTok; the URL ends in `/music/<name>-<digits>`. The trailing digits are the ID, and you can paste either the full URL or the number.

**What is the difference between `authorName` and `artist`?** `authorName` is the label TikTok shows for the sound. `artist` and `artists` are the credited performer profiles TikTok returns for licensed tracks. For user-recorded sounds the artist fields are usually absent.

**Why are `dspLinks` or `externalSongInfo` missing for some sounds?** Streaming-partner IDs only exist for licensed commercial tracks. Original user sounds do not have them, and the field is omitted rather than filled with a guess.

**How many sounds can one keyword return?** TikTok returns up to 30 sounds per query and does not paginate this catalogue, so `maxSoundsPerQuery` is capped at 30. Use several keywords to broaden coverage; duplicates are removed across queries.

**Why did I get fewer videos than the sound's video count?** The actor collects up to `maxPostsPerSound` (maximum 500) from the public feed. TikTok may return fewer items for very old, private or region-restricted posts, and it can cap anonymous feed pages per IP. When that happens the actor returns everything it could read and reports the shortfall in the run status. Large pulls are read 30 videos at a time and can take several minutes to finish.

**Why do some slideshow videos have no playback URL?** Photo posts use `images` instead of a video file; their `postType` is `slideshow` and the `video` object may only carry covers and dimensions.

**Are `playUrl`, covers and video URLs permanent?** No. TikTok signs media URLs with a short expiry. Treat them as temporary and download promptly if you need the media itself.

**Do the filters apply to sound rows too?** No. `publishedWithin`, `minPlayCount`, `minLikeCount` and `uniqueCreatorsOnly` apply to video rows after collection. Sound rows are always returned for the inputs you asked for.

**Is this affiliated with TikTok?** No. This is an independent actor that reads TikTok's public sound and video data; it is not endorsed by or affiliated with TikTok or ByteDance.

# Actor input Schema

## `mode` (type: `string`):

Choose how to find sounds: by sound URL/ID, or by keyword search.

## `musicUrls` (type: `array`):

(mode=bySound) TikTok sound page URLs. Example: https://www.tiktok.com/music/original-sound-7595604258835401494

## `musicIds` (type: `array`):

(mode=bySound) Numeric TikTok sound IDs, 15-20 digits, as an alternative to full URLs.

## `searchQueries` (type: `array`):

(mode=searchSounds) Keywords to search in TikTok's sound catalogue, e.g. lofi, phonk, afrobeats. Each query returns up to 30 sounds; duplicates are removed across queries.

## `maxSoundsPerQuery` (type: `integer`):

(mode=searchSounds) Keep at most this many sounds per keyword. TikTok returns a maximum of 30.

## `maxPostsPerSound` (type: `integer`):

Videos to collect per sound (0-500). Set 0 for sound metadata only. TikTok can cap the public feed per run, so fewer rows may be returned and the run status reports any shortfall.

## `includeMusicMetadata` (type: `boolean`):

Emit a metadata row per sound with title, creator/artist, duration, covers, DSP IDs, tags and video count.

## `includePosts` (type: `boolean`):

Emit one row per video that uses the sound, with author, caption, hashtags, mentions, POI, effects, slideshow images and engagement counts.

## `includeErrorRows` (type: `boolean`):

Emit a row with rowType='error' when an input cannot be read, instead of only logging it. Off by default.

## `publishedWithin` (type: `string`):

Keep only videos published inside this window. Applied after collection, to video rows.

## `minPlayCount` (type: `integer`):

Drop videos below this play count. 0 keeps everything. Videos without a play count are kept only when this is 0.

## `minLikeCount` (type: `integer`):

Drop videos below this like count. 0 keeps everything. Videos without a like count are kept only when this is 0.

## `uniqueCreatorsOnly` (type: `boolean`):

Keep only the highest-play video per author across the run. Useful for audience and creator discovery.

## Actor input object example

```json
{
  "mode": "bySound",
  "musicIds": [
    "7595604258835401494"
  ],
  "maxSoundsPerQuery": 10,
  "maxPostsPerSound": 5,
  "includeMusicMetadata": true,
  "includePosts": true,
  "includeErrorRows": false,
  "publishedWithin": "all",
  "minPlayCount": 0,
  "minLikeCount": 0,
  "uniqueCreatorsOnly": false
}
```

# Actor output Schema

## `data` (type: `string`):

Dataset containing sound metadata, videos using the sounds, and opt-in error rows. Use rowType to distinguish them.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "mode": "bySound",
    "musicIds": [
        "7595604258835401494"
    ],
    "maxPostsPerSound": 5,
    "includeMusicMetadata": true,
    "includePosts": true,
    "includeErrorRows": false,
    "publishedWithin": "all",
    "uniqueCreatorsOnly": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("vexaloom-labs/tiktok-sound-lookup-metadata-and-videos-using-it").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "mode": "bySound",
    "musicIds": ["7595604258835401494"],
    "maxPostsPerSound": 5,
    "includeMusicMetadata": True,
    "includePosts": True,
    "includeErrorRows": False,
    "publishedWithin": "all",
    "uniqueCreatorsOnly": False,
}

# Run the Actor and wait for it to finish
run = client.actor("vexaloom-labs/tiktok-sound-lookup-metadata-and-videos-using-it").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "mode": "bySound",
  "musicIds": [
    "7595604258835401494"
  ],
  "maxPostsPerSound": 5,
  "includeMusicMetadata": true,
  "includePosts": true,
  "includeErrorRows": false,
  "publishedWithin": "all",
  "uniqueCreatorsOnly": false
}' |
apify call vexaloom-labs/tiktok-sound-lookup-metadata-and-videos-using-it --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,vexaloom-labs/tiktok-sound-lookup-metadata-and-videos-using-it"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/IqJBdUeSYHgtHc7Lb/builds/LmWHGTW7L3zReLZ3O/openapi.json
