# TikTok Video Downloader (`parsebird/tiktok-video-downloader`) Actor

Download TikTok videos as MP4 from post URLs or short links. Get permanent re-hosted download links in Apify storage, AWS S3, Google Cloud, DigitalOcean Spaces or Azure, plus title and cover.

- **URL**: https://apify.com/parsebird/tiktok-video-downloader.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Stats:** 3 total users, 2 monthly users, 100.0% runs succeeded, 1 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.39 / 1,000 tiktok 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?

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 Video Downloader

TikTok Video Downloader saves public [TikTok](https://www.tiktok.com/) videos as MP4 files from post URLs or short links and gives you a permanent download link for each one.

<table width="100%" style="width:100%"><tr>
<td style="border-left:4px solid #25F4EE;padding:12px 16px;font-weight:600">
Paste tiktok.com/@user/video links or vt.tiktok.com, vm.tiktok.com and tiktok.com/t short links, and get each MP4 re-hosted to Apify storage, AWS S3, Google Cloud Storage, DigitalOcean Spaces or Azure Blob Storage, along with the caption, cover image, author, duration and file size.
</td>
</tr></table>
<br>
<table width="100%" style="width:100%">
<tr>
<td colspan="4" style="padding:10px 14px;background:#010101;border:none;border-radius:4px 4px 0 0">
<span style="color:#FFFFFF;font-size:14px;font-weight:700;letter-spacing:0.5px">ParseBird TikTok Suite</span>
<span style="color:#25F4EE;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;Trends, ads, LIVE, shop, stories, slideshows &amp; videos</span>
</td>
</tr>
<tr>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-trends-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Trends Scraper</a><br>
<span style="color:#78716C;font-size:11px">Trending hashtags, sounds, creators</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-ads-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Ads Scraper</a><br>
<span style="color:#78716C;font-size:11px">Creative Center Top Ads</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-top-ads-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Top Ads Scraper</a><br>
<span style="color:#78716C;font-size:11px">Top ads by likes tier &amp; language</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-top:none;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-live-search-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Live Search Scraper</a><br>
<span style="color:#78716C;font-size:11px">LIVE rooms broadcasting now</span>
</td>
</tr>
<tr>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;border-radius:0 0 0 4px;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-shop-reviews-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Shop Reviews Scraper</a><br>
<span style="color:#78716C;font-size:11px">Product reviews and ratings</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-story-viewer" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Story Viewer</a><br>
<span style="color:#78716C;font-size:11px">Active stories, no-watermark video</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%;background:#FFFFFF">
<a href="https://apify.com/parsebird/tiktok-slideshow-downloader" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:13px">TikTok Slideshow Downloader</a><br>
<span style="color:#78716C;font-size:11px">Photo-mode posts as image files</span>
</td>
<td style="padding:10px 14px;border:1px solid #E7E5E4;border-top:none;border-radius:0 0 4px 0;vertical-align:top;width:25%;background:#161823">
<a href="https://apify.com/parsebird/tiktok-video-downloader" style="color:#FFFFFF;text-decoration:none;font-weight:700;font-size:13px">TikTok Video Downloader</a><br>
<span style="color:#25F4EE;font-size:11px;font-weight:600">You are here</span>
</td>
</tr>
</table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```text
Use Apify Actor parsebird/tiktok-video-downloader to download public TikTok videos as MP4 and get a permanent download link per video. Example with ApifyClient (Python): client.actor("parsebird/tiktok-video-downloader").call(run_input={"startUrls":["https://www.tiktok.com/@cznburak/video/7120985110991604993","https://vt.tiktok.com/ZSDHmaujt/"],"storageType":"apify"}). Inputs: startUrls array of strings, required (tiktok.com/@user/video/{id} or /photo/{id} URLs, vt.tiktok.com, vm.tiktok.com and tiktok.com/t/ short links, resolved automatically); region string, optional two-letter country code such as US or DE (fetches through an IP in that country so TikTok serves its CDN for that location); maxItems integer, optional (max videos downloaded and charged per run, empty = unlimited); storageType "apify"|"aws"|"gcp"|"digitalocean"|"azure", default "apify"; AWS: s3AccessKeyId, s3SecretAccessKey, s3Region, s3Bucket, s3Path (optional); Google Cloud: googleCloudProjectId, googleCloudServiceKeyJson, googleCloudBucketName, googleCloudPath (optional); DigitalOcean Spaces: digitalOceanAccessKeyId, digitalOceanSecretAccessKey, digitalOceanRegion, digitalOceanBucketName, digitalOceanEndpoint, digitalOceanAcl ("private"|"public-read"), digitalOceanPath (all three optional); Azure: azureAccountName, azureAccountKey, azureContainerName, azurePath (optional); customMapFunction string, optional JavaScript function (object) => {...} applied to each item; outputConnector string, optional Apify MCP connector ID (Notion, Todoist and others); deliverTarget string, optional; deliverMode "perPost"|"summary", default "perPost"; deliverMaxItems integer, optional. Output: one dataset row per startUrls entry with title, sourceUrl, downloadUrl, cover, storageType, status ("succeeded"|"failed"|"invalidUrl"|"unavailable"|"noVideoContent"|"timedOut"), jobId, error, postId, authorUsername, durationSeconds, width, height, fileSizeBytes, storageKey, downloadedAt, inputSource{queryIndex,url}. Pricing: pay per event "video-downloaded", charged only for succeeded downloads; duplicates and failures are free. API docs: https://docs.apify.com/api/client/python/ and https://docs.apify.com/api/client/js/. Token: https://console.apify.com/account/integrations.
```

### What is TikTok Video Downloader?

**TikTok Video Downloader** is a bulk TikTok video downloader and TikTok API alternative. Give it a list of TikTok links, such as `https://www.tiktok.com/@cznburak/video/7120985110991604993` or a share link like `https://vt.tiktok.com/ZSDHmaujt/`, and it **downloads every video as an MP4 file** and **re-hosts it to your storage**. You get a stable download link instead of TikTok's short-lived signed CDN URL, plus the video caption, cover image, author username, duration, resolution and file size.

Videos go to the run's Apify key-value store with **zero setup**, or straight into **your own AWS S3, Google Cloud Storage, DigitalOcean Spaces or Azure Blob Storage** bucket.

The easiest way to try it: open the Input tab, keep the two prefilled TikTok links, and click **Start**.

### What can TikTok Video Downloader do?

- 🎬 **Download TikTok videos as MP4.** Each video is saved as an MP4 file named `tt-{postId}.mp4`, and its exact size is reported in `fileSizeBytes`.
- 🔗 **Resolve short links automatically.** `vt.tiktok.com`, `vm.tiktok.com` and `tiktok.com/t/…` links from the TikTok share menu are expanded to the underlying post. You don't need to open them yourself.
- ☁️ **Deliver to multiple clouds.** Pick the Apify key-value store, or bring your own AWS S3, Google Cloud Storage, DigitalOcean Spaces or Azure Blob Storage.
- 📌 **Get stable, re-hosted links.** TikTok's own video URLs are signed and expire. The `downloadUrl` points to your copy of the file instead.
- 🌍 **Target a regional CDN.** Set an optional two-letter `region` code and the video is fetched through an IP in that country, so TikTok serves it from its CDN for that location.
- 🧩 **Shape the output.** Apply a `customMapFunction` in JavaScript to reshape each item before it's saved.
- ♻️ **Deduplicate automatically.** If the same post appears twice in your input (for example, once as a full URL and once as a short link), it's downloaded and charged only once.
- 📤 **Send results to Notion, Todoist and more.** Deliver each video's status and download link through an Apify MCP connector.
- ⚙️ **Use the Apify platform.** Run it from the [Apify API](https://docs.apify.com/api/v2), set up [schedules](https://docs.apify.com/platform/schedules), connect [integrations](https://docs.apify.com/platform/integrations) (Make, Zapier, n8n, Google Drive, Slack, webhooks), and export results as JSON, CSV, Excel, XML or HTML.

#### Supported TikTok sources

| TikTok source | How to target it | What you get |
|---------------|------------------|--------------|
| Video post | `tiktok.com/@user/video/{id}` in `startUrls` | The MP4 re-hosted to your storage, with title, cover and video details |
| Photo-mode post | `tiktok.com/@user/photo/{id}` in `startUrls` | Recognized as a valid post and reported as `noVideoContent`, because it holds a slideshow of images instead of a video. Never charged. |
| Short link | `vt.tiktok.com/…`, `vm.tiktok.com/…` or `tiktok.com/t/…` in `startUrls` | Resolved to the underlying post automatically |

To download the images of photo-mode posts, use [TikTok Slideshow Downloader](https://apify.com/parsebird/tiktok-slideshow-downloader).

### What data can you extract from TikTok?

| Field | Description |
|-------|-------------|
| `title` | The video caption, including hashtags |
| `downloadUrl` | Permanent link to the MP4 in your chosen storage |
| `sourceUrl` | Canonical TikTok URL of the post |
| `cover` | Cover image URL of the video |
| `status` | `succeeded`, `failed`, `invalidUrl`, `unavailable`, `noVideoContent` or `timedOut` |
| `error` | Human-readable reason when the download did not succeed |
| `postId` | Numeric TikTok post ID |
| `authorUsername` | Username of the creator |
| `durationSeconds` | Video length in seconds |
| `width` / `height` | Video resolution in pixels |
| `fileSizeBytes` | Exact size of the saved MP4 |
| `storageType` / `storageKey` | Where the file was saved and its object key or path |
| `downloadedAt` | When the file was saved (UTC) |
| `inputSource` | The original input URL and its position (`queryIndex`) in `startUrls` |

### How to download TikTok videos

1. Open [TikTok Video Downloader](https://apify.com/parsebird/tiktok-video-downloader) in Apify Console and sign in (or create a free Apify account).
2. In **TikTok video URLs**, paste one link per line. Copy them from your browser's address bar or from TikTok's **Share → Copy link** button.
3. Optional: set **Max videos** to cap how many videos the run downloads and charges for.
4. Choose **Storage**. Keep **Apify key-value store** for zero setup, or pick your cloud and fill in its section (keys, region, bucket, optional path).
5. Optional: enter a **Region** code such as `US` or `DE`.
6. Click **Start** and wait for the run to finish. Short runs take a few seconds.
7. Open the **Output** tab. Each row has a `downloadUrl`. Click it to download the MP4, or export the whole table as JSON, CSV or Excel.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `startUrls` | array | **Yes** | — | TikTok post URLs or short links (vt.tiktok.com, vm.tiktok.com, tiktok.com/t/…), resolved automatically |
| `region` | string | No | — | Two-letter country code (e.g. `US`, `DE`). Selects which TikTok CDN location the video is fetched from |
| `maxItems` | integer | No | unlimited | Maximum number of videos to download and be charged for in this run |
| `storageType` | string | No | `apify` | `apify`, `aws`, `gcp`, `digitalocean` or `azure` |
| `customMapFunction` | string | No | — | JavaScript function applied to each output item, e.g. `(object) => { return {...object} }` |
| `outputConnector` | string | No | — | MCP connector to deliver the results to (see below) |
| `deliverTarget` | string | No | — | URL or ID of where the connector writes |
| `deliverMode` | string | No | `perPost` | `perPost` (one record per video) or `summary` (one roll-up per run) |
| `deliverMaxItems` | integer | No | — | Cap on how many records `perPost` delivers (ignored in `summary`) |

#### Storage configuration

| Storage | Fields |
|---------|--------|
| AWS S3 | `s3AccessKeyId`, `s3SecretAccessKey`, `s3Region`, `s3Bucket`, `s3Path` (optional) |
| Google Cloud Storage | `googleCloudProjectId`, `googleCloudServiceKeyJson`, `googleCloudBucketName`, `googleCloudPath` (optional) |
| DigitalOcean Spaces | `digitalOceanAccessKeyId`, `digitalOceanSecretAccessKey`, `digitalOceanRegion`, `digitalOceanBucketName`, `digitalOceanEndpoint` (optional), `digitalOceanAcl` (optional), `digitalOceanPath` (optional) |
| Azure Blob Storage | `azureAccountName`, `azureAccountKey`, `azureContainerName`, `azurePath` (optional) |

Keys and secrets are stored as [secret input](https://docs.apify.com/platform/actors/development/actor-definition/input-schema/secret-input), encrypted and hidden in the run's input. The credentials only need permission to upload objects (for example, `s3:PutObject` on AWS or the Storage Object Creator role on Google Cloud). If uploads keep failing at the start of a run, the Actor stops early so it doesn't download videos it can't deliver, and it shows the storage error.

#### Input examples

**Basic download**

```json
{
    "startUrls": [
        "https://www.tiktok.com/@cznburak/video/7120985110991604993",
        "https://vt.tiktok.com/ZSDHmaujt/"
    ],
    "storageType": "apify"
}
```

**With a region hint**

```json
{
    "startUrls": ["https://www.tiktok.com/@cznburak/video/7120985110991604993"],
    "region": "DE",
    "storageType": "apify"
}
```

**Deliver to your own S3 bucket**

```json
{
    "startUrls": ["https://www.tiktok.com/@cznburak/video/7120985110991604993"],
    "storageType": "aws",
    "s3AccessKeyId": "AKIAEXAMPLE",
    "s3SecretAccessKey": "example-secret-key",
    "s3Region": "us-east-1",
    "s3Bucket": "my-tiktok-downloads",
    "s3Path": "tiktok/videos"
}
```

**Capped run with output reshaping**

```json
{
    "startUrls": [
        "https://www.tiktok.com/@cznburak/video/7120985110991604993",
        "https://vt.tiktok.com/ZSDHmaujt/"
    ],
    "maxItems": 1,
    "customMapFunction": "(object) => { return { url: object.downloadUrl, status: object.status } }"
}
```

### Output example

Every dataset row corresponds to one entry in `startUrls`, and its shape is the same for every outcome. You can download the dataset as JSON, HTML, CSV or Excel.

**Succeeded**

```json
{
    "title": "En Güzel Bağ Sevgidir🥺❤️",
    "sourceUrl": "https://www.tiktok.com/@cznburak/video/7120985110991604993",
    "downloadUrl": "https://api.apify.com/v2/key-value-stores/hlPBI1e5gqpafCOpH/records/tt-7120985110991604993.mp4?signature=5APgCqnzAGVSv6ipayiM",
    "cover": "https://p16-common-sign.tiktokcdn-us.com/tos-alisg-p-0037/67aa7abe6dc74c97b9b0bc94176fbf28_1657983558~tplv-tiktokx-origin.image?dr=9636&x-expires=1791766800&...",
    "storageType": "apify",
    "status": "succeeded",
    "jobId": "job_4698cf90",
    "error": null,
    "postId": "7120985110991604993",
    "authorUsername": "cznburak",
    "durationSeconds": 30,
    "width": 576,
    "height": 1024,
    "fileSizeBytes": 6326163,
    "storageKey": "tt-7120985110991604993.mp4",
    "downloadedAt": "2026-10-10T01:21:47Z",
    "inputSource": {
        "queryIndex": 0,
        "url": "https://www.tiktok.com/@cznburak/video/7120985110991604993"
    }
}
```

**Photo-mode post (no video)**

```json
{
    "title": "¡Podemos tener más comunicación! 📣 ...",
    "sourceUrl": "https://www.tiktok.com/@anamiriamyepez/photo/7498924643227536645",
    "downloadUrl": null,
    "cover": "https://p16-common-sign.tiktokcdn.com/tos-maliva-i-photomode-us/4e11f114a249493eb708aa9977d014ca~tplv-photomode-image.jpeg?...",
    "storageType": "apify",
    "status": "noVideoContent",
    "jobId": null,
    "error": "The post contains no video.",
    "postId": "7498924643227536645",
    "authorUsername": "anamiriamyepez",
    "durationSeconds": null,
    "width": null,
    "height": null,
    "fileSizeBytes": null,
    "storageKey": null,
    "downloadedAt": null,
    "inputSource": {
        "queryIndex": 2,
        "url": "https://www.tiktok.com/@anamiriamyepez/photo/7498924643227536645"
    }
}
```

**Status values**

| `status` | Meaning | Charged |
|----------|---------|---------|
| `succeeded` | The MP4 was downloaded and saved; `downloadUrl` is set | Yes |
| `failed` | The page or video could not be downloaded, or the upload to your storage failed; see `error` | No |
| `invalidUrl` | Not a TikTok post URL, or a short link that is expired or invalid | No |
| `unavailable` | The post does not exist, or it is private or deleted | No |
| `noVideoContent` | A photo-mode post (slideshow) with no video | No |
| `timedOut` | The run ran out of time before this video was downloaded | No |

### Send results to Notion, Todoist and more (MCP connectors)

TikTok Video Downloader can deliver its results directly into the tools you already use, through [Apify MCP connectors](https://docs.apify.com/integrations/mcp-connectors).

1. Authorize a connector (Notion, Todoist, or any service whose MCP server offers non-destructive write tools) once in Apify Console → **Settings → API & Integrations → MCP connectors**.
2. Pick it in the **Send results to Notion, Todoist, …** field.
3. Fill in where and how to write:
   - **Destination target**: paste the URL or ID. For Notion, use a page URL (for example `https://www.notion.so/My-Posts-24f8a1b2c3d44e5f8a9b0c1d2e3f4a5b`) and share the page with your connector first via Notion's ••• → Connections menu. For Todoist, use a project URL or ID. Some services need none.
   - **Write mode**: `perPost` writes one record per video; `summary` writes a single roll-up for the run.
   - **Max records to deliver** (optional): cap on how many records `perPost` delivers.

Each video becomes one record with its status, source URL and download link. Failed downloads are delivered too, with their status and error, so the destination doubles as a download log.

**Notion as a spreadsheet.** When the target is a Notion page, the Actor creates a new database under it with one typed column per field (URL, number, date or text). Nested fields are flattened into their own columns, so `inputSource` becomes `inputSource.url` and `inputSource.queryIndex`. When the target is an existing database, the Actor fills the columns it already has (matched by name), and the rest of each record goes to the row's page body, so nothing is lost. The connector can't add columns to an existing database.

**Your credentials stay yours.** The Actor reaches your services only through your own authorized connector, and the connector field only accepts non-destructive tools. Delivery is best-effort and runs after the downloads: if a connector is misconfigured or a delivery fails, the run still finishes normally with all results intact, and the problem is reported in the run log. If the run is about to hit its timeout, delivery stops early, and the log shows how many records were delivered.

Links to Apify storage stay valid for as long as the run's storage is retained. Use your own cloud storage for permanent links.

### Use TikTok Video Downloader with the API

**Python** ([apify-client](https://docs.apify.com/api/client/python/))

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_APIFY_TOKEN>")

run = client.actor("parsebird/tiktok-video-downloader").call(run_input={
    "startUrls": [
        "https://www.tiktok.com/@cznburak/video/7120985110991604993",
        "https://vt.tiktok.com/ZSDHmaujt/",
    ],
    "storageType": "apify",
})

for video in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(video["status"], video["downloadUrl"])
```

**JavaScript** ([apify-client](https://docs.apify.com/api/client/js/))

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });

const run = await client.actor('parsebird/tiktok-video-downloader').call({
    startUrls: ['https://www.tiktok.com/@cznburak/video/7120985110991604993'],
    storageType: 'apify',
    maxItems: 10,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const video of items) {
    console.log(video.status, video.downloadUrl);
}
```

Get your API token in [Apify Console → Integrations](https://console.apify.com/account/integrations).

### Use cases

- **Content archiving.** Keep your own copy of your brand's or clients' TikTok videos in a bucket you control.
- **Repurposing your own content.** Pull MP4s of videos you own into editing tools or other platforms.
- **Social media research.** Collect videos with captions, authors and durations for trend analysis or media monitoring.
- **Dataset building.** Gather video files with resolution and size for computer vision or multimodal model evaluation.
- **Automation pipelines.** Combine with [TikTok Trends Scraper](https://apify.com/parsebird/tiktok-trends-scraper) to find trending videos, then download them here on a schedule.

### How it works

1. Each input is checked. Short links are expanded to the post they point to, and anything that isn't a TikTok post becomes an `invalidUrl` row.
2. The Actor loads the public post page and reads the post data TikTok embeds in it. No login or cookies from you are needed.
3. Photo-mode posts are reported as `noVideoContent`. For video posts, the Actor downloads the MP4 and checks that the file is complete.
4. The file is uploaded to the storage you chose, and a row with the `downloadUrl` is saved to the dataset.
5. Optionally, the results are delivered through your MCP connector after all downloads finish.

Duplicate posts reuse the first result. If the run gets restarted on another server, it resumes where it left off without downloading or charging again.

### How much does it cost to download TikTok videos?

TikTok Video Downloader uses **pay-per-event** pricing. Platform usage (compute, proxy and data transfer) is included in the event price.

| Event | When it is charged | Free | Bronze | Silver | Gold |
|-------|--------------------|------|--------|--------|------|
| `video-downloaded` | One TikTok video downloaded and saved to your storage | $2.99 / 1,000 | $2.79 / 1,000 | $2.59 / 1,000 | $2.39 / 1,000 |

**Examples (Free tier):** 100 videos cost **$0.299**, and 1,000 videos cost **$2.99**.

Only `succeeded` rows are charged. Failed downloads, invalid URLs, unavailable posts, photo-mode posts, timed-out entries and duplicates are **free**. Use `maxItems` to cap the number of paid downloads. If you set a maximum cost per run, the Actor checks the budget **before** each download and stops when the next video would not fit. Storing files in your own cloud may incur charges from your cloud provider.

### FAQ

**What video quality does TikTok Video Downloader save?**
It saves the H.264 MP4 that TikTok's web player streams for the post. The exact resolution depends on the upload and is reported in `width` and `height`. For example, the prefilled 30-second video is 576×1024 and about 6.3 MB.

**How long do download links stay valid?**
Links to Apify storage point to the run's default key-value store and follow your plan's [data retention](https://docs.apify.com/platform/storage/usage) for unnamed storages. Links to your own S3, Google Cloud, Spaces or Azure bucket are permanent object URLs. Whether they open in a browser depends on the bucket's access settings (for Spaces you can set `digitalOceanAcl` to `public-read`).

**Do I need a TikTok account or API key?**
No. The Actor only reads public post pages and doesn't log in. Private, deleted and login-only posts are reported as `unavailable`.

**What does the region option do?**
It fetches the post through an IP address in the country you choose, so TikTok returns its CDN for that location. For example, in our tests `DE` returned `tiktokcdn-eu.com` addresses and `US` returned `tiktokcdn-us.com` addresses. Leave it empty unless you have a reason to pick a location.

**Can I download a whole TikTok profile or hashtag?**
Not directly. This Actor downloads videos you already have links for. Collect links first with a scraper such as [TikTok Trends Scraper](https://apify.com/parsebird/tiktok-trends-scraper), then pass them to `startUrls`.

**Why did a short link come back as `invalidUrl`?**
Old or revoked share links redirect to TikTok's homepage instead of a post. Open the link in your browser to check. If it doesn't open a video, copy a fresh link from TikTok.

**How does `customMapFunction` work?**
It's a JavaScript function that receives each output item and returns the object to save, for example `(object) => { return { url: object.downloadUrl, status: object.status } }`. It runs in an isolated JavaScript engine. If it throws or doesn't return an object, the original item is saved and a warning is logged.

**Can I schedule it or connect it to other tools?**
Yes. Use [Apify schedules](https://docs.apify.com/platform/schedules) for recurring runs, and [integrations](https://docs.apify.com/platform/integrations) or [webhooks](https://docs.apify.com/platform/integrations/webhooks) to send results to Google Drive, Slack, Make, Zapier, n8n or your own API.

**I found a problem or need a feature.**
Open an issue in the **Issues** tab with the TikTok URL and what you expected.

### Is it legal to download TikTok videos?

TikTok Video Downloader only reads **publicly available** TikTok posts. It does not log in, and it does not access private accounts or private user data. TikTok videos are still protected by their creators' copyright, so download and reuse content only when you own it, have permission, or your use is otherwise allowed by law. Your use must also follow [TikTok's Terms of Service](https://www.tiktok.com/legal/page/global/terms-of-service/en). If your results include personal data, you are responsible for handling it lawfully under regulations such as GDPR. When in doubt, consult a lawyer. Read more in Apify's guide: [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

### Other TikTok tools

| Actor | What it does |
|-------|--------------|
| [TikTok Slideshow Downloader](https://apify.com/parsebird/tiktok-slideshow-downloader) | Download every image from TikTok photo-mode posts |
| [TikTok Story Viewer](https://apify.com/parsebird/tiktok-story-viewer) | View and download active public TikTok stories by username |
| [TikTok Trends Scraper](https://apify.com/parsebird/tiktok-trends-scraper) | Scrape trending TikTok hashtags, videos, sounds and creators by country |
| [TikTok Live Search Scraper](https://apify.com/parsebird/tiktok-live-search-scraper) | Search TikTok LIVE rooms by keyword |
| [TikTok Shop Reviews Scraper](https://apify.com/parsebird/tiktok-shop-reviews-scraper) | Scrape TikTok Shop product reviews by link or product ID |
| [TikTok Ads Scraper](https://apify.com/parsebird/tiktok-ads-scraper) | Scrape TikTok Top Ads from Creative Center |

### Other video downloaders

| Actor | What it does |
|-------|--------------|
| [Twitter (X) Video Downloader](https://apify.com/parsebird/twitter-video-downloader) | Download videos, GIFs and photos from X posts |
| [Facebook Media Downloader](https://apify.com/parsebird/facebook-media-downloader) | Download videos, reels and photos from public Facebook links |
| [Pinterest Video Downloader](https://apify.com/parsebird/pinterest-video-downloader) | Download MP4 videos and images from Pinterest pins |
| [YouTube Shorts Downloader](https://apify.com/parsebird/youtube-shorts-downloader) | Get direct media download links for YouTube Shorts |

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/tiktok-video-downloader/changelog.md

# Actor input Schema

## `startUrls` (type: `array`):

Add TikTok post URLs, one per line. Canonical video/photo URLs and short links (vt.tiktok.com, vm.tiktok.com, tiktok.com/t/…) are supported; short links are resolved automatically.

## `region` (type: `string`):

Optional two-letter country code (e.g. US, DE). Fetches the video through an Apify Proxy IP in that country, so TikTok serves it from its CDN for that location. Leave empty for automatic.

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

Maximum number of videos to download (and be charged for) in this run. Leave empty for no limit.

## `storageType` (type: `string`):

Where downloaded videos are delivered. Apify storage needs no setup. For your own cloud, fill in the matching section below.

## `s3AccessKeyId` (type: `string`):

Access key ID of an IAM user allowed to call s3:PutObject on the bucket.

## `s3SecretAccessKey` (type: `string`):

Secret access key for the access key ID above.

## `s3Region` (type: `string`):

Bucket region, e.g. us-east-1.

## `s3Bucket` (type: `string`):

Bucket name.

## `s3Path` (type: `string`):

Folder prefix inside the bucket, e.g. tiktok/videos.

## `googleCloudProjectId` (type: `string`):

ID of the project that owns the bucket.

## `googleCloudServiceKeyJson` (type: `string`):

Paste the full JSON key file of a service account with permission to create objects in the bucket (e.g. Storage Object Creator).

## `googleCloudBucketName` (type: `string`):

Google Cloud Storage bucket name.

## `googleCloudPath` (type: `string`):

Folder prefix inside the bucket.

## `digitalOceanAccessKeyId` (type: `string`):

DigitalOcean Spaces access key.

## `digitalOceanSecretAccessKey` (type: `string`):

Secret key for the Spaces access key above.

## `digitalOceanRegion` (type: `string`):

Region slug of the Space, e.g. nyc3, fra1, sgp1.

## `digitalOceanBucketName` (type: `string`):

Name of the Space (bucket).

## `digitalOceanEndpoint` (type: `string`):

Custom endpoint. Defaults to https://{region}.digitaloceanspaces.com.

## `digitalOceanAcl` (type: `string`):

Access level for uploaded files. Public read makes the download link open in any browser.

## `digitalOceanPath` (type: `string`):

Folder prefix inside the Space.

## `azureAccountName` (type: `string`):

Azure storage account name.

## `azureAccountKey` (type: `string`):

Access key of the storage account.

## `azureContainerName` (type: `string`):

Blob container to upload into.

## `azurePath` (type: `string`):

Folder prefix inside the container.

## `customMapFunction` (type: `string`):

Optional JavaScript function applied to each output item before it is saved, e.g. <code>(object) => { return { url: object.downloadUrl, status: object.status } }</code>.

## `outputConnector` (type: `string`):

Optional MCP connector to deliver the results to. Authorize it first in Apify Console → Settings → API & Integrations → MCP connectors.

## `deliverTarget` (type: `string`):

URL or ID of where the connector writes. Notion: a page URL (a typed database is created for you) or an existing database URL. Todoist: a project URL or ID. Some services need none.

## `deliverMode` (type: `string`):

perPost writes one record per video; summary writes a single roll-up for the run.

## `deliverMaxItems` (type: `integer`):

Optional cap on how many records perPost delivers (ignored in summary mode).

## Actor input object example

```json
{
  "startUrls": [
    "https://www.tiktok.com/@cznburak/video/7120985110991604993",
    "https://vt.tiktok.com/ZSDHmaujt/"
  ],
  "storageType": "apify",
  "deliverMode": "perPost"
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

## `files` (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 = {
    "startUrls": [
        "https://www.tiktok.com/@cznburak/video/7120985110991604993",
        "https://vt.tiktok.com/ZSDHmaujt/"
    ],
    "storageType": "apify"
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/tiktok-video-downloader").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 = {
    "startUrls": [
        "https://www.tiktok.com/@cznburak/video/7120985110991604993",
        "https://vt.tiktok.com/ZSDHmaujt/",
    ],
    "storageType": "apify",
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/tiktok-video-downloader").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 '{
  "startUrls": [
    "https://www.tiktok.com/@cznburak/video/7120985110991604993",
    "https://vt.tiktok.com/ZSDHmaujt/"
  ],
  "storageType": "apify"
}' |
apify call parsebird/tiktok-video-downloader --silent --output-dataset

```

## MCP server setup

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

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/7O3tsd0UvgW9RWBkN/builds/QlVyljSwqd2p6G79h/openapi.json
