# TikTok Profile Scraper (`mrdoe/tiktok-scraper`) Actor

Scrape TikTok profiles and recent videos without login or cookies. Extract video views, likes, comments, shares, favorites, captions, dates, creator profiles, music metadata, and optional video/audio downloads.

- **URL**: https://apify.com/mrdoe/tiktok-scraper.md
- **Developed by:** [MrDoe](https://apify.com/mrdoe) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 2 monthly users, 92.5% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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 Scraper](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/tiktok-scraper--hero.png)

## TikTok Scraper — scrape profile videos & download them (MP4 + MP3)

**Give it a TikTok profile URL and get every recent video as clean data — play, like, comment, share and favorite counts, the caption, the author, and the sound — plus an optional download of the video file and its audio track.** No TikTok login, no cookies, no account.

This Actor is a **TikTok profile scraper**, a **TikTok video downloader**, and a **TikTok sound / audio downloader** in one.

***

### What does the TikTok Scraper do?

Point it at one or more public TikTok profiles. It collects each profile's recent videos and returns one dataset row per video. By default it also downloads each video as an `.mp4` and its sound as an `.mp3` to storage, with direct links on the row.

![What a TikTok video gives you](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/tiktok-scraper--video-fields.png)

### Why use this TikTok scraper?

- **Creator & competitor tracking** — pull the full engagement set (plays, likes, comments, shares, favorites) for every recent video on a profile without opening each one.
- **Sound & trend research** — every row carries the video's music/sound: title, artist, and whether it's an original sound.
- **Archive or repurpose** — download the actual `.mp4` and `.mp3` files straight into Apify storage, not just links that expire.
- **No login** — no account, no cookies, nothing to connect and no account to get restricted.
- **Just works** — the Actor handles the hard part (bot detection, rate limits, rotating identities, retries) so you don't manage any of it.
- **Standard exports** — JSON, CSV, Excel, XML, or the Apify API.

### What makes this Actor different?

- **Complete data in one pass** — every engagement count, the caption, the author, the sound, and the actual video and audio files. No second tool, no stitching results together.
- **Reliable at scale** — built to keep working through TikTok's frequent anti-scraping changes, with automatic retries and identity rotation handled for you.
- **Real downloads** — MP4 + MP3 saved straight to storage with permanent links, so what you collect today still opens next month.
- **No account risk** — nothing is ever logged in, so there's no account to rate-limit, flag or ban.

### How it works

![How the TikTok Scraper works](https://api.apify.com/v2/key-value-stores/kE36venAoVchGsE6b/records/tiktok-scraper--how-it-works.png)

1. **Your input** — one or more profile URLs or `@handle`s, plus `maxItems` per profile and the download toggles.
2. **The Actor collects the data** — it takes care of everything between your input and clean results: anti-bot handling, rate limiting, rotating identities over residential IPs, retries and pagination.
3. **Output** — one dataset row per video, plus the downloaded media files in the key-value store.

### What data you get

| Field                                                         | Description                                                                    |
| ------------------------------------------------------------- | ------------------------------------------------------------------------------ |
| `url` / `id`                                                  | Video permalink and ID                                                         |
| `postedAt`                                                    | Publish time, ISO 8601                                                         |
| `description`                                                 | Caption text                                                                   |
| `playCount`                                                   | Views                                                                          |
| `likeCount` / `commentCount` / `shareCount` / `favoriteCount` | Engagement counts                                                              |
| `duration`                                                    | Video length in seconds                                                        |
| `videoTemporaryUrl`                                           | TikTok CDN link to the video (expires)                                         |
| `audioTemporaryUrl`                                           | TikTok CDN link to the sound (expires; original sounds only)                   |
| `videoStorageUrl`                                             | Permanent key-value-store link to the `.mp4` — set when `downloadVideos` is on |
| `audioStorageUrl`                                             | Permanent key-value-store link to the `.mp3` — set when `downloadAudio` is on  |
| `music`                                                       | `{ id, title, authorName, original }`                                          |
| `author`                                                      | `{ id, uniqueId, nickname, avatarUrl, verified, signature }`                   |

### Where do the downloaded video and audio go?

With `downloadVideos` / `downloadAudio` on (both default to **true**), the files are written to the run's **key-value store**:

| Option           | File saved             | Field with the link |
| ---------------- | ---------------------- | ------------------- |
| `downloadVideos` | `<user>-<videoId>.mp4` | `videoStorageUrl`   |
| `downloadAudio`  | `<user>-<videoId>.mp3` | `audioStorageUrl`   |

Each link looks like:

```text
https://api.apify.com/v2/key-value-stores/<storeId>/records/<user>-<videoId>.mp4
```

Those links are **permanent** (they live as long as the run's storage) and need no auth for a public run. Browse every file under the run's **Storage → Key-value store** tab in the Apify Console, or list them via the API.

`videoTemporaryUrl` / `audioTemporaryUrl` are temporary source links that **expire within hours** — use them only if you're fetching immediately; otherwise keep the download options on and use the storage links.

**The MP3:** for original sounds you get the clean source track; for licensed / commercial tracks the audio is taken straight from the video. Either way you get one `.mp3` per video.

### Input parameters

| Parameter                | Type    | Required | Default           | Description                                                                               |
| ------------------------ | ------- | -------- | ----------------- | ----------------------------------------------------------------------------------------- |
| `profileUrls`            | Array   | Yes      | —                 | TikTok profile URLs or `@handle`s to scrape.                                              |
| `maxItems`               | Integer | No       | `3`               | Stop after this many videos **per profile**. Raise it for a full export.                  |
| `downloadVideos`         | Boolean | No       | `true`            | Save each video's `.mp4` to the key-value store; adds `videoStorageUrl`.                  |
| `downloadAudio`          | Boolean | No       | `true`            | Save each video's sound as an `.mp3`; adds `audioStorageUrl`.                             |
| `proxyConfiguration`     | Object  | Yes      | Apify Residential | Required. TikTok flags datacenter IPs hard — a residential proxy is strongly recommended. |
| `notificationWebhookUrl` | String  | No       | —                 | A Discord or Slack incoming webhook (or any endpoint) to notify when the run finishes.    |

### Example output

```json
{
    "url": "https://www.tiktok.com/@travelusa_withme/video/7309500873443935278",
    "id": "7309500873443935278",
    "postedAt": "2026-08-10T14:32:00.000Z",
    "description": "Grand Canyon at sunrise 🌄🇺🇸",
    "playCount": 512340,
    "likeCount": 48210,
    "commentCount": 312,
    "shareCount": 890,
    "favoriteCount": 1204,
    "duration": 27,
    "videoTemporaryUrl": "https://v16-webapp-prime.tiktok.com/video/tos/...",
    "videoStorageUrl": "https://api.apify.com/v2/key-value-stores/abc123/records/travelusa_withme-7309500873443935278.mp4",
    "audioTemporaryUrl": "https://sf16-ies-music-va.tiktokcdn.com/obj/...",
    "audioStorageUrl": "https://api.apify.com/v2/key-value-stores/abc123/records/travelusa_withme-7309500873443935278.mp3",
    "music": {
        "id": "7309500000000000000",
        "title": "original sound",
        "authorName": "travelusa_withme",
        "original": true
    },
    "author": {
        "id": "6841234567890123456",
        "uniqueId": "travelusa_withme",
        "nickname": "Travel USA 🇺🇸",
        "avatarUrl": "https://p16-common-sign.tiktokcdn.com/...",
        "verified": false,
        "signature": "Traveling around the USA 🇺🇸"
    }
}
```

You can download the dataset as JSON, CSV, Excel, or XML.

### How to use the TikTok Scraper

1. Open the Actor's **Input** tab.
2. Paste one or more **`profileUrls`** (`https://www.tiktok.com/@name` or a bare `@name`).
3. Set **`maxItems`** — how many recent videos per profile.
4. Leave **Download videos** / **Download audio** on to store the media, or turn them off for metadata only.
5. Press **Start**. Rows appear in the **Dataset** tab; the `.mp4` / `.mp3` files land in the **Key-value store** tab.

### Usage examples

**Metadata only, last 30 videos**

```json
{ "profileUrls": ["https://www.tiktok.com/@nasa"], "maxItems": 30, "downloadVideos": false, "downloadAudio": false }
```

**Download every video + sound from a creator**

```json
{ "profileUrls": ["@zachking"], "maxItems": 50 }
```

**Several profiles with a Slack ping on finish**

```json
{
    "profileUrls": ["@nasa", "@spacex"],
    "maxItems": 20,
    "notificationWebhookUrl": "https://hooks.slack.com/services/..."
}
```

### Pricing / cost estimation

This Actor runs on your Apify plan's compute units — no separate per-result charge. Collecting from a heavily protected platform like TikTok, plus downloading video and audio, uses more compute and storage than a lightweight scraper. To keep runs cheap: lower `maxItems` and turn off whichever download you don't need.

### Tips for best results

- **Residential proxy, always.** A good residential proxy pool is the single biggest reliability factor. If a run returns 0 videos, try a different proxy country.
- **Temporary links expire.** Use `videoStorageUrl` / `audioStorageUrl` (or download promptly) for anything you keep.
- **`maxItems` is per profile**, not per run.
- **A retried request is normal** and clears on its own.

### Limitations

- **Public profiles only.** Private or nonexistent accounts return no data.
- TikTok's anti-scraping posture changes often; a run may need a retry or two, and very large exports go faster with a bigger residential proxy pool.
- `videoTemporaryUrl` / `audioTemporaryUrl` expire within hours.
- A row is a snapshot at collection time; counts keep moving.
- For licensed / commercial tracks the `.mp3` is taken from the video rather than a standalone source.

### FAQ

**Can I download a TikTok video with this Actor?**
Yes. `downloadVideos` is on by default — each video's `.mp4` is saved to the key-value store with a permanent link in `videoStorageUrl`.

**Can I download the sound / music from a TikTok video?**
Yes. `downloadAudio` is on by default — you get an `.mp3` per video in `audioStorageUrl`: the clean source track for original sounds, and the track taken from the video for licensed music.

**Where are the downloaded files saved?**
In the run's key-value store, as `<user>-<videoId>.mp4` / `.mp3`. The dataset rows carry the links, and you can browse or download them from the Storage tab in the Apify Console.

**Do I need a TikTok account or login?**
No. It only uses what TikTok shows to logged-out visitors — no account, no cookies.

**How many videos can it collect per profile?**
As many as `maxItems`. It keeps paging through the profile until it reaches your limit or the end of the profile.

**Why did a run return 0 videos?**
Almost always a temporary block (try a different residential proxy country) or a private/typo'd handle. The run log says which.

**How fresh is the data?**
Every run reads the live feed. Schedule the Actor to build an engagement history.

### Support

Found a bug or a field that changed shape? Open an issue on the Actor's **Issues** tab in the Apify Console.

### Legal / responsible use

This Actor accesses only data TikTok serves publicly to logged-out visitors and does not use login credentials. You are responsible for how you use the Actor and its output, including compliance with TikTok's Terms of Service, copyright in the videos and music you download, and the data-protection laws that apply to you.

# Actor input Schema

## `profileUrls` (type: `array`):

TikTok profile URLs, e.g. "https://www.tiktok.com/@travelusa/_withme". A bare "@handle" or "handle" also works.

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

Stop scraping a profile once this many videos have been collected.

## `downloadVideos` (type: `boolean`):

If enabled, each video's file is downloaded and stored in the key-value store, and a link to it is added to that video's dataset row.

## `downloadAudio` (type: `boolean`):

If enabled, each video's music/sound track is downloaded as a standalone audio file and stored in the key-value store, with a link added to that video's dataset row. Can be used together with or independently of "Download videos".

## `proxyConfiguration` (type: `object`):

Required - TikTok aggressively rate-limits and flags datacenter IPs. A residential proxy is strongly recommended.

## `notificationWebhookUrl` (type: `string`):

Get notified when the run finishes. Paste a Discord or Slack incoming webhook URL to post a message there, or any other webhook endpoint (Zapier, Make, Pipedream, or an email-forwarding webhook service) to receive a JSON summary instead. Leave blank to disable.

## Actor input object example

```json
{
  "profileUrls": [
    "https://www.tiktok.com/@travelusa_withme"
  ],
  "maxItems": 3,
  "downloadVideos": true,
  "downloadAudio": true,
  "proxyConfiguration": {
    "useApifyProxy": true,
    "apifyProxyGroups": [
      "RESIDENTIAL"
    ]
  }
}
```

# Actor output Schema

## `results` (type: `string`):

No description

# 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 = {
    "profileUrls": [
        "https://www.tiktok.com/@travelusa_withme"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("mrdoe/tiktok-scraper").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 = { "profileUrls": ["https://www.tiktok.com/@travelusa_withme"] }

# Run the Actor and wait for it to finish
run = client.actor("mrdoe/tiktok-scraper").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 '{
  "profileUrls": [
    "https://www.tiktok.com/@travelusa_withme"
  ]
}' |
apify call mrdoe/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/JfqcGYiOd5e5SsYtc/builds/Je5FZHr9zbgWuVqEG/openapi.json
