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

Download videos and audio from public TikTok video URLs. Save each media file to Apify storage with source links, author data, captions, file metadata, and dataset exports.

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

## Pricing

from $4.50 / 1,000 downloaded tiktok medias

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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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 video downloader for public video URLs

TikTok Video Downloader downloads video files, audio tracks, or both from public [TikTok](https://www.tiktok.com/) video URLs. Paste one or more TikTok video links and get downloadable media files saved in Apify storage, plus a dataset with source URLs, video IDs, author fields, captions, file names, content types, file sizes, and scrape timestamps.

Use this TikTok video downloader when you already have the TikTok video URLs and need a repeatable way to save the media for research, review, archiving, content operations, or downstream workflows. It works with public video pages only. You do not need to provide TikTok cookies, a TikTok login, or a TikTok API key.

For a small first run, keep the prefilled Apify TikTok video URL, leave **Media type** set to `Video`, and start the Actor. Once the output shape looks right, paste your own list of public TikTok video links or call the Actor through the Apify API.

### ✅ What this Actor does

- Accepts public TikTok video URLs.
- Downloads the TikTok video file, audio track, or both, depending on your input.
- Saves each downloaded media file to Apify key-value storage.
- Emits one dataset item per successfully downloaded media file.
- Adds the original URL, resolved source URL, TikTok video ID, author username, author name, caption, duration, cover URL, and scrape time when TikTok exposes them.
- Adds file metadata such as media type, quality setting, file name, content type, file size, storage key, and download URL.
- Adds visible video stats such as plays, likes, comments, shares, and collects when they are available on the public video page.
- Skips private, unavailable, or temporarily undownloadable media without saving failure rows.
- Stops at your total media item limit.

This Actor is focused on downloading media from known TikTok video URLs. It does not discover videos from profiles, hashtags, search results, comments, followers, TikTok Shop, or trending feeds.

### 📦 Data you can export

Each output item represents one downloaded TikTok media file. Core fields include:

- `inputIndex` and `requestedUrl`
- `sourceUrl` and `videoId`
- `authorUsername` and `authorName`
- `caption`, `durationSeconds`, and `coverUrl`
- `mediaType` with `video` or `audio`
- `quality`
- `downloadUrl`
- `fileName`, `contentType`, and `fileSizeBytes`
- `storageKey` and `sourceMediaUrl`
- `scrapedAt`
- `video` stats and dimensions when available
- `audio` metadata when available
- `userData` when you pass custom data with a URL

You can open the dataset in Apify, export it as JSON, CSV, Excel, XML, RSS, or HTML, call it through the Apify API, schedule runs, or connect it to webhooks and integrations. The binary media files are stored separately and linked from each dataset row through `downloadUrl`.

### 🚀 How to run

1. Paste one or more public TikTok video URLs in **TikTok video URLs**.
2. Choose **Media type**: `Video`, `Audio`, or `Video and audio`.
3. Keep **Media item limit** small for a test run, or raise it for larger batches.
4. Choose **Video quality** when downloading videos.
5. Start the Actor and open the dataset.
6. Use each row's `downloadUrl` to download the saved media file.

Desktop, mobile, and short TikTok video links are accepted when they resolve to a public video page. Profile URLs, hashtag URLs, search URLs, comment URLs, and private videos are not supported.

### 🔧 Input

| Field | What to enter |
| ----- | ------------- |
| `videoUrls` | Public TikTok video URLs. Each item can be a URL string or a request-list item with a `url` field. |
| `maxItems` | Maximum number of downloaded media files to save across the run. Default is `25`. |
| `mediaMode` | `video`, `audio`, or `both`. Default is `video`. |
| `quality` | `best`, `balanced`, or `small` for video downloads. Default is `balanced`. |

Example input:

```json
{
  "videoUrls": [
    {
      "url": "https://www.tiktok.com/@apifytech/video/7398101551744552225"
    }
  ],
  "mediaMode": "video",
  "quality": "balanced",
  "maxItems": 25
}
````

### 📄 Output example

```json
{
  "inputIndex": 1,
  "requestedUrl": "https://www.tiktok.com/@apifytech/video/7398101551744552225",
  "sourceUrl": "https://www.tiktok.com/@apifytech/video/7398101551744552225",
  "videoId": "7398101551744552225",
  "authorUsername": "apifytech",
  "authorName": "Apify",
  "caption": "Example TikTok caption",
  "durationSeconds": 23,
  "coverUrl": "https://...",
  "mediaType": "video",
  "quality": "balanced",
  "downloadUrl": "https://api.apify.com/v2/key-value-stores/.../records/tiktok-video-1-7398101551744552225",
  "fileName": "7398101551744552225-video.mp4",
  "contentType": "video/mp4",
  "fileSizeBytes": 1234567,
  "storageKey": "tiktok-video-1-7398101551744552225",
  "sourceMediaUrl": "https://...",
  "scrapedAt": "2026-05-26T16:00:00.000Z",
  "video": {
    "width": 576,
    "height": 1024,
    "playCount": 1000,
    "likeCount": 100,
    "commentCount": 10,
    "shareCount": 5,
    "collectCount": 2
  },
  "audio": {
    "id": "music-id",
    "title": "original sound",
    "authorName": "apifytech",
    "original": true,
    "durationSeconds": 23
  }
}
```

Some fields can be `null` when TikTok does not expose them on the public video page.

### 💳 Pricing

This Actor uses pay-per-event pricing. You are charged for each TikTok media file successfully downloaded and saved to storage. A video download counts as one media item. An audio download counts as one media item. If you choose `Video and audio`, one TikTok URL can produce two charged media items.

Skipped URLs and media files that cannot be downloaded are not saved as dataset rows.

### ⚠️ Limits and caveats

- The Actor needs direct TikTok video URLs. It does not search TikTok or crawl profiles.
- Only public TikTok video pages are supported.
- Some TikTok videos may not expose a downloadable video or audio URL at run time.
- Download URLs point to files saved in Apify storage for that run.
- `quality` affects video downloads only. Audio downloads use the audio track TikTok exposes.
- Output metadata depends on what TikTok shows on the public video page.

### ❓ FAQ

#### 🎧 Can I download TikTok audio only?

Yes. Set **Media type** to `Audio`. The Actor will save one audio file per TikTok video when TikTok exposes an audio track.

#### 📁 Can I download both video and audio from the same TikTok URL?

Yes. Set **Media type** to `Video and audio`. Each successful video file and each successful audio file is saved as a separate dataset item.

#### 🔎 Does this Actor find TikTok videos for me?

No. This Actor downloads media from TikTok video URLs you provide. For discovery workflows, use a TikTok search, keyword, profile, or transcript Actor that matches the data you need.

#### 🔐 Do I need a TikTok account?

No. The Actor is built for public TikTok video pages and does not ask you for TikTok login details, cookies, or an API key.

### 📝 Changelog

- 0.1: Initial release.

### 🆘 Support

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

### 🔗 Other actors

- [TikTok Transcript Scraper ↗](https://apify.com/maximedupre/tiktok-transcript-scraper) - Extract public TikTok transcripts, subtitle formats, and video metadata.
- [TikTok Keywords Discovery Tool ↗](https://apify.com/maximedupre/tiktok-keywords-discovery-tool) - Collect TikTok autocomplete keyword suggestions from seed terms.
- [Telegram Media Downloader ↗](https://apify.com/maximedupre/telegram-media-downloader) - Get media URLs and post data from public Telegram posts and channels.
- [SoundCloud Scraper ↗](https://apify.com/maximedupre/soundcloud-scraper) - Export public SoundCloud tracks, artists, playlists, albums, and comments.
- [YouTube Channel Scraper ↗](https://apify.com/maximedupre/youtube-channel-scraper) - Collect public YouTube channel profiles and recent video rows.

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

# Actor input Schema

## `videoUrls` (type: `array`):

Paste public TikTok video links. Desktop, mobile, and short video links are accepted. Profile, hashtag, search, comment, and private video URLs are not supported.

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

Maximum number of downloaded media files to save across this run. Keep the default for a small test before adding a larger URL list.

## `mediaMode` (type: `string`):

Choose whether to download the TikTok video file, the audio track, or both files for each URL.

## `quality` (type: `string`):

Choose the best available video, a balanced default, or the smallest available variant. Audio downloads use TikTok's exposed audio track.

## Actor input object example

```json
{
  "videoUrls": [
    {
      "url": "https://www.tiktok.com/@apifytech/video/7398101551744552225"
    }
  ],
  "maxItems": 25,
  "mediaMode": "video",
  "quality": "balanced"
}
```

# Actor output Schema

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

Open the dataset with downloaded TikTok video or audio files and their metadata.

# 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 = {
    "videoUrls": [
        {
            "url": "https://www.tiktok.com/@apifytech/video/7398101551744552225"
        }
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maximedupre/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 = { "videoUrls": [{ "url": "https://www.tiktok.com/@apifytech/video/7398101551744552225" }] }

# Run the Actor and wait for it to finish
run = client.actor("maximedupre/tiktok-video-downloader").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "videoUrls": [
    {
      "url": "https://www.tiktok.com/@apifytech/video/7398101551744552225"
    }
  ]
}' |
apify call maximedupre/tiktok-video-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=maximedupre/tiktok-video-downloader",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "TikTok Video Downloader",
        "description": "Download videos and audio from public TikTok video URLs. Save each media file to Apify storage with source links, author data, captions, file metadata, and dataset exports.",
        "version": "0.1",
        "x-build-id": "apeuugTRUNqadY4ws"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/maximedupre~tiktok-video-downloader/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-maximedupre-tiktok-video-downloader",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/maximedupre~tiktok-video-downloader/runs": {
            "post": {
                "operationId": "runs-sync-maximedupre-tiktok-video-downloader",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/maximedupre~tiktok-video-downloader/run-sync": {
            "post": {
                "operationId": "run-sync-maximedupre-tiktok-video-downloader",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "required": [
                    "videoUrls"
                ],
                "properties": {
                    "videoUrls": {
                        "title": "TikTok video URLs",
                        "minItems": 1,
                        "maxItems": 500,
                        "type": "array",
                        "description": "Paste public TikTok video links. Desktop, mobile, and short video links are accepted. Profile, hashtag, search, comment, and private video URLs are not supported.",
                        "items": {
                            "type": "object",
                            "required": [
                                "url"
                            ],
                            "properties": {
                                "url": {
                                    "type": "string",
                                    "title": "URL of a web page",
                                    "format": "uri"
                                }
                            }
                        }
                    },
                    "maxItems": {
                        "title": "Media item limit",
                        "minimum": 1,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "Maximum number of downloaded media files to save across this run. Keep the default for a small test before adding a larger URL list.",
                        "default": 25
                    },
                    "mediaMode": {
                        "title": "Media type",
                        "enum": [
                            "video",
                            "audio",
                            "both"
                        ],
                        "type": "string",
                        "description": "Choose whether to download the TikTok video file, the audio track, or both files for each URL.",
                        "default": "video"
                    },
                    "quality": {
                        "title": "Video quality",
                        "enum": [
                            "best",
                            "balanced",
                            "small"
                        ],
                        "type": "string",
                        "description": "Choose the best available video, a balanced default, or the smallest available variant. Audio downloads use TikTok's exposed audio track.",
                        "default": "balanced"
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
