# TikTok Video, Audio & Cover Downloader (`nimbryxo-studio/tiktok-video-audio-and-cover-downloader`) Actor

Download TikTok videos, cover thumbnails, background audio, and slideshow images by post URL, with quality selection and a stable download link per file.

- **URL**: https://apify.com/nimbryxo-studio/tiktok-video-audio-and-cover-downloader.md
- **Developed by:** [Nimbryxo-studio](https://apify.com/nimbryxo-studio) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.49 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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, Audio & Cover Downloader

Download TikTok video files, cover thumbnails, background audio, and slideshow images by URL. The actor stores each file in Apify's Key-Value Store and returns a stable download URL per asset. Supports quality selection (best, 720p, 540p, 360p, smallest) and a configurable filename template. No TikTok account or cookies are required.

### What this actor does

- Accepts TikTok video and photo post URLs or bare numeric post IDs as input (duplicates are processed once)
- Downloads the selected asset types (video, cover image, audio, slideshow frames) per post
- Stores each file in the run's Key-Value Store and emits one dataset row per downloaded asset; assets that can't be found or downloaded get no row
- Supports quality selection for video downloads: best, 720p, 540p, 360p, or smallest
- Returns file metadata including dimensions, byte size, codec, and bitrate where available
- Allows a custom filename template with `{postId}`, `{type}`, `{ordinal}`, and `{ext}` placeholders
- Processes each URL sequentially to avoid rate limiting
- Empty fields are omitted

### Output per asset

- `postId` — unique TikTok video ID
- `postUrl` — canonical TikTok post URL
- `assetType` — type of asset: `video`, `cover`, `audio`, or `image`
- `ordinal` — index of the asset within its type: the frame number for slideshow images, `0` for everything else
- `kvsKey` — Key-Value Store key used to store the file (built from `filenameTemplate`, with characters other than letters, digits, `.`, `_` and `-` replaced by `_`)
- `kvsUrl` — stable Apify Key-Value Store URL to download the file
- `mimeType` — MIME type the file is stored with: `video/mp4`, `audio/mpeg`, or `image/jpeg` for covers and slideshow images
- `byteSize` — file size in bytes
- `width` — pixel width (video and slideshow image assets)
- `height` — pixel height (video and slideshow image assets)
- `duration` — duration in seconds (video and audio assets)
- `codecType` — video codec identifier (e.g. `h264`), video only
- `bitrate` — video bitrate in bps, video only
- `gearName` — TikTok quality tier label of the chosen video file (e.g. `normal`, `adapt`), present when TikTok offered a list of quality options
- `definition` — TikTok's video definition label (e.g. `normal`, `high`), when exposed separately from `gearName`
- `downloadedAt` — ISO 8601 timestamp when the file was saved to the store

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `postUrls` | array of strings | — | TikTok post URLs to download, such as `tiktok.com/@user/video/ID`, `/photo/ID`, `/video/ID`, `/v/ID` or `/embed/v2/ID`, or bare numeric IDs. Short `vm.tiktok.com`/`vt.tiktok.com` links are not recognized and are skipped. |
| `postIds` | array of strings | — | Numeric TikTok post IDs (alternative to `postUrls`; both lists can be combined). |
| `assetTypes` | array of strings | `["video", "cover"]` | Asset types to download per post: `video`, `images` (slideshow frames), `audio`, `cover`. |
| `preferredQuality` | string | `"best"` | Target video quality: `best`, `720p`, `540p`, `360p`, or `smallest`. |
| `filenameTemplate` | string | `"{postId}_{type}_{ordinal}.{ext}"` | Template for Key-Value Store keys. Placeholders: `{postId}`, `{type}`, `{ordinal}`, `{ext}`. |

#### Example: Download video and cover thumbnail

```json
{
  "postUrls": ["https://www.tiktok.com/@khaby.lame/video/7574844184952081686"],
  "assetTypes": ["video", "cover"],
  "preferredQuality": "best"
}
```

#### Example: Cover thumbnails only (lightweight)

```json
{
  "postUrls": [
    "https://www.tiktok.com/@khaby.lame/video/7574844184952081686",
    "https://www.tiktok.com/@natgeo/video/7341234567890123456"
  ],
  "assetTypes": ["cover"]
}
```

#### Example: Download at 540p to save storage

```json
{
  "postUrls": ["https://www.tiktok.com/@bbcnews/video/7395279524742083872"],
  "assetTypes": ["video"],
  "preferredQuality": "540p",
  "filenameTemplate": "{postId}_video_{ordinal}.{ext}"
}
```

#### Example: Download slideshow images and audio

```json
{
  "postUrls": ["https://www.tiktok.com/@somecreator/video/7123456789012345678"],
  "assetTypes": ["images", "audio"]
}
```

### Use cases

- **Content archiving** — preserve brand or creator content before it is deleted or made private
- **Ad creative libraries** — download competitor or inspiration videos for internal review and benchmarking
- **Thumbnail pipelines** — bulk-collect cover images for visual classification, brand consistency audits, or moderation workflows
- **Media production** — pull background music tracks (`audio` asset type) from viral TikTok sounds for licensing research
- **Dataset building** — compile labeled video/image datasets for computer vision or multimodal ML training

### FAQ

**Q: Do I need a TikTok account or cookies?**\
A: No. The actor downloads publicly available TikTok videos without any authentication.

**Q: How long are the download URLs valid?**\
A: Files are stored in the run's default Key-Value Store, and `kvsUrl` works for as long as Apify keeps that run's storage (unnamed storages are removed after your plan's retention period). Download the files to your own storage if you need them for longer.

**Q: What is the difference between `video` and `images` asset types?**\
A: `video` downloads the standard MP4 file for regular video posts. `images` downloads individual frames from TikTok slideshow (photo carousel) posts, one row per frame. Regular video posts do not produce `image` rows.

**Q: What does `preferredQuality` do exactly?**\
A: When TikTok offers several encodings of a video, the actor picks the one whose quality-tier label contains the requested resolution (e.g. `720`), or the highest/lowest bitrate for `best`/`smallest`. If no entry matches the label, it falls back to the highest-bitrate entry, same as `best`. When TikTok offers no list of encodings, the single available file is downloaded regardless of this setting.

**Q: What if a URL fails to download?**\
A: Failed downloads do not block other URLs — the actor moves on to the next post. A post that produces no assets simply has no rows in the dataset rather than an error row, so check your input list against the dataset's distinct `postId` values to see which posts didn't come through. Inputs that aren't recognized as a TikTok post are skipped the same way.

**Q: Are short TikTok URLs (vm.tiktok.com, vt.tiktok.com) supported?**\
A: No. Open the short link in a browser and paste the full `tiktok.com/@user/video/ID` address, or just the numeric ID, instead.

**Q: Can I download multiple posts in one run?**\
A: Yes. Pass as many URLs as needed in the `postUrls` array. Posts are processed sequentially.

**Q: What filename template should I use for slideshow images?**\
A: Keep `{ordinal}` in the template (the default does) so each frame gets a unique, ordered key; without it, frames of the same post overwrite each other in the store.

**Q: Is this affiliated with TikTok?**\
A: No. It is an independent tool that downloads publicly available TikTok media and is not run or endorsed by TikTok. Only download content you have the right to use.

# Actor input Schema

## `postUrls` (type: `array`):

TikTok post URLs to download (e.g. https://www.tiktok.com/@user/video/123). Accepts full URLs, short URLs, and bare numeric IDs.

## `postIds` (type: `array`):

Numeric TikTok post IDs as strings (alternative to postUrls).

## `assetTypes` (type: `array`):

Which assets to download per post. 'video' = MP4 file, 'images' = slideshow frames, 'audio' = background music MP3, 'cover' = thumbnail JPEG.

## `preferredQuality` (type: `string`):

Target video quality. 'best' = highest bitrate. '720p', '540p', '360p' = closest match from bitrateInfo. 'smallest' = lowest bitrate.

## `filenameTemplate` (type: `string`):

KVS key template. Placeholders: {postId}, {type}, {ordinal}, {ext}. Example: {postId}*{type}*{ordinal}.{ext}

## Actor input object example

```json
{
  "postUrls": [
    "https://www.tiktok.com/@khaby.lame/video/7574844184952081686"
  ],
  "assetTypes": [
    "cover"
  ],
  "preferredQuality": "best",
  "filenameTemplate": "{postId}_{type}_{ordinal}.{ext}"
}
```

# Actor output Schema

## `posts` (type: `string`):

Dataset containing TikTok post download links and 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 = {
    "postUrls": [
        "https://www.tiktok.com/@khaby.lame/video/7574844184952081686"
    ],
    "assetTypes": [
        "cover"
    ],
    "preferredQuality": "best",
    "filenameTemplate": "{postId}_{type}_{ordinal}.{ext}"
};

// Run the Actor and wait for it to finish
const run = await client.actor("nimbryxo-studio/tiktok-video-audio-and-cover-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 = {
    "postUrls": ["https://www.tiktok.com/@khaby.lame/video/7574844184952081686"],
    "assetTypes": ["cover"],
    "preferredQuality": "best",
    "filenameTemplate": "{postId}_{type}_{ordinal}.{ext}",
}

# Run the Actor and wait for it to finish
run = client.actor("nimbryxo-studio/tiktok-video-audio-and-cover-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 '{
  "postUrls": [
    "https://www.tiktok.com/@khaby.lame/video/7574844184952081686"
  ],
  "assetTypes": [
    "cover"
  ],
  "preferredQuality": "best",
  "filenameTemplate": "{postId}_{type}_{ordinal}.{ext}"
}' |
apify call nimbryxo-studio/tiktok-video-audio-and-cover-downloader --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,nimbryxo-studio/tiktok-video-audio-and-cover-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/dslkxaZlYGt90DdOe/builds/mzw961qgVn2Qt8P5r/openapi.json
