# TikTok Profile Videos API Scraper (`maximedupre/tiktok-profile-videos-api`) Actor

Collect public TikTok profile videos from usernames, profile URLs, or numeric user IDs. Get one deduplicated row per upload with captions, engagement counts, creator details, sounds, hashtags, media links, and optional playlist or repost context when TikTok shows them.

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

## Pricing

from $0.25 / 1,000 profile 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

### 🎬 TikTok profile videos in structured rows

For developers, data teams, social media analysts, and researchers, this Actor reads known public TikTok creator usernames, profile URLs, or numeric user IDs. It returns one deduplicated dataset row for each eligible public upload, with fields for the requested profile, video identity, captions, timing, engagement counts, creator and sound details, hashtags, media links, and optional playlist, repost, and related-creator context. Use these rows to compare creator posts, review public engagement, or feed a TikTok profile videos API workflow.

**Use cases**

- Pull public post details with [**Tiktok Profile Video Metadata**](https://apify.com/maximedupre/tiktok-profile-videos-api/examples/tiktok-profile-video-metadata).
- Review a creator's public reposts with [**Tiktok Reposted Videos**](https://apify.com/maximedupre/tiktok-profile-videos-api/examples/tiktok-reposted-videos).
- List a known username's public uploads with [**Tiktok Videos By Username**](https://apify.com/maximedupre/tiktok-profile-videos-api/examples/tiktok-videos-by-username).
- Gather public uploads for a creator with [**Tiktok User Videos**](https://apify.com/maximedupre/tiktok-profile-videos-api/examples/tiktok-user-videos).
- Read a public profile's video feed as structured rows with [**Tiktok Profile Videos**](https://apify.com/maximedupre/tiktok-profile-videos-api/examples/tiktok-profile-videos).

#### 📦 Public TikTok upload rows

Each row records the first eligible occurrence of one public upload found for a requested profile or supported profile surface. If the same source upload appears again through another submitted username, URL, user ID, or supported surface, the later match is ignored. The saved row keeps the first requested-profile attribution. Missing source values are `null`, and empty arrays stay empty. Video rows can include direct public media links. Photo carousels use `media.photoUrls` and do not get a made-up video link. TikTok-signed media links may expire.

#### ▶️ Collect a creator's public profile videos

Use one known creator target or a large list. The same options apply to every target in the run.

**Run steps**

1. Add public creator usernames, profile URLs, or numeric user IDs to **Creator profiles**.
2. Turn on playlist, repost, or related-creator options when you need those public details.
3. Choose **Newest first** or **Oldest first**, and set an optional upload limit.
4. Start the run and open the default dataset link in the Output panel.

Use a smaller `maxItems` to shorten the run and reduce the number of rows you review. Leave `maxItems` empty to return all available results until the source is exhausted. Only public TikTok surfaces are in scope. Private, follower-only, deleted, or login-gated profiles and content can return no rows. The Actor does not need a TikTok login, OAuth, or source credentials. Public data is fetched at run time, so source availability can change.

#### ⚙️ Input

Add at least one value to `creatorTargets`. Usernames, profile URLs, and numeric user IDs can be mixed in one run. Numeric IDs should be entered as strings.

**Input fields**

| Field | Type | What it does |
| --- | --- | --- |
| `creatorTargets` | array of strings | Required. Adds one or more known public TikTok creator usernames, profile URLs, or numeric user IDs. |
| `includePlaylists` | boolean | Includes public uploads found in the target creator's playlists or mixes, with playlist details when available. |
| `checkPlaylistMembership` | boolean | Checks ordinary profile-feed videos for public playlist or mix membership. It does not collect playlist-only videos. |
| `playlistNameFilter` | string | Limits collected playlists or mixes to names that match this text when `includePlaylists` is on. Leave it blank or omit it to include all public playlists and mixes. |
| `includeReposts` | boolean | Includes public videos reposted by the target creator and adds the original video and creator when TikTok exposes them. |
| `onlyAmplified` | boolean | Keeps only uploads that repost or mention another creator. This filter does not turn on repost collection. |
| `enrichRelatedCreators` | boolean | Requests extra public profile details for creators found in reposts or caption mentions, including audience counts, content counts, bio information, links, and business-account status. |
| `maxItems` | integer | Optional positive limit for uploads from each requested profile. Leave it empty to return all available results until the source is exhausted. |
| `sortOrder` | string | Chooses the order of uploads within each profile: `newest` or `oldest`. |

**Example input**

This is the public input from a successful beta default-input run:

```json
{
  "creatorTargets": [
    "@tiktok"
  ],
  "includePlaylists": false,
  "checkPlaylistMembership": false,
  "includeReposts": false,
  "onlyAmplified": false,
  "enrichRelatedCreators": false,
  "maxItems": 10,
  "sortOrder": "newest"
}
```

#### 🧾 Output

The Output panel provides a link to the default dataset. One stable row shape covers video and photo-carousel uploads. Optional values can be `null`, and optional lists can be empty when TikTok does not expose matching public data.

**Dataset link**

| Field | Type | What it does |
| --- | --- | --- |
| `datasetItems` | string | Opens the collected rows in the default dataset. |

**Video and photo row fields**

| Field | Type | What it does |
| --- | --- | --- |
| `requestedProfile` | string | Username, profile URL, or numeric user ID that first led to this upload. |
| `videoId` | string | Stable TikTok ID for the upload. |
| `videoUrl` | string | Canonical public TikTok page for the upload. |
| `caption` | string or null | Public caption text, or `null` when TikTok does not show one. |
| `publishedAt` | string or null | Public publication time in ISO 8601 format, or `null` when unavailable. |
| `durationSeconds` | number or null | Upload length in seconds, or `null` for photo carousels or unavailable data. |
| `mediaType` | string | `video` or `photoCarousel`. |
| `playCount` | integer or null | Public play count, or `null` when TikTok does not show it. |
| `likeCount` | integer or null | Public like count, or `null` when TikTok does not show it. |
| `commentCount` | integer or null | Public comment count, or `null` when TikTok does not show it. |
| `shareCount` | integer or null | Public share count, or `null` when TikTok does not show it. |
| `saveCount` | integer or null | Public save count, or `null` when TikTok does not show it. |
| `creator` | object or null | Public profile details for the creator of the upload, or `null` when unavailable. |
| `creator.username` | string | Creator username without the leading `@`. |
| `creator.displayName` | string or null | Creator display name, or `null` when unavailable. |
| `creator.followerCount` | integer or null | Public follower count, or `null` when TikTok does not show it. |
| `creator.profileUrl` | string or null | Public TikTok profile URL, or `null` when unavailable. |
| `creator.isVerified` | boolean or null | Whether TikTok marks the creator as verified, or `null` when unavailable. |
| `sound` | object or null | Public sound details used by the upload, or `null` when no sound is shown. |
| `sound.soundId` | string or null | Stable TikTok sound ID, or `null` when unavailable. |
| `sound.title` | string or null | Public sound title, or `null` when unavailable. |
| `sound.author` | string or null | Public sound author name, or `null` when unavailable. |
| `sound.isOriginal` | boolean or null | Whether TikTok marks the sound as original, or `null` when unavailable. |
| `hashtags` | array of strings | Hashtags attached to the caption. It is empty when none are shown. |
| `captionMentions` | array of strings | Creator handles mentioned in the public caption. It is empty when none are shown. |
| `media` | object | Direct public media links and available media details. |
| `media.downloadUrl` | string or null | Main direct public video URL, or `null` for a photo carousel or when no usable link is exposed. |
| `media.watermarkFreeVideoUrl` | string or null | Direct public watermark-free video URL when TikTok exposes one, or `null` otherwise. |
| `media.coverImageUrl` | string or null | Direct public cover-image URL, or `null` when unavailable. |
| `media.photoUrls` | array of strings | Direct public photo URLs in a photo carousel. It is empty for videos or when no photo URL is available. |
| `playlists` | array of objects | Public playlists or mixes that contain the upload. It is empty when none are found. |
| `playlists[].playlistId` | string or null | Stable TikTok playlist or mix ID, or `null` when unavailable. |
| `playlists[].name` | string or null | Public playlist or mix name, or `null` when unavailable. |
| `playlists[].url` | string or null | Public playlist or mix URL, or `null` when unavailable. |
| `playlists[].videoCount` | integer or null | Public number of videos in the playlist or mix, or `null` when unavailable. |
| `playlists[].ownerUsername` | string or null | Playlist or mix owner's username, or `null` when unavailable. |
| `playlists[].position` | integer or null | One-based position of this upload in the playlist or mix, or `null` when TikTok does not expose it. |
| `repost` | object or null | Original upload details when this row is a repost. It is `null` for the creator's own upload. |
| `repost.originalVideo` | object | Original upload shared by this repost. |
| `repost.originalVideo.videoId` | string | Stable TikTok ID for the original upload. |
| `repost.originalVideo.videoUrl` | string | Canonical public TikTok page for the original upload. |
| `repost.originalCreator` | object | Creator of the original upload. |
| `repost.originalCreator.username` | string | Original creator username without the leading `@`. |
| `repost.originalCreator.displayName` | string or null | Original creator display name, or `null` when unavailable. |
| `repost.originalCreator.profileUrl` | string or null | Original creator public profile URL, or `null` when unavailable. |
| `relatedCreators` | array of objects | Extra public profile details for creators found in a repost or caption mention. It is empty when enrichment is off or no creators are found. |
| `relatedCreators[].username` | string | Related creator username without the leading `@`. |
| `relatedCreators[].displayName` | string or null | Related creator display name, or `null` when unavailable. |
| `relatedCreators[].profileUrl` | string or null | Related creator public profile URL, or `null` when unavailable. |
| `relatedCreators[].followerCount` | integer or null | Public follower count, or `null` when unavailable. |
| `relatedCreators[].followingCount` | integer or null | Public following count, or `null` when unavailable. |
| `relatedCreators[].videoCount` | integer or null | Public video count, or `null` when unavailable. |
| `relatedCreators[].likesReceivedCount` | integer or null | Public likes received count, or `null` when unavailable. |
| `relatedCreators[].bio` | string or null | Public profile bio, or `null` when unavailable. |
| `relatedCreators[].links` | array of strings | Public links listed on the profile. It is empty when none are shown. |
| `relatedCreators[].isBusinessAccount` | boolean or null | Whether TikTok marks the profile as a business account, or `null` when unavailable. |

**Example row**

This complete row came from a successful current-beta run with reposts and related-creator enrichment enabled. The signed links are genuine source values and may expire.

```json
{
  "requestedProfile": "@tiktok",
  "videoId": "7677743868229455135",
  "videoUrl": "https://www.tiktok.com/@thedodo/video/7677743868229455135",
  "caption": "For International Dog Day 2026, join @TikTok and The Dodo at @Wags & Walks Rescue’s LA headquarters to meet some adoptable rescue dogs and break down common myths around rescuing. 🐶 #internationaldogday",
  "publishedAt": "2026-08-24T23:27:37.000Z",
  "durationSeconds": 20,
  "mediaType": "video",
  "playCount": 19800,
  "likeCount": 561,
  "commentCount": 27,
  "shareCount": 18,
  "saveCount": 26,
  "creator": {
    "username": "thedodo",
    "displayName": "The Dodo",
    "followerCount": 6300000,
    "profileUrl": "https://www.tiktok.com/@thedodo",
    "isVerified": true
  },
  "sound": {
    "soundId": "7677743825783196446",
    "title": "original sound",
    "author": "The Dodo",
    "isOriginal": true
  },
  "hashtags": [
    "internationaldogday"
  ],
  "captionMentions": [
    "@tiktok",
    "@wagsandwalksla"
  ],
  "media": {
    "downloadUrl": "https://v16-webapp-prime.us.tiktok.com/video/tos/useast8/tos-useast8-ve-0068c001-tx2/oApBEAbGliXs0NMV5zazv03SKoEQBiZIpqRBA/?a=1988&bti=ODszNWYuMDE6&&bt=493&ft=aEeq8qT0mIoPD128soxI3wU4ooAbMeF~O5&mime_type=video_mp4&rc=MzQzZTtnaWloZjVmM2dkM0BpamZkb245cnVnZDMzaTczNEBfXjE0YzFjNS8xMTQ0Y18vYSNoZ3FgMmRrMTNhLS1kMTJzcw%3D%3D&expire=1788460648&l=2026090118370713824891AC2B352A0590&ply_type=2&policy=2&signature=7752a99b65230ad97b5fd9ae88071b9d&tk=tt_chain_token&btag=e000b8000",
    "watermarkFreeVideoUrl": null,
    "coverImageUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast8-p-0068-tx2/oAyvXIbRZIAU1BVm0YlSpASiBoqzaB02ispEM~tplv-tiktokx-origin.image?dr=9636&x-expires=1788458400&x-signature=G683Md6j11MYCMVePE0fiQiVPa8%3D&t=4d5b0474&ps=13740610&shp=81f88b70&shcp=43f4a2f9&idc=useast5",
    "photoUrls": []
  },
  "playlists": [],
  "repost": {
    "originalVideo": {
      "videoId": "7677743868229455135",
      "videoUrl": "https://www.tiktok.com/@thedodo/video/7677743868229455135"
    },
    "originalCreator": {
      "username": "thedodo",
      "displayName": "The Dodo",
      "profileUrl": "https://www.tiktok.com/@thedodo"
    }
  },
  "relatedCreators": [
    {
      "username": "wagsandwalksla",
      "displayName": "Wags & Walks Rescue",
      "profileUrl": "https://www.tiktok.com/@wagsandwalksla",
      "followerCount": 9208,
      "followingCount": 76,
      "videoCount": 469,
      "likesReceivedCount": 194900,
      "bio": "LA based dog rescue 🐾",
      "links": [
        "https://linkin.bio/wagsandwalks"
      ],
      "isBusinessAccount": true
    },
    {
      "username": "thedodo",
      "displayName": "The Dodo",
      "profileUrl": "https://www.tiktok.com/@thedodo",
      "followerCount": 6300000,
      "followingCount": 2056,
      "videoCount": 4463,
      "likesReceivedCount": 259200000,
      "bio": "For animal people.",
      "links": [
        "https://likeshop.me/t/thedodo"
      ],
      "isBusinessAccount": true
    }
  ]
}
```

#### 💳 Pricing

Pricing is pay per event. You pay for each `Profile Video` event, which represents one deduplicated public video saved to the default dataset. The exact tier price is shown on the Store page.

| Event | What it covers |
| --- | --- |
| `Profile Video` | One deduplicated public video saved to the default dataset. |

#### 🔌 Integrations

Read the default dataset from the Output panel or through the Apify API. Use the public TikTok page URLs in each row to trace the source upload. Direct media links are source links and may expire.

Watch the Apify workflow guide:

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

#### ❓ FAQ

##### What happens if the same upload appears more than once?

The first eligible occurrence is saved. Later matches from another submitted username, URL, user ID, or supported profile surface are ignored, and the row keeps the first requested-profile attribution.

##### What is the difference between Include playlists and Check playlist membership?

Include playlists can add public uploads found in the target creator's playlists or mixes. Check playlist membership checks ordinary profile-feed videos for public membership and does not collect playlist-only videos.

##### Can I collect public reposts and filter to amplified uploads?

Yes. Turn on **Include reposted videos** to add public reposts. Turn on **Only reposts or mentions** to keep uploads that repost or mention another creator. That filter does not turn on repost collection.

##### What does an empty Maximum uploads per profile value do?

It returns all available results until the source is exhausted. Set `maxItems` when you want a shorter run or fewer rows to review.

##### What happens when a profile is private or unavailable?

The Actor does not make placeholder rows for private, deleted, or unreadable targets. Other submitted targets can continue when possible, but a target can return no rows when public data is not available.

##### How are photo carousels represented?

The row uses `mediaType: "photoCarousel"`. Its `media.photoUrls` can hold the public photo links, while video-only media links and duration can be `null`.

##### Are the media links permanent?

No. TikTok can return signed links that expire. Use the public `videoUrl` for the source page and rerun when you need fresh media links.

##### Do I need a TikTok login or API key?

No. The Actor reads public TikTok surfaces without a TikTok login, OAuth, or source credential. Private and login-gated content is outside the product.

##### Can I search by hashtag or keyword?

No. The Actor starts from known creator usernames, profile URLs, or numeric user IDs. Hashtag, keyword, and general creator-discovery search are outside its scope.

##### Can I submit an exact video URL?

No. `creatorTargets` accepts creator usernames, profile URLs, or numeric user IDs. The run collects the selected public surfaces for those creator targets.

### 📝 Changelog

**v0.0** (01-09-2026)

- Initial release.

### 🆘 Support

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

### 🔗 Related Actors

- [TikTok Playlist Scraper](https://apify.com/maximedupre/tiktok-playlist): collect playlist names and ordered public videos related to a creator profile.
- [TikTok Repost Scraper](https://apify.com/maximedupre/tiktok-reposts): inspect public reposts and original creator details separately.
- [TikTok Profile Mention Scraper](https://apify.com/maximedupre/tiktok-profile-mention-scraper): find public videos that mention a profile handle.
- [TikTok Creator Analytics Scraper](https://apify.com/maximedupre/tiktok-creator-analytics): compare public profile totals and recent post metrics.
- [TikTok Video Downloader](https://apify.com/maximedupre/tiktok-video-downloader): resolve known public TikTok video URLs into direct media links.

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

# Actor input Schema

## `creatorTargets` (type: `array`):

Add one or more public TikTok creator usernames, profile URLs, or numeric user IDs. Use one value per line.

## `includePlaylists` (type: `boolean`):

Include public uploads found in the target creator's playlists or mixes, with playlist details when available. Playlist name filtering applies only when this is on.

## `checkPlaylistMembership` (type: `boolean`):

Check ordinary profile-feed videos for public playlist or mix membership. This adds membership details to those rows and does not collect playlist-only videos.

## `playlistNameFilter` (type: `string`):

Only collect public playlists or mixes whose name matches this text. This applies when Include playlists is on. Leave it blank or omit it to include all public playlists and mixes.

## `includeReposts` (type: `boolean`):

Include public videos reposted by the target creator and mark them as reposts. The original video and creator are included when TikTok exposes them.

## `onlyAmplified` (type: `boolean`):

Keep only uploads that repost or mention another creator. This filter does not turn on repost collection.

## `enrichRelatedCreators` (type: `boolean`):

Request extra public profile details for creators found in reposts or caption mentions, including audience size, content counts, bio information, links, and business account status.

## `maxItems` (type: `integer`):

Enter a positive whole number to stop after this many uploads for each requested profile. Leave it empty to collect all uploads TikTok exposes for the selected surfaces. This limit applies to each profile, not the whole run.

## `sortOrder` (type: `string`):

Choose the order of uploads within each profile.

## Actor input object example

```json
{
  "creatorTargets": [
    "@tiktok",
    "https://www.tiktok.com/@tiktok",
    "123456789"
  ],
  "includePlaylists": false,
  "checkPlaylistMembership": false,
  "playlistNameFilter": "music",
  "includeReposts": false,
  "onlyAmplified": false,
  "enrichRelatedCreators": false,
  "maxItems": 10,
  "sortOrder": "newest"
}
```

# Actor output Schema

## `datasetItems` (type: `string`):

Open the collected 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 = {
    "creatorTargets": [
        "@tiktok"
    ],
    "maxItems": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/tiktok-profile-videos-api").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 = {
    "creatorTargets": ["@tiktok"],
    "maxItems": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/tiktok-profile-videos-api").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 '{
  "creatorTargets": [
    "@tiktok"
  ],
  "maxItems": 10
}' |
apify call maximedupre/tiktok-profile-videos-api --silent --output-dataset

```

## MCP server setup

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

```

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/hO4BG9mvHo46deWN7/builds/iZ2jCxfDByqLvdNo1/openapi.json
