# TikTok Scraper - Videos & Users (`thirdwatch/tiktok-scraper`) Actor

Scrape TikTok videos by keyword or username. Get video details, engagement stats (views, likes, shares), author info, music, and hashtags. No login required.

- **URL**: https://apify.com/thirdwatch/tiktok-scraper.md
- **Developed by:** [Thirdwatch](https://apify.com/thirdwatch) (community)
- **Categories:** Social media, News
- **Features:** Limited permissions
- **Stats:** 83 total users, 1 monthly users, 100.0% runs succeeded, 2 bookmarks
- **User rating**: No ratings yet

## Pricing

from $2.70 / 1,000 results

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 Scraper

> **Thirdwatch portfolio:** 8,800+ users across 140+ public Actors, 2M+ records delivered, >95% run success. [Explore all Thirdwatch Actors](https://apify.com/thirdwatch).

> Find TikTok videos and user profiles by keyword or handle — descriptions, public engagement counts, creator info, music, and tags.

### What you get

Structured video and user data without a login, collected without a browser, so runs default to 256 MB and finish in seconds. `@username` queries list the creator's latest videos from TikTok's own embed page (plus a public index for deeper history) and read every video's public page for exact view, like, comment, share and bookmark counts. `#hashtag` queries start from TikTok's hashtag embed listing; keyword and creator searches use a public index for discovery, then hydrate each hit from TikTok's page state. Fallback rows are labeled explicitly instead of presenting unavailable engagement as real zeroes.

### Output fields (videos)

| Field | Description |
|-------|-------------|
| `id` | TikTok video ID |
| `description` | Video caption |
| `url` | Direct link to the video |
| `authorName` | Creator display name |
| `authorUsername` | Creator handle (without `@`) |
| `authorUrl` | Profile URL |
| `authorFollowers` | Creator follower count |
| `authorVerified` | Verified-creator flag |
| `viewCount` | Number of views |
| `likeCount` | Number of likes |
| `commentCount` | Number of comments |
| `shareCount` | Number of shares |
| `bookmarkCount` | Number of saves |
| `duration` | Video duration in seconds |
| `createdAt` | ISO 8601 upload timestamp |
| `musicTitle` | Audio/music title |
| `musicAuthor` | Audio/music artist |
| `thumbnailUrl` | Thumbnail image URL |
| `hashtags` | Hashtags extracted from the caption |
| `isAd` | Paid-promotion flag |
| `dataSource` | Which public index produced this row — useful when auditing coverage gaps |
| `dataQuality` | `full_video`, `partial_indexed_engagement`, `partial_tiktok_page`, or `discovery_only` |
| `engagementAvailable` | `true` only when public engagement metrics were actually available |

### Output fields (users)

| Field | Description |
|-------|-------------|
| `id` | TikTok user ID |
| `username` | Handle |
| `nickname` | Display name |
| `url` | Profile URL |
| `bio` | Profile biography |
| `verified` | Verified flag |
| `followers` | Follower count |
| `following` | Following count |
| `likes` | Total likes received |
| `videoCount` | Number of posted videos |
| `avatarUrl` | Profile picture URL |

### Example output

```json
{
    "id": "7345678901234567890",
    "description": "Easy 15-minute pasta recipe #cooking #recipe #foodtok",
    "url": "https://www.tiktok.com/@chefmike/video/7345678901234567890",
    "authorName": "Chef Mike",
    "authorUsername": "chefmike",
    "authorFollowers": 1250000,
    "authorVerified": true,
    "viewCount": 8500000,
    "likeCount": 425000,
    "commentCount": 3200,
    "shareCount": 18000,
    "bookmarkCount": 95000,
    "duration": 47,
    "createdAt": "2026-03-15T14:30:00Z",
    "musicTitle": "original sound",
    "musicAuthor": "Chef Mike",
    "hashtags": ["cooking", "recipe", "foodtok"],
    "isAd": false
}
```

### Input parameters

| Parameter | Required | Description |
|-----------|----------|-------------|
| `queries` | Yes | List of search terms, `@usernames`, or `#hashtags`. Examples: `["cooking", "@gordonramsay", "#recipe"]`. |
| `searchType` | No | `videos` or `users`. Default `videos`. |
| `maxResults` | No | Max total results across all queries. Default `8`. |
| `maxResultsPerQuery` | No | Max results per individual query. Default `50`. |
| `liveEnrichment` | No | Takes a slower second pass only for rows the standard pass could not complete. Default `false`; select at least 2048 MB memory when enabled (the default 256 MB is enough when this is off). |
| `sortBy` | No | For `@username` video queries: `default` keeps TikTok's own order (pinned posts may come first); `newest` picks the most recent uploads before the result limit is applied. Hashtag and keyword queries are unaffected. Default `default`. |
| `downloadVideos` | No | Save each video's MP4 (up to 25 MiB) to the run's key-value store. Adds download status and file details to matching rows; a failed download never drops the video's metadata. Video searches only. Default `false`. |
| `maxAgeDays` | No | Only keep videos with a known publication date within this many days. `0` disables the filter. Default `0`. |

### Use cases

- **Influencer research**: Follower counts, engagement rates, and posting cadence for any creator.
- **Competitor tracking**: Growth and top-performing content for a roster of competitor accounts.
- **Trend monitoring**: Pull hashtag and keyword feeds to surface viral content early.
- **Brand monitoring**: Find videos mentioning your brand, product, or category.
- **Partnership discovery**: Discover creators in a niche for brand deals.
- **Market research**: Analyze audience behavior across topics and formats.

### Use cases & recipes

Step-by-step guides on [thirdwatch.dev/blog](https://thirdwatch.dev/blog):

- [Monitor Brand TikTok Presence (2026 Guide)](https://thirdwatch.dev/blog/monitor-brand-tiktok-presence)
- [Research TikTok Creator Engagement (2026 Guide)](https://thirdwatch.dev/blog/research-tiktok-creator-engagement)
- [Scrape TikTok Profiles and Videos at Scale (2026)](https://thirdwatch.dev/blog/scrape-tiktok-profiles-and-videos)
- [Track TikTok Trending Content by Hashtag (2026)](https://thirdwatch.dev/blog/track-tiktok-trending-content-by-hashtag)

### Limitations

- Private accounts cannot be scraped.
- Video media URLs are short-lived and may expire shortly after extraction.
- Very new or low-engagement videos may have incomplete metadata.
- A creator's newest ~10 videos come straight from TikTok; anything beyond that is discovered through a public index, which can lag TikTok and returns older videos in index order rather than newest-first.
- When exact-page hydration is blocked, the row is retained as `dataQuality: "discovery_only"` (index hit) or `"partial_embed"` (embed listing, rounded view count only) with `engagementAvailable: false`; unavailable numeric metrics are not evidence of zero engagement.
- Rate limits apply on heavy runs — spread large jobs across queries.

### Compared to alternatives

- **vs. clockworks/tiktok-scraper** ($0.0037/result, 156K users): That actor is cheaper with a broader surface area. This actor keeps the schema tight and consistent across video and user search and is maintained on a predictable release cadence.

Pairs well with [Instagram Scraper](https://apify.com/thirdwatch/instagram-scraper?fpr=9m2cd6) and [YouTube Scraper](https://apify.com/thirdwatch/youtube-scraper?fpr=9m2cd6) for cross-platform creator research.

### FAQ

**Can I scrape a specific creator's videos?**
Yes. Prefix the handle with `@` in `queries` (e.g., `@gordonramsay`). Switch `searchType` to `videos` for their video feed or `users` for the profile record.

**Does hashtag search work?**
Yes. Prefix the term with `#` (e.g., `#recipe`) and use `searchType: "videos"`.

**Are view counts accurate in real time?**
Counts are taken from the public source selected for the run. Use `engagementAvailable` and `dataQuality` to distinguish complete live rows from index-only discovery rows.

**Do I need an API key or login?**
No.

Last verified: 2026-07

More scrapers at [thirdwatch.dev](https://thirdwatch.dev).

# Actor input Schema

## `queries` (type: `array`):

List of search terms, @usernames, or hashtags to scrape. Examples: 'cooking', '@gordonramsay', '#recipe'.

## `searchType` (type: `string`):

Type of search to perform.

## `maxResults` (type: `integer`):

Maximum total results across all queries.

## `maxResultsPerQuery` (type: `integer`):

Maximum results per individual query.

## `liveEnrichment` (type: `boolean`):

Try live TikTok pages for indexed videos missing engagement. Requires selecting at least 2048 MB memory for the run; slower and more expensive.

## `sortBy` (type: `string`):

For @username video queries: 'Default' keeps TikTok's order (pinned posts may come first); 'Newest' picks the most recent uploads before applying the result limit. Hashtags and keywords are unaffected.

## `downloadVideos` (type: `boolean`):

Save each video's MP4 (up to 25 MiB) to the run's default key-value store under video-{id}.mp4. Rows gain videoDownloadStatus plus videoStorageKey, videoStorageId, videoByteLength and videoSha256 on success, or videoDownloadError on failure. A failed download never drops the video's metadata. Video searches only.

## `maxAgeDays` (type: `integer`):

Only keep videos with a known publication date within this many days. 0 disables the filter. Collection time is never used as publication time.

## Actor input object example

```json
{
  "queries": [
    "cooking"
  ],
  "searchType": "videos",
  "maxResults": 8,
  "maxResultsPerQuery": 25,
  "liveEnrichment": false,
  "sortBy": "default",
  "downloadVideos": false,
  "maxAgeDays": 0
}
```

# Actor output Schema

## `results` (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 = {
    "queries": [
        "cooking"
    ],
    "searchType": "videos",
    "maxResults": 8,
    "maxResultsPerQuery": 25
};

// Run the Actor and wait for it to finish
const run = await client.actor("thirdwatch/tiktok-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 = {
    "queries": ["cooking"],
    "searchType": "videos",
    "maxResults": 8,
    "maxResultsPerQuery": 25,
}

# Run the Actor and wait for it to finish
run = client.actor("thirdwatch/tiktok-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 '{
  "queries": [
    "cooking"
  ],
  "searchType": "videos",
  "maxResults": 8,
  "maxResultsPerQuery": 25
}' |
apify call thirdwatch/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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