# TikTok Video Downloader: No Watermark MP4, Cover, Audio (`memo23/tiktok-video-downloader`) Actor

Download TikTok videos without the watermark, in bulk. Get stable Apify-hosted MP4, cover image, audio track and slideshow files. TikTok's own links need exact headers and die after 48 hours; these need neither. Takes post URLs, share links or IDs. No login, no cookies.

- **URL**: https://apify.com/memo23/tiktok-video-downloader.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Videos, Social media, AI
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.00 / 1,000 posts

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/platform/actors/running/actors-in-store#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 Video Downloader

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/tiktok-downloader-logo.png" width="140" alt="TikTok Video Downloader"></p>

Download TikTok videos **without the watermark** and get back a link that actually works.

Paste TikTok post URLs, share links or IDs. The Actor fetches the real media files — video, cover image, audio track, slideshow images — and re-hosts them on Apify, so what you get back is a plain URL you can open, embed or hand to any downstream tool.

### Why Use This Scraper?

Most "TikTok downloader" tools return TikTok's own signed CDN link. That link is close to useless on its own, and here is exactly why (measured, not guessed):

- **Fetched without the right headers, it answers HTTP 403.** TikTok's video CDN requires an exact `Referer` / `Origin` / `Cookie` set. Paste the link into a browser and you get an error — and because the 403 body still carries a `video/mp4` content-type, naive tools report it as a successful download.
- **It expires in 48 hours.** The link carries an `expire` timestamp exactly two days out. Any workflow that stores those links is storing dead links.

This Actor does the fetch for you, with the correct headers, inside the run. You get a stable Apify-hosted file instead of a booby-trapped link. Cover images and audio are re-hosted the same way.

### Overview

One row per post, with a direct file URL for every asset you asked for. Video, cover, audio and slideshow images are each optional, so you only pay for and wait on what you need. No login, no cookies, no account risk.

### Supported Inputs

Any mix of these, in one run:

| Input | Example |
|---|---|
| Full post URL | `https://www.tiktok.com/@tiktok/video/7106594312292453675` |
| Short share link | `https://vm.tiktok.com/ZMabcdefg/` |
| `vt.` share link | `https://vt.tiktok.com/ZSabcdefg/` |
| Embed URL | `https://www.tiktok.com/embed/v2/7106594312292453675` |
| Bare numeric ID | `7106594312292453675` |

Share links are resolved by following the redirect, which costs nothing extra.

### Use Cases

- **Content archiving** — keep a durable copy of your own posts before they are edited or removed
- **Ad and creative research** — build a swipe file of competitor videos that does not rot in two days
- **Sound and music analysis** — pull audio tracks separately for trend and attribution work
- **Video editing and repurposing** — clean, watermark-free source files for licensed re-cuts
- **Dataset building** — feed real MP4s into transcription, vision or moderation pipelines
- **Thumbnail and cover studies** — collect cover images at full resolution

### How It Works

<p align="center"><img src="https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-tiktok-downloader.png" width="900" alt="How the TikTok Video Downloader works"></p>

1. Every input is normalized to a numeric post ID; short links are resolved by redirect.
2. One upstream call fetches the post's full media object — metadata, cover, audio and slideshow images.
3. When a video is requested, a second call returns the signed source link **plus the exact headers it requires**.
4. The Actor fetches the bytes itself with those headers, checks the response is real media rather than an error page, and writes it to the run's key-value store.
5. Each post becomes one dataset row with both the Apify file URL and the original source URL.

### Input Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `posts` | array | — | **Required.** TikTok post URLs, share links or IDs. |
| `downloadVideo` | boolean | `true` | Fetch the MP4 and re-host it. |
| `removeWatermark` | boolean | `true` | Get the clean source file with no watermark or username overlay. |
| `downloadCover` | boolean | `true` | Save the thumbnail as a JPEG. |
| `downloadMusic` | boolean | `false` | Save the sound as a separate audio file. |
| `downloadSlideshowImages` | boolean | `true` | For photo posts, save every image in the set. |
| `storeFiles` | boolean | `true` | Off returns source URLs only — no files, no re-hosting. |
| `maxFileSizeMb` | integer | `100` | Skip files larger than this instead of downloading them. |

#### Minimal input

```json
{
  "posts": ["https://www.tiktok.com/@tiktok/video/7106594312292453675"]
}
```

#### Audio-only input

```json
{
  "posts": ["https://www.tiktok.com/@tiktok/video/7106594312292453675"],
  "downloadVideo": false,
  "downloadCover": false,
  "downloadMusic": true
}
```

### Output Overview

One dataset row per post, plus the actual files in the run's key-value store. Posts that cannot be delivered yield a single error item rather than failing the run.

### Output Samples

