# TikTok Post Scraper — Video & Slideshow Data by URL or ID (`memo23/tiktok-post-scraper`) Actor

Scrape any TikTok post by URL or ID — caption, play/like/comment/share/save/repost counts, author + follower stats, hashtags, mentions, music, and downloadable video/image URLs. No login or cookies. JSON, CSV, Excel.

- **URL**: https://apify.com/memo23/tiktok-post-scraper.md
- **Developed by:** [Muhamed Didovic](https://apify.com/memo23) (community)
- **Categories:** Social media, AI, Agents
- **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 Post Scraper

Get the **complete data behind any public TikTok post** — video or photo slideshow — from a URL or ID. Caption, every engagement count (views, likes, comments, shares, saves, reposts), the author's profile and follower stats, hashtags, mentions, music, and downloadable video / image / cover URLs. No login, no cookies, no browser.

![How it works](https://raw.githubusercontent.com/muhamed-didovic/muhamed-didovic.github.io/main/assets/how-it-works-tiktok-post.png)

### Why Use This Scraper?

- **One request, the whole post** — engagement stats, author identity, follower counts, music, hashtags, mentions, and media links all on a single row.
- **Video and slideshow** — photo carousels return their image URLs; videos return play + download URLs. The `postType` field tells them apart.
- **Downloadable media URLs** — signed CDN links for the video, cover, music, and each slideshow image, ready to fetch.
- **Hashtags & mentions that don't go missing** — pulled from TikTok's structured data, and re-parsed from the caption when TikTok omits them, so you never get an empty list on a post that clearly has tags.
- **Newest stats** — engagement is read from TikTok's `statsV2` source, including the `repostCount` older scrapers miss.
- **Bulk-friendly and honest** — mix URLs, share links, and bare IDs in one run. Private, deleted, and invalid posts yield a clear error item instead of a failed run.

### Overview

This Actor takes a list of TikTok posts and returns one structured row per post. It works with public posts only and requires no TikTok account.

### Supported Inputs

| Input form | Example |
|---|---|
| Full post URL | `https://www.tiktok.com/@nasa/video/723987198712345678` |
| Photo / slideshow URL | `https://www.tiktok.com/@user/photo/723987198712345678` |
| Share link | `https://vm.tiktok.com/ZMabc123/`, `https://vt.tiktok.com/xyz/` |
| Bare post ID | `723987198712345678` |

All forms can be mixed freely in the `posts` list.

### Use Cases

- **Influencer vetting** — pull real engagement and follower counts before paying for a placement.
- **Campaign & competitor tracking** — snapshot the stats on any set of posts over time.
- **Content archiving** — grab the downloadable video / image / cover URLs for posts you need to keep.
- **Trend research** — analyze which hashtags, sounds, and formats are driving views in your niche.
- **Datasets for AI** — structured post records for training, analytics, or RAG pipelines.
- **Ad & AIGC auditing** — the `isAd` and `isAigc` flags surface paid and AI-generated posts.

### How It Works

1. **Resolve** — every input is normalized to a numeric post ID. Share links are followed for free before any paid lookup.
2. **Extract** — the post's full record is fetched: caption, engagement, author and follower stats, music, hashtags, mentions, and media.
3. **Deliver** — one clean row per post, with downloadable media URLs, written to the dataset.

### Input Configuration

| Field | Type | Default | Description |
|---|---|---|---|
| `posts` | array | — (required) | TikTok post URLs, share links, or bare numeric IDs. |
| `includeMediaUrls` | boolean | `true` | Include downloadable video / image / cover / music URLs (signed, expire in hours). |
| `includeAuthorStats` | boolean | `true` | Include author bio, avatar, and follower / following / likes / video counts. |
| `includeHashtagsMentions` | boolean | `true` | Include hashtag and @-mention arrays parsed from the caption. |

Example input:

```json
{
    "posts": [
        "https://www.tiktok.com/@easyenglishwithfun/video/7607978879944379670",
        "https://vm.tiktok.com/ZMabc123/",
        "7673836093183151363"
    ],
    "includeMediaUrls": true,
    "includeAuthorStats": true,
    "includeHashtagsMentions": true
}
```

### Output Overview

One row per post. Posts that cannot be delivered (private, deleted, invalid) produce a single error item with a `message` explaining why — the run itself still succeeds.

### Output Samples

Post row (video, trimmed):

```json
{
    "postId": "7607978879944379670",
    "postUrl": "https://www.tiktok.com/@easyenglishwithfun/video/7607978879944379670",
    "postType": "video",
    "caption": "Simple English Conversation 💬 … #LearnEnglish #EnglishConversation",
    "createdAt": "2026-02-17T23:23:48.000Z",
    "locationCreated": "DE",
    "durationSeconds": 72,
    "playCount": 2100000,
    "likeCount": 116800,
    "commentCount": 855,
    "shareCount": 11000,
    "saveCount": 21287,
    "repostCount": 0,
    "isAd": false,
    "isAigc": false,
    "stitchEnabled": false,
    "duetEnabled": false,
    "authorId": "7353205763273376800",
    "authorUsername": "easyenglishwithfun",
    "authorNickname": "Easy English with fun",
    "authorVerified": false,
    "authorFollowerCount": 172500,
    "authorHeartCount": 533600,
    "authorVideoCount": 118,
    "hashtags": ["LearnEnglish", "EnglishConversation", "EnglishForBeginners"],
    "mentions": [],
    "musicTitle": "original sound - Easy English with fun",
    "musicAuthor": "Easy English with fun",
    "coverUrl": "https://p16-common-sign.tiktokcdn-us.com/…",
    "videoUrl": "https://v16-webapp-prime.us.tiktok.com/…",
    "videoDownloadUrl": "https://v16-webapp-prime.us.tiktok.com/…",
    "imageUrls": [],
    "scrapedAt": "2026-08-16T18:33:00.000Z"
}
```

Error item (private/deleted post):

```json
{
    "post": "7582320231775816981",
    "error": "post_unavailable",
    "message": "Post 7582320231775816981 is not available — it is private, deleted, or region-blocked."
}
```

### Key Output Fields

| Field | Meaning |
|---|---|
| `postType` | `video` or `slideshow` (photo carousel). |
| `playCount` … `repostCount` | Engagement from TikTok's `statsV2` — views, likes, comments, shares, saves, reposts. |
| `isAd` / `isAigc` | Paid advertisement / AI-generated-content flags. |
| `authorFollowerCount` … `authorVideoCount` | The author's follower, following, total-likes, and video counts. |
| `hashtags` / `mentions` | Arrays parsed from the caption (structured data first, caption text as fallback). |
| `musicTitle` / `musicAuthor` / `musicUrl` | The sound used, and its downloadable URL. |
| `videoUrl` / `videoDownloadUrl` / `coverUrl` / `imageUrls` | Signed CDN media links. Slideshows fill `imageUrls`; videos fill the video links. |
| `subtitleUrl` note | Need the spoken words too? See the **TikTok Transcript Scraper** below. |

### FAQ

**Do I need to log in or provide cookies?**
No. The Actor never touches your TikTok account and only reads public posts.

**Does it handle photo slideshows?**
Yes. Photo posts return their image URLs in `imageUrls` and are marked `postType: "slideshow"`.

**Why is a media URL not loading later?**
TikTok's media links are signed and expire after a few hours. Fetch them during or soon after the run — don't store the URL and expect it to work next week.

**What happens with a private or deleted post?**
It returns an error item explaining why, and the run continues with your other posts.

**Can I get the transcript / subtitles?**
That's a separate Actor — see [TikTok Transcript Scraper](https://apify.com/memo23/tiktok-transcript-scraper). This one returns the post's metadata and media, not the spoken text.

**What does it cost?**
Pay per result: one charge per post delivered, 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 Transcript Scraper](https://apify.com/memo23/tiktok-transcript-scraper)** — full 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 Hashtag Scraper](https://apify.com/memo23/tiktok-hashtag-scraper)** — every video posted under a hashtag
- **[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:** Return the full structured record of public TikTok posts (video or slideshow) — caption, engagement, author + follower stats, hashtags, mentions, music, and downloadable media URLs.

**Minimal tested input:**

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

**Output:** array of flat objects, one per post. Core fields: `postId`, `postUrl`, `postType`, `caption`, `createdAt`, `durationSeconds`, `playCount`, `likeCount`, `commentCount`, `shareCount`, `saveCount`, `repostCount`, `isAd`, `isAigc`, `stitchEnabled`, `duetEnabled`, `shareEnabled`, `authorId`, `authorSecUid`, `authorUsername`, `authorNickname`, `authorVerified`, `authorPrivate`, `scrapedAt`. With the default toggles on: `authorBio`, `authorAvatarUrl`, `authorFollowerCount`, `authorFollowingCount`, `authorHeartCount`, `authorVideoCount`, `hashtags[]`, `mentions[]`, `musicId`, `musicTitle`, `musicAuthor`, `coverUrl`, `musicUrl`, `videoUrl`, `videoDownloadUrl`, `imageUrls[]`.

**Behavior & billing:** Pay-per-event — one charge per post. Media URLs are signed and expire within hours. Private/deleted/invalid posts and unresolvable links yield one error item each (`error`, `message`) instead of failing the run. No login/cookies required.

### ⚠️ Disclaimer

This Actor accesses publicly available data on TikTok for legitimate research, market-intelligence, 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 regulations (GDPR, CCPA, etc.). The authors are not responsible for any misuse. Users must:

- Respect rate limits and avoid overloading TikTok's infrastructure
- Not use scraped data to violate user privacy or platform terms
- Process any personal data only with a lawful basis and in compliance with their jurisdiction
- Not republish scraped content in violation of copyright

We do not store scraped data; the Actor returns it directly to your Apify dataset for your authorized use. TikTok is a trademark of ByteDance Ltd.; this Actor is not affiliated with or endorsed by TikTok or ByteDance.

### SEO Keywords

tiktok post scraper, tiktok video scraper, scrape tiktok post, tiktok post data, tiktok video data, tiktok post api, tiktok video metadata, tiktok engagement scraper, tiktok stats scraper, tiktok video downloader url, tiktok slideshow scraper, tiktok photo post scraper, tiktok hashtag extractor, tiktok video stats, tiktok view count scraper, tiktok post export, tiktok video json, tiktok post to csv, tiktok content analysis, tiktok influencer data, tiktok video metrics, apify tiktok scraper

# Actor input Schema

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

TikTok posts to scrape. Accepts full post URLs (`https://www.tiktok.com/@user/video/123…`), photo/slideshow URLs, share links (`vm.tiktok.com/…`, `vt.tiktok.com/…`), or bare numeric post IDs — mix them freely.

## `includeMediaUrls` (type: `boolean`):

Include downloadable video / image / cover / music URLs on each row. These are signed CDN links that expire after a few hours — fetch them promptly.

## `includeAuthorStats` (type: `boolean`):

Include the author's follower / following / total-likes / video counts and profile bio on each row.

## `includeHashtagsMentions` (type: `boolean`):

Include arrays of the hashtags and @-mentions parsed from the caption.

## Actor input object example

```json
{
  "posts": [
    "https://www.tiktok.com/@damczhelga_/video/7673836093183151363"
  ],
  "includeMediaUrls": true,
  "includeAuthorStats": true,
  "includeHashtagsMentions": true
}
```

# Actor output Schema

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

All post rows (one per video/slideshow) in the default dataset.

# 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/@damczhelga_/video/7673836093183151363"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("memo23/tiktok-post-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "posts": ["https://www.tiktok.com/@damczhelga_/video/7673836093183151363"] }

# Run the Actor and wait for it to finish
run = client.actor("memo23/tiktok-post-scraper").call(run_input=run_input)

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

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

```

## CLI example

```bash
echo '{
  "posts": [
    "https://www.tiktok.com/@damczhelga_/video/7673836093183151363"
  ]
}' |
apify call memo23/tiktok-post-scraper --silent --output-dataset

```

## MCP server setup

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

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/a3fs95CeL3MQXW1uC/builds/EnuVkXWn1VaUhSeYi/openapi.json
