# TikTok Playlist Scraper (`maximedupre/tiktok-playlist`) Actor

Collect public TikTok playlist details and videos from playlist or collection IDs, playlist URLs, public account handles, or public profile URLs. Get playlist names, counts, creator details, video order, engagement, and available media links with collection times in a structured dataset.

- **URL**: https://apify.com/maximedupre/tiktok-playlist.md
- **Developed by:** [Maxime Dupré](https://apify.com/maximedupre) (community)
- **Categories:** Social media, Videos, Marketing
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.70 / 1,000 playlist videos

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
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?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

### 🎵 Turn TikTok playlists into structured data

For content researchers, creator teams, and developers, this Actor collects public TikTok playlist details and video rows. Review playlist names, counts, creator details, video order, engagement, available media links, and collection times in one dataset.

**Use cases**

- Find public playlists from a TikTok account with **[TikTok playlists by username](https://apify.com/maximedupre/tiktok-playlist/examples/tiktok-playlists-by-username)**.
- Check playlist names, counts, creators, and source links with **[TikTok playlist metadata](https://apify.com/maximedupre/tiktok-playlist/examples/tiktok-playlist-metadata)**.
- Collect videos and their playlist positions with **[TikTok playlist videos](https://apify.com/maximedupre/tiktok-playlist/examples/tiktok-playlist-videos)**.
- Build a structured playlist snapshot with **[TikTok playlist data](https://apify.com/maximedupre/tiktok-playlist/examples/tiktok-playlist-data)**.
- Extract public playlist details and videos with **[TikTok playlist scraper](https://apify.com/maximedupre/tiktok-playlist/examples/tiktok-playlist-scraper)**.

#### 📚 See playlist details and videos

Each run writes playlist rows, video rows, or both to the default dataset. Use `recordType` to tell the two row shapes apart. TikTok may leave optional fields out when the public source does not provide them.

#### ▶️ Run a TikTok playlist snapshot

**Run steps**

1. Choose whether to return playlist metadata, playlist videos, or both.
2. Choose `Playlist IDs or URLs` to read direct playlist targets, or choose `Profile handles or URLs` to find public playlists from accounts.
3. Add one or more values to the matching target list. The list for the other search method is ignored.
4. Set an optional limit for playlists found per account or videos returned per playlist. Leave `maxPlaylistsPerAccount` empty to return all available public playlists until the source is exhausted. Leave `maxVideosPerPlaylist` empty to return all available public videos until the source is exhausted.
5. Start the run and open the dataset link in the Output panel.

Availability can differ from one run to another. Private, deleted, or otherwise unavailable TikTok content is outside the product. The Actor reads public source data and does not need a TikTok login, cookies, or source credentials.

#### ⚙️ Input

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `resultType` | string | Chooses playlist metadata rows, playlist video rows, or both. |
| `discoveryMethod` | string | Chooses direct playlist IDs or URLs, or public account handles or profile URLs whose playlists should be found. |
| `playlistTargets` | array of strings | Adds one or more public playlist or collection IDs or playlist URLs. Use this list with `discoveryMethod: "playlistTargets"`. |
| `profileTargets` | array of strings | Adds one or more public TikTok account handles or profile URLs. Use this list with `discoveryMethod: "profileTargets"`. |
| `maxPlaylistsPerAccount` | integer | Optional cap for playlists found from each selected profile. Leave it empty to return all available public playlists until the source is exhausted. |
| `maxVideosPerPlaylist` | integer | Optional cap for videos returned from each selected playlist. It applies to Playlist videos and Playlist metadata and videos. Leave it empty to return all available public videos until the source is exhausted. |

**Result choices**

`resultType` accepts `playlistMetadata`, `playlistVideos`, or `playlistMetadataAndVideos`. `discoveryMethod` accepts `playlistTargets` or `profileTargets`. Use one discovery method per run.

**Example input**

This is the public input from a successful run with one playlist target:

```json
{
  "resultType": "playlistVideos",
  "discoveryMethod": "playlistTargets",
  "playlistTargets": [
    "7516638364301265695"
  ],
  "maxVideosPerPlaylist": 1
}
```

#### 🧾 Output

The Output panel provides a link to the default dataset. A run can contain playlist rows, video rows, or both. The tables below list every field in each public row shape. Required playlist and video page links are included, while optional source data appears when TikTok provides it.

**Run output field**

| Field | Type | What it does |
| --- | --- | --- |
| `datasetUrl` | string | Link to the default dataset that holds the rows returned by the run. |

**Playlist record fields**

| Field | Type | What it does |
| --- | --- | --- |
| `recordType` | string | Identifies this row as a `playlist` row. |
| `playlistId` | string | Stable TikTok ID of the playlist or collection. |
| `name` | string | Name shown for the playlist on TikTok. |
| `videoCount` | integer | Number of videos in the playlist reported by TikTok. |
| `coverImageUrl` | string | Source URL for the playlist cover image. |
| `playlistUrl` | string | Public TikTok URL for the playlist. |
| `creator` | object | TikTok account that owns the playlist. |
| `creator.id` | string | Stable TikTok ID of the playlist creator. |
| `creator.handle` | string | Public TikTok handle of the playlist creator. |
| `creator.displayName` | string | Display name of the playlist creator. |
| `creator.profileUrl` | string | Public TikTok profile URL of the playlist creator. |
| `creator.followersCount` | integer | Creator follower count reported by TikTok. |
| `creator.followingCount` | integer | Number of accounts followed by the creator. |
| `creator.likesCount` | integer | Creator likes reported by TikTok. |
| `creator.videoCount` | integer | Creator video count reported by TikTok. |
| `collectedAt` | string | Time when the playlist row was collected. |

**Example playlist row**

This complete row came from a successful metadata run:

```json
{
  "recordType": "playlist",
  "playlistId": "7516638364301265695",
  "name": "In The Mix",
  "videoCount": 24,
  "coverImageUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oMr6rAA6QCIh5zBgE2FEAqDfIoAjTeAQIifXqO~tplv-tiktokx-origin.image?dr=9636&x-expires=1788062400&x-signature=oxdTe4Q1oeR9n48yb0dSLbeY06Q%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
  "playlistUrl": "https://www.tiktok.com/@tiktok/playlist/In-The-Mix-7516638364301265695",
  "creator": {
    "id": "107955",
    "handle": "tiktok",
    "profileUrl": "https://www.tiktok.com/@tiktok",
    "displayName": "TikTok",
    "followersCount": 95400000,
    "followingCount": 2,
    "likesCount": 463000000,
    "videoCount": 1497
  },
  "collectedAt": "2026-08-29T22:53:26.032Z"
}
```

**Playlist video record fields**

| Field | Type | What it does |
| --- | --- | --- |
| `recordType` | string | Identifies this row as a `video` row. |
| `playlistId` | string | Stable TikTok ID of the playlist that contains the video. |
| `playlistUrl` | string | Public TikTok URL for the playlist that contains the video. |
| `playlistName` | string | Name of the playlist that contains the video. |
| `position` | integer | Position of the video in the playlist as provided by TikTok. |
| `videoId` | string | Stable TikTok ID of the video. |
| `videoUrl` | string | Public TikTok page URL for the video. |
| `caption` | string | Caption published with the video. |
| `publishedAt` | string | Time when the video was published on TikTok. |
| `engagement` | object | Engagement counts reported by TikTok for the video. |
| `engagement.views` | integer | Video views reported by TikTok. |
| `engagement.likes` | integer | Video likes reported by TikTok. |
| `engagement.comments` | integer | Video comments reported by TikTok. |
| `engagement.shares` | integer | Video shares reported by TikTok. |
| `engagement.saves` | integer | Video saves reported by TikTok. |
| `creator` | object | TikTok account that published the video. |
| `creator.id` | string | Stable TikTok ID of the video creator. |
| `creator.handle` | string | Public TikTok handle of the video creator. |
| `creator.displayName` | string | Display name of the video creator. |
| `creator.profileUrl` | string | Public TikTok profile URL of the video creator. |
| `creator.followersCount` | integer | Creator follower count reported by TikTok. |
| `creator.followingCount` | integer | Number of accounts followed by the creator. |
| `creator.likesCount` | integer | Creator likes reported by TikTok. |
| `creator.videoCount` | integer | Creator video count reported by TikTok. |
| `music` | object | Sound details when TikTok provides them. |
| `music.id` | string | Stable TikTok ID of the sound. |
| `music.title` | string | Sound title on TikTok. |
| `music.authorName` | string | Sound author name on TikTok. |
| `music.url` | string | Public TikTok URL for the sound. |
| `media` | object | Video file details and source links when TikTok provides them. |
| `media.durationSeconds` | number | Video duration in seconds. |
| `media.width` | integer | Video width in pixels. |
| `media.height` | integer | Video height in pixels. |
| `media.quality` | string | Media quality label supplied by TikTok. |
| `media.coverImageUrl` | string | Source URL for the video's cover image. |
| `media.downloadUrl` | string | Direct source URL for the video file. It may expire. |
| `captionLanguage` | string | Language code supplied for the video caption. |
| `hashtags` | array of strings | Hashtags found in the video caption. |
| `mentions` | array of strings | TikTok handles mentioned in the video caption. |
| `images` | array of objects | Images in a video slideshow when TikTok provides them. |
| `images[].url` | string | Source URL for a slideshow image. |
| `images[].width` | integer | Slideshow image width in pixels. |
| `images[].height` | integer | Slideshow image height in pixels. |
| `collectedAt` | string | Time when the video row was collected. |

**Example playlist video row**

This unshortened row came from a successful video run. The signed media links are source links and may expire:

```json
{
  "recordType": "video",
  "playlistId": "7585292371022088990",
  "playlistUrl": "https://www.tiktok.com/@tiktok/playlist/TikTok-Awards-7585292371022088990",
  "playlistName": "TikTok Awards",
  "position": 1,
  "videoId": "7584645463475932447",
  "videoUrl": "https://www.tiktok.com/@tiktok/video/7584645463475932447",
  "collectedAt": "2026-08-29T22:55:18.047Z",
  "caption": "So excited to perform at the first-ever U.S. TikTok Awards in LA on Dec 18. Catch it live on TikTok + Tubi. 💃🏽🫶🏽",
  "publishedAt": "2025-12-17T02:18:15.000Z",
  "engagement": {
    "views": 573300,
    "likes": 12200,
    "comments": 1443,
    "shares": 923,
    "saves": 1274
  },
  "creator": {
    "id": "107955",
    "handle": "tiktok",
    "profileUrl": "https://www.tiktok.com/@tiktok",
    "displayName": "TikTok",
    "followersCount": 95400000,
    "followingCount": 2,
    "likesCount": 463000000,
    "videoCount": 1497
  },
  "music": {
    "id": "7584645384653589278",
    "url": "https://www.tiktok.com/music/sound-7584645384653589278",
    "title": "original sound",
    "authorName": "TikTok"
  },
  "media": {
    "durationSeconds": 31,
    "width": 720,
    "height": 1280,
    "quality": "720p",
    "coverImageUrl": "https://p16-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oUF6EpABfACCAYDlEu3CLWIADFRVhQZA2VEEEe~tplv-tiktokx-origin.image?dr=9636&x-expires=1788213600&x-signature=XaVN1kfv4B1TxS727rNpdBeyvMY%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast8",
    "downloadUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast8/tos-useast8-ve-0068c001-tx2/o44lLfGtR9YCxCGgYEurbIdvQeEdEAFhEfQUeA/?a=1988&bti=ODszNWYuMDE6&&bt=1149&ft=4KJMyMzm8Zmo0h77ca4jVN_OQpWrKsd.&mime_type=video_mp4&rc=NTo4PGgzMzc6Njk5NGgzOUBpM3lydnQ5cmc0ODMzaTczNEBfLS01LTQyXjIxYF4tNDIuYSNzc3EwMmRrMi5hLS1kMTJzcw%3D%3D&expire=1788216948&l=202608292255178AF1644E149453488856&ply_type=2&policy=2&signature=5ca323f11c18540a225913c55ee8e269&tk=tt_chain_token&btag=e00090000"
  },
  "captionLanguage": "en"
}
```

#### 💳 Pricing

The Actor uses pay-per-event pricing. The Store page shows the price for each event and buyer tier.

| Event | When it is charged |
| --- | --- |
| Playlist Details | One public playlist's details are saved. |
| Playlist Video | One public video from a selected playlist is saved. |

#### 🔌 Integrations

**Dataset access**

Open the dataset link in the Output panel to review the saved rows or use them in your workflow. Use `playlistUrl` and `videoUrl` to trace rows back to public TikTok pages. Signed media links may expire, so use them soon after the run.

**Video guide**

https://www.youtube.com/watch?v=bNACk1\_S\_6w\&list=PLObrtcm1Kw6MUrlLNDbK9QRg8VDJg0gOW\&index=4

#### ❓ FAQ

##### Do signed media links expire?

Yes. Source download and cover links can expire. Use `playlistUrl` and `videoUrl` as links to the public TikTok pages.

##### What does `position` mean?

It is the video's position in the playlist as provided by TikTok.

##### What if TikTok does not provide a field?

Optional fields can be absent when TikTok does not show that value. The Actor does not invent missing public-source data.

##### What happens when a playlist has no accessible public videos?

Only accessible public videos can produce video rows. Private, deleted, or unavailable videos are outside the product, and optional values stay absent when TikTok does not provide them.

##### Can I submit more than one playlist target?

Yes. Add multiple playlist IDs or URLs to `playlistTargets`, with one value for each playlist.

##### Can I submit more than one profile target?

Yes. Add multiple public account handles or profile URLs to `profileTargets`, with one value for each account.

##### Can I combine playlist targets and profile targets in one run?

No. Choose one discovery method per run. The fields for the other method are ignored. Use a separate run when you need the other target type.

##### Which result type should I choose?

Choose `playlistMetadata` for playlist names, counts, links, and creator details. Choose `playlistVideos` for video rows and their playlist positions. Choose `playlistMetadataAndVideos` for both shapes in one run.

##### Do I need a TikTok login or cookies?

No. The Actor reads public TikTok data without a TikTok login, cookies, or source credentials.

##### Do the limits have a fixed maximum?

The input schema does not set an upper bound for either limit. Leave `maxPlaylistsPerAccount` empty to return all available public playlists until the source is exhausted. Leave `maxVideosPerPlaylist` empty to return all available public videos until the source is exhausted.

### 📝 Changelog

**0.0: Initial release**

### 🆘 Support

For issues, questions, or feature requests, [file a ticket](https://console.apify.com/actors/maximedupre~tiktok-playlist/issues) and I'll fix or implement it in less than 24h 🫡

### 🔗 Related Actors

- [TikTok Search Scraper](https://apify.com/maximedupre/tiktok-search-results-scraper) finds public TikTok videos or creators by keyword.
- [TikTok Creator Analytics Scraper](https://apify.com/maximedupre/tiktok-creator-analytics) reviews public profile and audience metrics for creators found in a playlist.
- [TikTok Video Downloader](https://apify.com/maximedupre/tiktok-video-downloader) downloads media from the public video URLs in playlist rows.
- [TikTok Transcript Scraper](https://apify.com/maximedupre/tiktok-transcript-scraper) extracts public captions and transcripts from video URLs in playlist rows.
- [TikTok Audio Downloader](https://apify.com/maximedupre/tiktok-audio-downloader) saves audio from playlist video URLs when TikTok exposes an audio track.

**Made with ❤️ by Maxime Dupré**

# Actor input Schema

## `resultType` (type: `string`):

Choose playlist metadata rows, playlist video rows, or both.

## `discoveryMethod` (type: `string`):

Choose direct playlist IDs or URLs, or public TikTok account handles or profile URLs whose playlists you want to find.

## `playlistTargets` (type: `array`):

Enter one or more public TikTok playlist or collection IDs or playlist URLs. Add one value for each playlist.

## `profileTargets` (type: `array`):

Enter one or more public TikTok account handles or profile URLs. The Actor finds public playlists from each account.

## `maxPlaylistsPerAccount` (type: `integer`):

Optional cap for playlists found from each selected profile. Leave it empty to get all available public playlists until the source is exhausted.

## `maxVideosPerPlaylist` (type: `integer`):

Optional cap for videos returned from each selected playlist. It applies when the result type is Playlist videos or Playlist metadata and videos. Leave it empty to get all available public videos until the source is exhausted.

## Actor input object example

```json
{
  "resultType": "playlistVideos",
  "discoveryMethod": "playlistTargets",
  "playlistTargets": [
    "7516638364301265695"
  ],
  "maxVideosPerPlaylist": 1
}
```

# Actor output Schema

## `datasetUrl` (type: `string`):

Open the result rows in the default dataset.

# 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 = {
    "resultType": "playlistVideos",
    "discoveryMethod": "playlistTargets",
    "playlistTargets": [
        "7516638364301265695"
    ],
    "maxVideosPerPlaylist": 1
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/tiktok-playlist").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 = {
    "resultType": "playlistVideos",
    "discoveryMethod": "playlistTargets",
    "playlistTargets": ["7516638364301265695"],
    "maxVideosPerPlaylist": 1,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/tiktok-playlist").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 '{
  "resultType": "playlistVideos",
  "discoveryMethod": "playlistTargets",
  "playlistTargets": [
    "7516638364301265695"
  ],
  "maxVideosPerPlaylist": 1
}' |
apify call maximedupre/tiktok-playlist --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maximedupre/tiktok-playlist"
        }
    }
}

```

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/qcqJPyxn936hNtAAp/builds/kcJcFkKaN3yCsoc1b/openapi.json