#### Video post

```json
{
  "postId": "7666239218879941896",
  "postUrl": "https://www.tiktok.com/@kittensklout/video/7666239218879941896",
  "postType": "video",
  "caption": "soo cute #catsoftiktok #cat #cute #kitten #fyp",
  "createdAt": "2026-07-24T23:23:39.000Z",
  "durationSeconds": 26,
  "authorUsername": "kittensklout",
  "authorNickname": "kloutkittens",
  "authorVerified": false,
  "playCount": 14400000,
  "likeCount": 3300000,
  "commentCount": 11100,
  "shareCount": 869700,
  "musicTitle": "cats in the cold",
  "musicAuthor": "mage tears",
  "videoSourceUrl": "https://v16-webapp-prime.tiktok.com/video/tos/alisg/...",
  "videoSourceExpiresAt": "2026-08-20T09:01:26.000Z",
  "watermarkRemoved": true,
  "videoUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/7666239218879941896-video.mp4",
  "videoBytes": 824307,
  "coverSourceUrl": "https://p16-common-sign.tiktokcdn-us.com/...",
  "coverUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/7666239218879941896-cover.jpg",
  "musicSourceUrl": "https://sf16.tiktokcdn-us.com/obj/...",
  "musicUrl": "https://api.apify.com/v2/key-value-stores/<storeId>/records/7666239218879941896-audio.m4a",
  "scrapedAt": "2026-08-18T09:01:02.405Z"
}
```

#### Unavailable post

```json
{
  "post": "not-a-tiktok-url",
  "error": "invalid_post",
  "message": "\"not-a-tiktok-url\" is not a TikTok post URL or ID."
}
```

### Key Output Fields

| Field | Description |
|---|---|
| `videoUrl` | Apify-hosted MP4. No headers required, no 48-hour expiry. |
| `videoSourceUrl` | TikTok's original signed link — needs exact headers, dies in 48 h. |
| `videoSourceExpiresAt` | When that source link stops working, parsed from the link itself. |
| `videoBytes` | Size of the downloaded file, so you can verify you got real media. |
| `watermarkRemoved` | Whether the clean source file was requested. |
| `coverUrl` / `musicUrl` | Apify-hosted thumbnail and audio track. |
| `imageUrls` | Apify-hosted images for slideshow posts, in order. |
| `postType` | `video` or `slideshow`. |
| `error` / `message` | Present only on rows for posts that could not be delivered. |

### FAQ

**Do I need a TikTok login or cookies?**
No. Nothing is ever logged in, and no account of yours is touched.

**Is the video really watermark-free?**
Yes — `removeWatermark` (on by default) requests the clean source file, not the shared copy with the overlay.

**How long do the Apify file links last?**
As long as the run's key-value store, which follows your Apify account's data-retention setting. That is far longer than the 48 hours TikTok's own links survive, but it is not literally forever — copy files to your own storage if you need permanent archives.

**Can I get just the link and skip the download?**
Yes — set `storeFiles` to `false`. You will get `videoSourceUrl` and nothing re-hosted. Remember it needs exact headers and expires.

**What about photo and slideshow posts?**
They have no video file. Every image in the set is downloaded instead, in order.

**What happens with private or deleted posts?**
You get one error item explaining why, and the run still succeeds.

**What does it cost?**
Pay per result: one charge per post delivered, a small add-on when a video file is actually downloaded, plus a small per-run start fee. Error items are the only thing a failed target ever costs you. No subscription.

### Support

Found a bug or need a field added? Open an issue on the Actor's **Issues** tab in Apify Console, or email <muhamed.didovic@gmail.com>.

### Additional Services

Need a custom TikTok or social-media scraper, enrichment pipeline, or a private version of this Actor? Custom builds available — reach out at <muhamed.didovic@gmail.com>.

### Explore More Scrapers

