# TikTok Scraper - from $0.05 per 1,000 videos (`esdrasdw/tiktok-scraper`) Actor

From $0.05 per 1,000 videos. Track public TikTok profiles and hashtags day by day: views, likes, comments, shares and saves for every video, plus comment text and replies.

- **URL**: https://apify.com/esdrasdw/tiktok-scraper.md
- **Developed by:** [Esdrasdw](https://apify.com/esdrasdw) (community)
- **Categories:** Videos, Social media, SEO tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.05 / 1,000 videos

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

## 📈 Track TikTok performance, day by day

**$0.10 per 1,000 videos, and $0.05 on any paid Apify plan.** About 30x
cheaper than the usual TikTok scraper on the free plan.

A versatile, low-cost TikTok scraper for people who watch numbers: agencies,
brands, creators and analysts who want to see **how every video and every
profile evolves, day after day**. Views, likes, comments, shares and saves for
each video, exact follower counts for each profile, and the comments
themselves when you want to know what the audience is saying.

Give it a list of profiles or hashtags, run it on a schedule, and every run is a fresh
snapshot you can compare with yesterday's. No login, no cookies, no browser
automation on your side.

### Why this scraper

- 💸 **Cheap enough to run every day.** $0.10 per 1,000 videos on the free
  plan, $0.05 on paid plans. Comments and replies are $0.05 per 1,000 ($0.025 on
  paid plans), and only when you ask for them.
- 🎯 **High-quality data.** Profile numbers are exact (1,881,247 followers, not
  "1.9M"). Every video comes with the same clean, structured fields, ready for
  a spreadsheet, a dashboard or a database.
- 📈 **Built for tracking evolution.** Schedule a daily run over your profiles
  and watch views, likes, comments, shares and saves grow video by video, and
  followers and total likes grow profile by profile.
- 🧰 **Versatile.** Up to 1,000 profiles and 100 hashtags per run, newest or oldest videos first,
  any date range (for an old period of a big profile the run jumps straight to
  it), comments with their replies, reposts, and only the columns you choose.
- 🛡️ **You only pay for what you get.** Charged per video and per comment
  delivered. A run that returns nothing costs nothing, and options this Actor
  does not offer are refused before anything is collected.

### What you get

For every video: the link, the caption, hashtags and mentions, the publish
date, view, like, comment, share, save and repost counts, and three organized
blocks:

- **`authorMeta`**: the profile, with nickname, bio, bio link, avatar, verified,
  account creation date, followers, following, friends, total likes and video
  count (exact numbers, not rounded).
- **`musicMeta`**: the sound, with name, author, original or not, duration and
  cover.
- **`videoMeta`**: duration, width, height, quality, format and cover.

Photo slideshows come with every photo, and the tagged location and effects
come too. Turn on comments and each video carries its comments, each comment
carrying its replies.

You choose the columns. Keep only the fields you need and you get clean
columns instead of a wall of JSON you have to clean up later.

The layout follows the most used TikTok scraper on Apify, so switching doesn't
break your integration.

### How to use it

1. In the **Profiles** block, add profiles: a handle (`nasa`), `@nasa` or a
   profile URL (`https://www.tiktok.com/@nasa`). Set **Videos per profile** and
   pick **Sort videos by**: Latest or Oldest.
2. In the **Hashtags** block, add hashtags: `fyp`, `#fyp` or
   `https://www.tiktok.com/tag/fyp`, and set **Videos per hashtag**. Fill in
   profiles, hashtags or both.
3. Optionally, add **Reposts** under **Profile sections**.
4. Optionally, set **Comments per video** and **Replies per comment**.
5. Optionally, narrow it down under **Date range**.
6. Optionally, pick the columns under **Fields to return**.
7. Run it, then download the dataset as JSON, CSV, Excel or HTML.

### Input

| Field | Type | Default | What it does |
|---|---|---|---|
| `profiles` | array | — | Profiles to scrape: handle, `@handle` or URL (up to 1,000) |
| `hashtags` | array | — | Hashtags to scrape: `tag`, `#tag` or URL (up to 100) |
| `resultsPerHashtag` | integer | `resultsPerPage` | Videos per hashtag, from 10 to 10,000 |
| `resultsPerPage` | integer | `100` | Videos per profile, from 10 to 10,000 (a profile with fewer returns all it has); with reposts, also the maximum reposts |
| `profileSorting` | string | `latest` | Profiles: `latest` or `oldest` |
| `profileScrapeSections` | array | `["videos"]` | `videos`, `reposts`, or both |
| `commentsPerPost` | integer | `0` | Comments included with each video (up to 1,000) |
| `maxRepliesPerComment` | integer | `0` | Replies included under each comment (up to 1,000); a video carries at most 3,000 comments and replies in total |
| `oldestPostDateUnified` | string | — | Only videos published on or after this date |
| `newestPostDate` | string | — | Only videos published before this date |
| `selectedFields` | array | every field (the form pre-selects the main ones) | Which columns to return (comments always come when requested) |

Field names match the ones used by the most used TikTok profile scraper, so a
profile-based input written for that Actor works here. Handles are not
case-sensitive, and profile URLs may carry extra parts such as `?lang=en`.

At least one profile or hashtag is required.

Options this Actor does not offer (`popular` sorting, stories, search, post URLs, downloads, followers lists, likes and views filters) are
refused before anything is collected. The reason is in `OUTPUT`.

#### Pinned videos

Videos always come strictly by publish date. **Pinned videos are ignored as
pinned**: they never jump to the top of the list. A pinned video shows up at
its own date, like any other video. `excludePinnedPosts` is accepted.

#### Example input

```json
{
  "profiles": ["nasa", "khaby.lame"],
  "resultsPerPage": 50,
  "profileSorting": "latest",
  "commentsPerPost": 20
}
```

#### A profile's first videos

```json
{
  "profiles": ["zachking"],
  "resultsPerPage": 30,
  "profileSorting": "oldest"
}
```

Oldest starts at the profile's very first video, and stays fast on large
profiles.

#### Hashtags

```json
{
  "hashtags": ["footballedit", "receitasfaceis"],
  "resultsPerHashtag": 100,
  "oldestPostDateUnified": "7 days"
}
```

Videos come newest first, every one carrying the hashtag. Each item has
`input` (the hashtag) and `searchHashtag` (`name`, `videoCount`). The results
are the hashtag's recent public videos, not the full history of a hashtag with
millions of posts.

#### Filter by date

`oldestPostDateUnified` and `newestPostDate` take:

- a date: `2025-01-31`
- an ISO timestamp: `2025-01-31T18:00:00Z` (no time zone means UTC)
- a relative period: `3 days`, `2 weeks`, `6 months`, `1 year` (also
  `minutes` and `hours`)

```json
{
  "profiles": ["zachking"],
  "resultsPerPage": 1000,
  "oldestPostDateUnified": "2024-01-01",
  "newestPostDate": "2025-01-01"
}
```

That returns everything zachking published in 2024.

`resultsPerPage` counts only videos inside the dates. Videos outside them are
never delivered and never charged.

The date range applies to profile videos and hashtag videos. Reposts come in
TikTok's order, newest reposts first, without a date filter.

### Output

```json
{
  "id": "7689510970292489502",
  "webVideoUrl": "https://www.tiktok.com/@khaby.lame/video/7689510970292489502",
  "text": "Ye… I’m gonna mind my business #learnfromkhaby #comedy",
  "createTimeISO": "2026-09-25T16:30:18.000Z",
  "playCount": 5700000,
  "diggCount": 690000,
  "commentCount": 15600,
  "shareCount": 39500,
  "collectCount": 33612,
  "hashtags": ["learnfromkhaby", "comedy"],
  "authorMeta": { "name": "khaby.lame", "nickName": "Khabane lame", "verified": true, "fans": 162966356, "heart": 2683467682, "video": 1356 },
  "musicMeta": { "musicName": "original sound", "musicAuthor": "Khabane lame", "musicOriginal": true, "duration": 26 },
  "videoMeta": { "duration": 26, "width": 720, "height": 1280, "definition": "720p", "format": "mp4" },
  "input": "khaby.lame",
  "fromProfileSection": "videos",
  "comments": [
    {
      "text": "KHABY LAME 💪🏿",
      "diggCount": 9890,
      "replyCount": 17,
      "authorUsername": "someone",
      "replies": [{ "text": "Yooow", "diggCount": 16, "authorUsername": "someone.else" }]
    }
  ]
}
```

Above about 10,000, TikTok itself rounds video views and likes to 3 digits
(5,700,000), on its website too. Profile numbers in `authorMeta` are exact.

#### Every field

| Field | Type | What it is |
|---|---|---|
| `id` | string | Video ID |
| `webVideoUrl` | string | Link to the video |
| `text` | string | Full caption |
| `textLanguage` | string | Caption language |
| `createTime` / `createTimeISO` | integer / string | Publish time, Unix seconds / ISO UTC |
| `playCount` | integer | Views |
| `diggCount` | integer | Likes |
| `commentCount` | integer | Comments |
| `shareCount` | integer | Shares |
| `collectCount` | integer | Saves |
| `repostCount` | integer | Reposts |
| `hashtags` | array | Hashtags in the caption |
| `mentions` | array | Handles mentioned in the caption |
| `detailedMentions` | array | Mentioned profiles with ID and link |
| `isAd` | boolean | Paid ad |
| `isSlideshow` | boolean | Photo slideshow instead of a video |
| `slideshowImageLinks` | array | Every photo of a slideshow |
| `location` | object | Tagged place: name, address, city, country |
| `effectStickers` | array | Effects used |
| `authorMeta` | object | Profile (see above) |
| `musicMeta` | object | Sound (see above) |
| `videoMeta` | object | Video file details (see above) |
| `input` | string | The profile or hashtag you asked for |
| `fromProfileSection` | string | `videos` or `reposts` (profiles only) |
| `searchHashtag` | object | Hashtag items only: `name`, `videoCount` |
| `comments` | array | Comments: `id`, `text`, `stickerUrl` (sticker and GIF comments), `diggCount`, `replyCount`, `createTimeISO`, `authorUsername`, `authorNickname`, `authorProfileUrl`, `likedByAuthor`, `pinnedByAuthor`, `language`, and `replies` when requested (same fields, without `replyCount`) |
| `commentsIncomplete` | boolean | Fewer comments than requested could be collected |

Cover and avatar links are temporary, as on TikTok itself: download them soon
after the run. Video and audio files are not included.

You can download the dataset in JSON, CSV, Excel, HTML, XML or RSS.

### API

Every run is available over the Apify API. Replace `<TOKEN>` with your API
token from **Settings → Integrations**.

#### Run and wait for the results

```bash
curl -X POST "https://api.apify.com/v2/acts/<ACTOR_ID>/run-sync-get-dataset-items?token=<TOKEN>" \
  -H "Content-Type: application/json" \
  -d '{
        "profiles": ["nasa"],
        "resultsPerPage": 50
      }'
```

Best for small and medium jobs. The connection stays open until the run ends,
so keep a generous client timeout.

#### Python

```python
from apify_client import ApifyClient

client = ApifyClient("<TOKEN>")

run = client.actor("<ACTOR_ID>").call(run_input={
    "profiles": ["nasa"],
    "resultsPerPage": 100,
    "commentsPerPost": 20,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["webVideoUrl"], item["playCount"], len(item.get("comments", [])))
```

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<TOKEN>' });

const run = await client.actor('<ACTOR_ID>').call({
    profiles: ['nasa'],
    resultsPerPage: 100,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.length);
```

#### Run summary

Besides the dataset, each run writes an `OUTPUT` record to the key-value store
with a summary per profile and per hashtag:

```json
{
  "ok": true,
  "total_items": 150,
  "total_comments": 2400,
  "profiles": [
    { "profile": "nasa", "count": 100, "comments": 1600 },
    { "profile": "khaby.lame", "count": 50, "comments": 800 },
    { "hashtag": "footballedit", "count": 100 }
  ]
}
```

With reposts, each profile also has `sections` (videos and reposts counted
apart). A profile can carry `notes`, for example
`reposts could not be collected right now, please try again later` or
`no reposts found`. The summary has `timed_out: true` when the run reached its
time limit and `charge_limit_reached: true` when it reached the maximum cost
you set.

When a profile cannot be completed, its entry carries an `error` field and the
videos already collected stay in the dataset. The `error` is one of:

| `error` | What it means | What to do |
|---|---|---|
| `profile not found or unavailable` | The handle does not exist, was renamed or banned | Check the handle |
| `profile is private` | The profile is private | Nothing: only public profiles can be read |
| `no public videos found` | The profile has no public videos | Check the profile |
| `no videos published in the requested date range` | Nothing inside your dates | Widen the range |
| `could not be collected right now, please try again later` | A temporary problem on TikTok's side | Run that profile again later |
| `collection stopped early, please try again later for the rest` | Some videos were collected, then a temporary problem stopped it | Run again later for the rest |
| `the run time limit was reached before this profile finished; videos collected so far are in the dataset` | The run's timeout arrived mid-profile | Give the run a longer timeout |
| `not started: run time limit reached` | The timeout arrived before this profile's turn | Give the run a longer timeout |
| `not started: the maximum cost set for this run was reached` | The run reached the maximum cost you set | Raise it, or run the rest separately |
| `not started: TikTok is refusing requests right now, please try again later` | TikTok refused several profiles in a row | Run again later |
| `not a valid TikTok profile` | The entry is not a handle or profile URL | Fix the entry |
| `hashtag not found` | The hashtag does not exist | Check the hashtag |
| `not a valid hashtag` | The entry has spaces or invalid characters | Fix the entry |

**Sizing the timeout.** Without comments, a run collects several hundred
videos per minute. With 50 comments per video, 100 videos take about 2 minutes.
When the timeout is close, the run stops on its own, writes this summary and
finishes as *Succeeded*, keeping everything collected so far.

### What people use this for

- **Daily tracking** of views, likes, comments, shares and saves per video.
- **Influencer vetting**: reach versus engagement over the last videos.
- **Content research**: which videos, hashtags and sounds perform.
- **Comment analysis**: what the audience says, with replies.
- **Hashtag monitoring**: the newest videos of a hashtag, every day.
- **Period reports** for a month, quarter or campaign.

### Frequently asked questions

**Can I get the comment text?**
Yes. Set `commentsPerPost`, and `maxRepliesPerComment` for the replies. They
come inside each video, most relevant first. Comments that are only a sticker
or GIF come with `stickerUrl`.

**Why are some views rounded?**
TikTok publishes video views and likes rounded to 3 digits above about 10,000,
on its own website too. That is the number TikTok gives out. Profile numbers
(followers, total likes) are exact.

**Can I choose which columns I get?**
Yes. Pick them in **Fields to return** (`selectedFields`). Leave it empty and
you get every field. Comments are always included when you ask for them.

**Can I sort by most viewed?**
No. Videos come by publish date. Pull the period you care about and sort by
`playCount` in your spreadsheet.

**Why is an old pinned video not at the top?**
Pinned videos are ignored as pinned. The list is always by publish date, so
"Latest" really is the latest, and each pinned video appears at its own date.

**How many videos can I get from a hashtag?**
Up to `resultsPerHashtag`, newest first. Large hashtags usually return a few
hundred recent videos per run; a smaller hashtag can return fewer than you ask
for.

**Can I scrape private profiles?**
No. Only public profiles return data. A private profile is skipped and marked
in `OUTPUT`, and the rest of the run continues.

**What happens if one profile fails?**
The other profiles keep going. Videos already collected stay in the dataset,
and the `OUTPUT` record marks that profile with an `error` field.

**Can I ask for more videos than the profile has?**
Yes. You get everything available and the run ends normally.

**Do I need a proxy or a login?**
No. There is nothing to configure: no cookies, no session, no browser.

**What are reposts?**
Videos from other accounts that the profile reposted. `authorMeta` is the
original author, and `input` is the profile that reposted it.

**How much does it cost?**

| | Free plan | Any paid Apify plan |
|---|---|---|
| Videos | $0.10 per 1,000 | $0.05 per 1,000 |
| Comments and replies | $0.05 per 1,000 | $0.025 per 1,000 |

Charged per video and per comment delivered: each reply counts as one comment.
A run that returns nothing costs nothing. If you set a maximum cost for a run,
the run stops when it is reached, keeps everything collected so far, and says
so in its status and in `OUTPUT` (`charge_limit_reached`).

**How do I track a profile every day?**
Create a task with your profiles and schedule it daily in Apify. Each run is a
snapshot of that day: join the runs by video `id` to see how `playCount`,
`diggCount`, `commentCount`, `shareCount` and `collectCount` evolve, and by
`authorMeta.name` to follow `fans` and `heart`. To pick up only new videos, set
`oldestPostDateUnified` to `1 day`.

**Is this affiliated with TikTok?**
No. See the disclaimer at the bottom.

### Notes and limits

- Only **public** profiles are supported.
- A profile that is unavailable is skipped with a warning; the other profiles
  in the same run continue normally.
- Requesting more videos than a profile has simply returns everything
  available.

### Support

Found a bug or need a field that is not on the list? Open an issue on the
Actor's **Issues** tab with the input you used and the run ID.

### Disclaimer

This is an unofficial tool and is not affiliated with, endorsed by, or
sponsored by TikTok or ByteDance Ltd. It collects only publicly available
content. You are responsible for how you use the data, including compliance
with applicable laws and the target site's terms.

# Changelog

This Actor's version history is a separate document: https://apify.com/esdrasdw/tiktok-scraper/changelog.md

# Actor input Schema

## `profiles` (type: `array`):

Public TikTok profiles, one per line: a handle (nasa), @handle or a profile URL (https://www.tiktok.com/@nasa). Up to 1,000 per run.

## `resultsPerPage` (type: `integer`):

How many videos to return for each profile: at least 10, up to 10,000 (and, if you also pick reposts, the maximum number of reposts). A profile with fewer videos returns all it has.

## `profileSorting` (type: `string`):

Latest: newest first. Oldest: oldest first, from the very first video. Pinned videos never jump to the top: each one shows up at its own publish date, like any other video.

## `profileScrapeSections` (type: `array`):

Videos: the profile's own videos. Reposts: videos from other accounts that the profile reposted (each one keeps its original author in authorMeta).

## `hashtags` (type: `array`):

Hashtags, one per line: fyp, #fyp or https://www.tiktok.com/tag/fyp. Up to 100 per run.

## `resultsPerHashtag` (type: `integer`):

How many videos to return for each hashtag, newest first: at least 10, up to 10,000.

## `commentsPerPost` (type: `integer`):

How many comments to include with each video (0 = none).

## `maxRepliesPerComment` (type: `integer`):

How many replies to include under each comment (0 = none). The same as clicking "View replies" on TikTok. Only used when comments are on.

## `oldestPostDateUnified` (type: `string`):

Only videos published on or after this date: YYYY-MM-DD, an ISO timestamp, or a relative period such as 7 days, 2 weeks or 3 months.

## `newestPostDate` (type: `string`):

Only videos published before this date. The run jumps straight to it, so an old period of a large profile is fast.

## `selectedFields` (type: `array`):

Keep the ones you need and remove the rest; leave it empty to get every field. Comments are always included when you ask for them above.

## Actor input object example

```json
{
  "profiles": [
    "nasa"
  ],
  "resultsPerPage": 100,
  "profileSorting": "latest",
  "profileScrapeSections": [
    "videos"
  ],
  "resultsPerHashtag": 100,
  "commentsPerPost": 0,
  "maxRepliesPerComment": 0,
  "selectedFields": [
    "id",
    "webVideoUrl",
    "text",
    "createTime",
    "createTimeISO",
    "playCount",
    "diggCount",
    "commentCount",
    "shareCount",
    "collectCount",
    "hashtags",
    "mentions",
    "authorMeta",
    "musicMeta",
    "videoMeta",
    "input",
    "fromProfileSection"
  ]
}
```

# Actor output Schema

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

Every video collected, with its numbers and, when requested, its comments. Ready to download as JSON, CSV or Excel.

## `summary` (type: `string`):

Videos and comments per profile, and the reason when a profile could not be completed.

# 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 = {
    "profiles": [
        "nasa"
    ],
    "resultsPerPage": 100,
    "resultsPerHashtag": 100,
    "commentsPerPost": 0,
    "maxRepliesPerComment": 0,
    "selectedFields": [
        "id",
        "webVideoUrl",
        "text",
        "createTime",
        "createTimeISO",
        "playCount",
        "diggCount",
        "commentCount",
        "shareCount",
        "collectCount",
        "hashtags",
        "mentions",
        "authorMeta",
        "musicMeta",
        "videoMeta",
        "input",
        "fromProfileSection"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("esdrasdw/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 = {
    "profiles": ["nasa"],
    "resultsPerPage": 100,
    "resultsPerHashtag": 100,
    "commentsPerPost": 0,
    "maxRepliesPerComment": 0,
    "selectedFields": [
        "id",
        "webVideoUrl",
        "text",
        "createTime",
        "createTimeISO",
        "playCount",
        "diggCount",
        "commentCount",
        "shareCount",
        "collectCount",
        "hashtags",
        "mentions",
        "authorMeta",
        "musicMeta",
        "videoMeta",
        "input",
        "fromProfileSection",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("esdrasdw/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 '{
  "profiles": [
    "nasa"
  ],
  "resultsPerPage": 100,
  "resultsPerHashtag": 100,
  "commentsPerPost": 0,
  "maxRepliesPerComment": 0,
  "selectedFields": [
    "id",
    "webVideoUrl",
    "text",
    "createTime",
    "createTimeISO",
    "playCount",
    "diggCount",
    "commentCount",
    "shareCount",
    "collectCount",
    "hashtags",
    "mentions",
    "authorMeta",
    "musicMeta",
    "videoMeta",
    "input",
    "fromProfileSection"
  ]
}' |
apify call esdrasdw/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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