# TikTok Scraper: Videos, Hashtags, Profiles & Comments (`humble-echidna/tiktok-scraper`) Actor

Scrape TikTok without login: videos from hashtags, sounds, profiles and video links, with views, likes, comments, shares, saves, author follower counts, music and hashtags as flat columns. Add each video's comments, filter by date, or get only new videos on a schedule.

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

## Pricing

from $1.60 / 1,000 video or profiles

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

### What does TikTok Scraper do?

**TikTok Scraper** gets **TikTok videos from hashtags, sounds, profiles and video links**, with **views, likes,
comments, shares and saves**, the author's follower counts, the sound and the hashtags, one flat row per video. Add
each video's **comments and replies** as rows of their own. No login, no account, no cookies of yours.

[Input fields](https://apify.com/humble-echidna/tiktok-scraper/input-schema) ·
[API](https://apify.com/humble-echidna/tiktok-scraper/api) ·
[Use it from Claude, ChatGPT or Cursor (MCP)](#can-i-use-tiktok-scraper-from-an-ai-agent-mcp)

**Jump to:** [Monitor](#monitor-tiktok-get-only-new-videos-and-comments-in-slack-email-or-a-webhook) ·
[Fields](#what-data-does-tiktok-scraper-return) ·
[Price](#how-much-does-it-cost-to-scrape-tiktok) ·
[How to use](#how-to-scrape-tiktok-hashtags-profiles-and-comments) ·
[Input](#input) · [Output](#output) · [Switching](#switching-from-another-tiktok-actor) ·
[AI agents (MCP)](#can-i-use-tiktok-scraper-from-an-ai-agent-mcp) · [Limits](#limits) · [FAQ](#faq)

**Try it in one click:** the input comes pre-filled with NASA's profile. That's 10 results (its 10 latest videos),
or about $0.035 (10 × $3.50/1,000, plus $0.0001 for the run start). **Then replace it with what you actually
want.**

### Monitor TikTok: get only new videos and comments, in Slack, email or a webhook

With **Only new since the last run** on, each run returns (and charges for) only the videos and comments that input
hasn't returned before. A run with nothing new costs only the start fee ($0.0001).

1. Put what you follow in **Hashtags**, **Profiles** or **Sounds** (`"profiles": ["nasa"]`, `"hashtags": ["skincare"]`), set **Max videos per source** to how many of each to look at (`"maxVideosPerSource": 10`: the
   10 latest of a profile, the first 10 TikTok lists for a hashtag), turn on **Only new since the last run**
   (`"onlyNew": true`), and click **Start**. This first run returns everything it looks at and is the baseline.
2. Click **Save as a new task** (top right of the actor page). What has been returned is remembered per hashtag,
   sound, profile and video (for comments), in a store in your account, for 120 days.
3. In Apify Console, open **Schedules**, click **Create new**, set how often in **Schedule setup** (for example every
   hour, or daily at 07:00), then **Add** your task.
4. On the task, open the **Integrations** tab and pick where the new videos go:
   - **Slack**: click **Configure**, sign in, pick the workspace and channel, and the "run succeeded" event. A
     useful message: `{{resource.statusMessage}}` and a link,
     `<https://console.apify.com/storage/datasets/{{resource.defaultDatasetId}}|new TikTok videos>`.
   - **Gmail**: click **Connect with Google**, set the subject and body, and attach the dataset. It sends after each
     successful run.
   - **HTTP webhook**: event `ACTOR.RUN.SUCCEEDED`, your URL. Apify POSTs `{"eventType": ..., "resource": {...}}`;
     `resource.defaultDatasetId` is the run's dataset, and
     `GET https://api.apify.com/v2/datasets/<defaultDatasetId>/items?format=json` (with your API token) returns the
     new rows.

Apify's integrations fire after every successful run, including quiet ones: a quiet run's dataset is empty.

To watch the comments on your own videos, put the video links in **Video links** with **Comments per video** set
and only new on: the video row comes back each run with fresh counts, and only comments you haven't had yet.

### What data does TikTok Scraper return?

One row per **video** (`"type": "video"`, photo posts included), per **comment or reply** (`"type": "comment"`) and,
if you ask for it, per **profile** (`"type": "profile"`), in one table. The main fields:

| Field | Example | Notes |
|---|---|---|
| `url` | `https://www.tiktok.com/@nasa/video/7695060950394703118` | The video (or `/photo/` post) |
| `text` | `We just released hundreds of new images…` | Caption; for comments, the comment |
| `createdAt` | `2026-10-10T15:26:57Z` | When it was posted, UTC |
| `views`, `likes`, `comments`, `shares`, `saves` | `297900`, `27200`, `1739`, `1096`, `1752` | As precise as TikTok gives them (it rounds large ones) |
| `hashtags`, `mentions` | `["easyrecipes", "dinner"]` | From the caption, lowercase, no `#` or `@` |
| `authorUsername`, `authorName`, `authorVerified` | `nasa`, `NASA`, `true` | |
| `authorFollowers`, `authorLikes`, `authorVideos` | `2100000`, `11000000`, `56` | Rounded on video rows; exact on profile rows |
| `musicTitle`, `musicAuthor`, `musicId`, `musicUrl` | `original sound - NASA` | The sound; `musicUrl` works in **Sounds** |
| `durationSeconds`, `width`, `height`, `coverUrl` | `43`, `718`, `1276` | `coverUrl` is a signed link that expires |
| `isSlideshow`, `imageUrls` | `false`, `[]` | Photo posts list their images |
| `videoId`, `videoUrl`, `replyTo`, `replies` | | Comments: which video, which comment a reply answers, reply count |
| `source`, `sourceType` | `nasa`, `profile` | The input line the row came from |

Every row also has `id` (stable across runs, for deduplicating) and `scrapedAt`. The full list is under
[Output](#output).

### How much does it cost to scrape TikTok?

You pay per row:

| | Free plan | Starter | Scale | Business and up |
|---|---:|---:|---:|---:|
| Video (or profile row), per 1,000 | **$3.50** | $2.90 | $2.20 | $1.60 |
| Comment or reply, per 1,000 | **$1.20** | $0.95 | $0.70 | $0.48 |

plus Apify's start fee each time a run starts: $0.00005 per GB of memory, so $0.0001 at the default 2 GB.

- **The pre-filled example:** 10 videos × $3.50/1,000 = $0.035, plus the start fee.
- **A month, for example:** 20 creators checked daily for new videos with only new on, about 2 new videos each a
  week: ~170 videos ≈ **$0.60** on the Free plan, plus $0.003 of start fees. A brand pulling 100 hashtag videos and
  50 comments each, weekly: 400 videos + 20,000 comments ≈ **$25.40** (Starter: $20.16).
- **Free filters:** **Only videos newer than** and **Only new since the last run** cost nothing; skipped videos and
  comments are never charged.
- **Caps:** **Max results per run** in the input, and **Maximum cost per run** in the run options. The run stops
  cleanly at whichever comes first, and stops fetching as soon as the limit is covered.

**Never charged:** sources that fail (a missing account, a private profile's videos, a hashtag TikTok doesn't have),
videos or comments skipped by the filters, and anything past your limits.

### How to scrape TikTok hashtags, profiles and comments

1. Open TikTok Scraper and click **Try for free** (or **Start** if you're signed in).
2. Fill in any of **Hashtags**, **Profiles**, **Video links** and **Sounds**, one per line. One run can mix them.
3. Set **Max videos per source**, and if you want comments, **Comments per video** (and **Replies per comment**).
4. Optionally set **Only videos newer than** (`7 days`, `2026-10-01`) or **Only new since the last run**.
5. Click **Start**, then open the **Output** tab and export as JSON, CSV or Excel. The **Comments** view shows just
   the comments.

### Example: NASA's latest videos

The pre-filled input:

```json
{"profiles": ["nasa"], "maxVideosPerSource": 10}
```

It returned 10 videos in 22 seconds on Apify (run on 2026-10-14). The third, with long links shortened:

```json
{
  "type": "video",
  "id": "7695060950394703118",
  "url": "https://www.tiktok.com/@nasa/video/7695060950394703118",
  "text": "We just released hundreds of new images and hours of new audio from our Artemis Il mission around the Moon this spring. Check out our link in bio for the Artemis II Preliminary Lunar Science Report.",
  "createdAt": "2026-10-10T15:26:57Z",
  "views": 297900,
  "likes": 27200,
  "comments": 1739,
  "shares": 1096,
  "saves": 1752,
  "reposts": 0,
  "hashtags": [],
  "mentions": [],
  "authorUsername": "nasa",
  "authorName": "NASA",
  "authorId": "7664638705177150477",
  "authorVerified": true,
  "authorFollowers": 2100000,
  "authorFollowing": 23,
  "authorLikes": 11000000,
  "authorVideos": 56,
  "authorBio": "Making the seemingly impossible, possible.✨",
  "authorAvatar": "https://p16-common-sign.tiktokcdn-us.com/tos-useast5-avt-0068-tx/e5143212…jpeg?…",
  "authorUrl": "https://www.tiktok.com/@nasa",
  "durationSeconds": 43,
  "width": 718,
  "height": 1276,
  "coverUrl": "https://p19-common-sign.tiktokcdn-us.com/tos-useast5-p-0068-tx/o0UC1fSKnwLIBgdIAP0iA0ApWBZiIoG91SuMhT~tplv-tiktokx-origin.image?…",
  "isSlideshow": false,
  "imageUrls": [],
  "musicId": "7695060940479384334",
  "musicTitle": "original sound - NASA",
  "musicAuthor": "NASA",
  "musicOriginal": false,
  "musicUrl": "https://www.tiktok.com/music/sound-7695060940479384334",
  "language": "en",
  "locationCreated": "US",
  "isAd": false,
  "source": "nasa",
  "sourceType": "profile",
  "scrapedAt": "2026-10-14T22:46:20.069288Z"
}
```

With **Comments per video** set, each comment follows as its own row (from another run the same day; the author's
id, avatar and profile link and `scrapedAt` left out here):

```json
{
  "type": "comment",
  "id": "7695062072681972502",
  "url": "https://www.tiktok.com/@nasa/video/7695060950394703118?comment=7695062072681972502",
  "text": "how do people say this is fake😭",
  "createdAt": "2026-10-10T15:31:24Z",
  "likes": 833,
  "replies": 78,
  "likedByAuthor": false,
  "pinnedByAuthor": false,
  "replyTo": null,
  "language": "en",
  "authorUsername": "uncledannyfr",
  "authorName": "Uncle Danny RC",
  "videoId": "7695060950394703118",
  "videoUrl": "https://www.tiktok.com/@nasa/video/7695060950394703118",
  "source": "https://www.tiktok.com/@nasa/video/7695060950394703118",
  "sourceType": "video"
}
```

### Input

| Field | What it does |
|---|---|
| **Hashtags** (`hashtags`) | `cooking`, `#cooking` or `https://www.tiktok.com/tag/cooking`, one per line |
| **Profiles** (`profiles`) | `nasa`, `@nasa` or `https://www.tiktok.com/@nasa`: the account's latest videos |
| **Video links** (`videoUrls`) | `https://www.tiktok.com/@user/video/<id>`, `/photo/` links, `vm.tiktok.com` and `tiktok.com/t/` short links |
| **Sounds** (`sounds`) | `https://www.tiktok.com/music/<name>-<id>`, or just the id: videos using that sound |
| Max videos per source (`maxVideosPerSource`) | How many of each hashtag's, sound's or profile's videos to look at, in TikTok's order (default 10, up to 1,000; see [Limits](#limits)) |
| Comments per video (`commentsPerVideo`) | Up to this many top-level comments per video, as rows (default 0, up to 1,000) |
| Replies per comment (`repliesPerComment`) | Up to this many replies to each comment that has any (default 0, up to 100) |
| Only videos newer than (`newerThan`) | A date (`2026-10-01`) or an age (`24 hours`, `7 days`, `2 weeks`, `3 months`) |
| Only new since the last run (`onlyNew`) | Skip videos and comments this input returned before |
| Also return each profile (`profileRows`) | One row per profile with exact follower, following, like and video counts, bio and bio link |
| Max results per run (`maxResults`) | Cap on all rows together |

```json
{
  "hashtags": ["skincare"],
  "profiles": ["nasa", "@nba"],
  "videoUrls": ["https://vm.tiktok.com/ZMexample/"],
  "maxVideosPerSource": 30,
  "commentsPerVideo": 20,
  "newerThan": "7 days",
  "maxResults": 1000
}
```

### Output

Every row has the same columns; the ones that don't apply to its `type` are `null` (or missing). Fields TikTok
doesn't publish for an item are `null`. Videos and comments are written in batches, so they don't strictly
alternate; match a comment to its video with `videoId` = `id`. The run's `RUN_STATS` record lists every source, what it returned, what the filters skipped
(`alreadySeen`, `olderThanCutoff`), why a list ended (`listEnded`) and anything that failed, with TikTok's own reason.

### Switching from another TikTok actor?

Most TikTok actors take the same kinds of input under other names. Here's where each goes:

| What you had | Put it here |
|---|---|
| Hashtags | **Hashtags** (`hashtags`), with or without `#` |
| Profiles or usernames | **Profiles** (`profiles`): usernames, `@names` or links |
| Post or video URLs (`postURLs`, `startUrls`) | **Video links** (`videoUrls`); short links work |
| Music or sound URLs | **Sounds** (`sounds`) |
| Results per page / per source (`resultsPerPage`, `maxItems`) | **Max videos per source**, and **Max results per run** for the total |
| Comments per post | **Comments per video**; replies with **Replies per comment** |
| A date filter (oldest post date, days back) | **Only videos newer than**: a date or `N days`; free here |
| Search queries | Not available: TikTok asks visitors to log in to search ([why](#limits)) |
| Follower or following lists, video downloads, transcripts | Not available here |

What's different in the output: one **flat row** per video or comment instead of nested author, music and video
objects. Author fields start with `author` (`authorUsername`, `authorFollowers`), sound fields with `music`
(`musicTitle`, `musicId`). Counts are `views`, `likes`, `comments`, `shares`, `saves`; the posting time is
`createdAt` (ISO 8601) and the page is `url`. Comments come in the same table with `type: "comment"` and point at
their video with `videoId` and `videoUrl`.

### Run it on a schedule, or from your own code

1. Save your input as a [task](https://docs.apify.com/platform/actors/running/tasks) (**Save as a new task**, top right
   of the actor page) and add it to a [schedule](https://docs.apify.com/platform/schedules) (Console → Schedules →
   **Create new**).
2. Collect results: download the dataset as JSON, CSV or Excel; fetch the latest run's results from the
   [API](https://apify.com/humble-echidna/tiktok-scraper/api)
   (`GET https://api.apify.com/v2/actor-tasks/<task id>/runs/last/dataset/items?status=SUCCEEDED&format=csv`, with
   your API token); let a [webhook](https://docs.apify.com/platform/integrations/webhooks) tell your system when a
   run succeeds; or connect it to Make, Zapier or n8n through
   [Apify's integrations](https://docs.apify.com/platform/integrations).

#### Can I use TikTok Scraper from an AI agent (MCP)?

Yes, through [Apify's MCP server](https://docs.apify.com/platform/integrations/mcp), from Claude, ChatGPT, Cursor or
any other MCP client. Add this to your client's MCP configuration (or let the agent find it with the server's actor
search); your client signs you in to Apify:

```json
{
  "mcpServers": {
    "apify": {
      "url": "https://mcp.apify.com?tools=humble-echidna/tiktok-scraper"
    }
  }
}
```

To use an [Apify API token](https://console.apify.com/settings/integrations) instead of signing in, add
`"headers": {"Authorization": "Bearer <APIFY_TOKEN>"}` next to `url`.

An agent should pass a few sources and small counts, e.g.
`{"hashtags": ["skincare"], "maxVideosPerSource": 20, "commentsPerVideo": 10, "maxResults": 200}`.

### Who it's for

Brands and agencies tracking a hashtag, a campaign sound or competitors' accounts; influencer marketers checking a
creator's recent views and engagement before a deal; social listening and research teams reading what people say in
the comments; and anyone whose dashboard, spreadsheet or AI agent needs fresh TikTok numbers on a schedule.

### Why this one?

- **One run, one table.** Hashtags, profiles, video links, sounds, comments and replies together, every row flat
  and ready for a spreadsheet.
- **Built for schedules.** Only new skips what you already have (videos and comments), and a quiet run costs the
  start fee ($0.0001).
- **Free filters.** The date filter and only new are free, and profile videos older than your cutoff are skipped
  before they're even fetched.
- **Says what happened.** Each source's outcome is in the log and `RUN_STATS`: how many it returned, what was
  skipped and why, and TikTok's own reason when something isn't available. No silent empty runs.
- **Reliable.** One failing source, video or comment thread never affects the others. On 2026-10-14 on Apify, 2
  hashtags × 100 videos took 58 s and 2 videos × 300 comments took 22 s.

### Limits

These are TikTok's limits for visitors who aren't logged in (measured 2026-10-14), and this actor never logs in or
uses accounts or cookies:

- **Profiles: the ~10 latest videos** (a pinned video first), the ones TikTok shows on a profile's embed card. Its
  full video grid isn't served to automated visitors.
- **Hashtags: about 120-160 videos** each; TikTok then says there are no more (`listEnded` in `RUN_STATS`). The
  order is TikTok's and changes between visits.
- **Comments: a few hundred per video.** TikTok ends the comment list for visitors at about 500 positions, with
  repeats: 372 distinct comments on a video with 2,265 (replies included). Replies come on top with **Replies per
  comment**.
- **Sounds:** creators' original sounds work. Licensed songs' sound pages aren't shown to visitors (TikTok status
  10219\); those lines fail free with that reason.
- **No keyword search.** TikTok shows visitors a dozen results and then asks them to log in.
- **No follower or following lists, video downloads, transcripts, stories or live streams.**
- **Counts are what visitors see** when the run reads them. TikTok rounds large counts (and author counts on video
  rows); profile rows (**Also return each profile**) carry exact follower counts.
- Image and video links (`coverUrl`, `authorAvatar`, `imageUrls`) are TikTok's signed links and expire after a few
  days; download them soon if you need them.

### FAQ

#### Is it legal to scrape TikTok?

This actor reads only what TikTok shows anyone who isn't logged in: public videos, profiles, hashtag and sound pages
and comments, through the same pages and requests tiktok.com uses in a browser. It never logs in and can't see
private accounts. TikTok's robots.txt disallows the embed and API paths it uses for automated clients, and TikTok's
Terms of Service (section 3.4, which say they apply even to visitors without an account) forbid extracting data by
automated means without TikTok's written approval. Courts have treated scraping of public data differently from
breaking into private data, but the law differs by country and use. Results include public usernames and comments,
which are personal data in many places (GDPR and similar laws): have a lawful reason, keep only what you need, and
don't use them for spam or profiling people. How you use the data is up to you and the laws that apply to you. An
account owner who wants their account left out can open an issue.

#### Why did a source return nothing, or fewer results than expected?

Look at that source in the log or `RUN_STATS`: the account may be private or not exist (TikTok's own status is
quoted), the hashtag may not exist, the sound may be a licensed song, the list may have ended (`listEnded`), or a
filter (**Only videos newer than**, **Only new**) skipped the rest (`olderThanCutoff`, `alreadySeen`). Every other
source in the run is unaffected. If TikTok's page didn't load a hashtag's videos at all, the source fails free; run
it again later, and please open an issue with the input if it keeps happening.

#### Can I get only new results since my last run?

Yes: turn on **Only new since the last run**
([how](#monitor-tiktok-get-only-new-videos-and-comments-in-slack-email-or-a-webhook)). It works per hashtag, sound,
profile and video; video links always return their video, with only new comments.

#### How is this different from TikTok's official APIs?

TikTok's Research API is for approved non-profit academic researchers, and its Display and Business APIs cover
accounts that log in to your app. This actor needs no application or login and works for any public account,
hashtag or sound, but only with what logged-out visitors can see.

### Related actors

| Actor | Use it when |
|---|---|
| [Instagram Scraper](https://apify.com/humble-echidna/instagram-scraper) | You track the same creators or brands on Instagram |
| [Bulk Image Downloader](https://apify.com/humble-echidna/bulk-image-downloader) | You want covers or slideshow images saved before TikTok's links expire (dataset input, URL field `coverUrl`) |
| [Dataset Transformer](https://apify.com/humble-echidna/dataset-transform) | You want the rows filtered, renamed or split into videos and comments in your own CSV or Excel layout |
| [Dataset Diff](https://apify.com/humble-echidna/dataset-diff) | You want to see how views, likes or followers changed between two runs |

### Feedback and support

Found a bug, or need a field or source that isn't here? Open an issue on the **Issues** tab with the input you used.

### Versions

Current version: **0.1**. See the Changelog tab for what changed in each version.

# Changelog

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

# Actor input Schema

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

Hashtags to get videos from, one per line: `cooking`, `#cooking` or a link like https://www.tiktok.com/tag/cooking. Returns the videos TikTok lists on the hashtag's page, in its order, up to Max videos per source each.

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

TikTok accounts, one per line: `nasa`, `@nasa` or https://www.tiktok.com/@nasa. Returns each account's latest videos as TikTok shows them to visitors who aren't logged in: about 10, newest first, a pinned video first if there is one. Private accounts return no videos.

## `videoUrls` (type: `array`):

Single videos or photo posts, one link per line: https://www.tiktok.com/@user/video/<id>, a /photo/ link, or a short link (vm.tiktok.com/..., tiktok.com/t/...). One result per link, with fresh counts.

## `sounds` (type: `array`):

Sounds (music) to get the videos that use them, one per line: a link like https://www.tiktok.com/music/original-sound-7695060940479384334, or just the number at its end.

## `maxVideosPerSource` (type: `integer`):

How many of each hashtag's, sound's or profile's videos to look at, in TikTok's order, 1 to 1000 (default 10). Visitors who aren't logged in see about 120-160 per hashtag and the ~10 latest per profile. Only new and the date filter skip some of those. Video links give their one video.

## `commentsPerVideo` (type: `integer`):

Also return up to this many top-level comments for every video returned, 0 to 1000 (default 0: none). Each comment is one result at the lower comment price, in TikTok's order (top comments first). TikTok lists a few hundred per video to visitors who aren't logged in.

## `repliesPerComment` (type: `integer`):

With comments on, also return up to this many replies to each comment that has any, 0 to 100 (default 0: none). Each reply is a comment result (with `replyTo` set to the comment it answers) and costs one more request per comment.

## `newerThan` (type: `string`):

Skip videos posted before this: a date like 2026-10-01, or an age like `7 days`, `24 hours`, `2 weeks`, `3 months`. Leave empty for no date filter. Skipped videos are never charged.

## `onlyNew` (type: `boolean`):

For schedules: skip videos (from hashtags, sounds and profiles) and comments this input has returned before. Remembered per hashtag, sound, profile and video, in a store in your account, for 120 days. Video links always return their video; only their comments are filtered.

## `profileRows` (type: `boolean`):

Add one result per profile with its follower, following, like and video counts, bio and bio link (charged like a video). Off by default: every video row already carries its author's counts.

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

Stop after this many results in total (videos, profiles and comments together), e.g. 100. Minimum 1; leave empty (the default) for no limit. The run also stops cleanly at the maximum cost per run you set in the run options, whichever comes first.

## Actor input object example

```json
{
  "profiles": [
    "nasa"
  ],
  "maxVideosPerSource": 10,
  "commentsPerVideo": 0,
  "repliesPerComment": 0,
  "onlyNew": false,
  "profileRows": false
}
```

# Actor output Schema

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

No description

## `runStats` (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 = {
    "profiles": [
        "nasa"
    ],
    "maxVideosPerSource": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("humble-echidna/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"],
    "maxVideosPerSource": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("humble-echidna/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"
  ],
  "maxVideosPerSource": 10
}' |
apify call humble-echidna/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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