- **[TikTok Post Scraper](https://apify.com/memo23/tiktok-post-scraper)** — full metadata and engagement for any post
- **[TikTok Transcript Scraper](https://apify.com/memo23/tiktok-transcript-scraper)** — transcripts and subtitles from any video, every language
- **[TikTok Comments Scraper](https://apify.com/memo23/tiktok-comments-scraper)** — every comment on any video, deduplicated, with commenter profiles
- **[TikTok Profile Scraper](https://apify.com/memo23/tiktok-profile-scraper)** — profile details and stats for any account
- **[TikTok Search Scraper](https://apify.com/memo23/tiktok-search-scraper)** — TikTok's ranked search results for any keyword

Browse the full portfolio: [muhamed-didovic.github.io](https://muhamed-didovic.github.io/)

### 🤖 For AI Agents & LLM Apps

**Purpose:** Download the actual media files behind public TikTok posts — watermark-free MP4, cover image, audio track, slideshow images — and return stable URLs that require no request headers.

**Minimal tested input:**

```json
{ "posts": ["https://www.tiktok.com/@tiktok/video/7106594312292453675"] }
```

**Output:** array of flat objects, one per post. Core fields: `postId`, `postUrl`, `postType`, `caption`, `createdAt`, `durationSeconds`, `authorUsername`, `authorNickname`, `authorVerified`, `playCount`, `likeCount`, `commentCount`, `shareCount`, `musicTitle`, `musicAuthor`, `scrapedAt`. Per enabled toggle: `videoUrl`, `videoSourceUrl`, `videoSourceExpiresAt`, `videoBytes`, `watermarkRemoved`, `coverUrl`, `coverSourceUrl`, `musicUrl`, `musicSourceUrl`, `imageUrls[]`, `imageSourceUrls[]`.

**Critical for agents:** use `videoUrl`, not `videoSourceUrl`. The source URL returns HTTP 403 without an exact `Referer`/`Origin`/`Cookie` header set, and expires 48 hours after the run. The 403 body is served with a `video/mp4` content-type, so check the byte length — anything under ~1 KB is an error page, not a file.

**Behavior & billing:** Pay-per-event — one charge per post, plus an add-on when a video file is downloaded. Private/deleted/invalid posts and unresolvable share links yield one error item each (`error`, `message`) instead of failing the run. No login or cookies required.

### ⚠️ Disclaimer

This Actor accesses publicly available content on TikTok for legitimate research, archiving, and business-analysis purposes. It does not log in, bypass authentication, or access private content. Use of this Actor must comply with TikTok's Terms of Service and all applicable laws, including data-protection and copyright law. The authors are not responsible for any misuse. Users must:

- Respect rate limits and avoid overloading TikTok's infrastructure
- Not use downloaded media to violate user privacy or platform terms
- Process any personal data only with a lawful basis and in compliance with their jurisdiction
- **Not republish, redistribute or monetize downloaded videos without the rights to do so** — downloading a video does not grant you a licence to it

Downloaded files are written to **your own** Apify key-value store and returned to you; the authors neither retain nor receive a copy. TikTok is a trademark of ByteDance Ltd.; this Actor is not affiliated with or endorsed by TikTok or ByteDance.

### SEO Keywords

tiktok video downloader, tiktok downloader no watermark, download tiktok video, tiktok mp4 download, tiktok video download api, remove tiktok watermark, tiktok audio download, tiktok sound downloader, tiktok cover image download, tiktok slideshow downloader, tiktok photo download, save tiktok video, tiktok bulk downloader, tiktok video archive, download tiktok without watermark api, tiktok media downloader, tiktok content archiving, tiktok video backup, bulk download tiktok videos, tiktok downloader actor, apify tiktok downloader

# Actor input Schema

## `posts` (type: `array`):

TikTok post URLs or numeric IDs. Full links (tiktok.com/@user/video/123…), short share links (vm.tiktok.com/…, vt.tiktok.com/…) and bare IDs all work.

## `downloadVideo` (type: `boolean`):

Fetch the MP4 and re-host it on Apify. Turn this off to collect only cover images, audio or metadata.

## `removeWatermark` (type: `boolean`):

Grab the clean source file with no TikTok watermark or username overlay. Turn off to keep the watermarked version.

## `downloadCover` (type: `boolean`):

Save the post's thumbnail as a JPEG.

## `downloadMusic` (type: `boolean`):

Save the post's sound as a separate audio file — useful for sound and music research.

## `downloadSlideshowImages` (type: `boolean`):

For photo/slideshow posts, save every image in the set.

## `storeFiles` (type: `boolean`):

On (recommended): files are fetched and served from stable Apify URLs that need no special headers. Off: only TikTok's own source links are returned — those require exact Referer/Origin/Cookie headers and expire after 48 hours.

## `maxFileSizeMb` (type: `integer`):

Files larger than this are skipped rather than downloaded. Guards against a single very long video eating the whole run.

## Actor input object example

```json
{
  "posts": [
    "https://www.tiktok.com/@tiktok/video/7106594312292453675"
  ],
  "downloadVideo": true,
  "removeWatermark": true,
  "downloadCover": true,
  "downloadMusic": false,
  "downloadSlideshowImages": true,
  "storeFiles": true,
  "maxFileSizeMb": 100
}
```

# Actor output Schema

## `downloads` (type: `string`):

All download rows (one per post) in the default dataset.

## `files` (type: `string`):

The key-value store holding every downloaded video, cover, audio track and image.

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

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

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

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,memo23/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/pQGdDfhFC35QToTxZ/builds/3gK8Aa0Lg0fKWoDjm/openapi.json
