# TikTok Profile Scraper (`insights_data/tiktok-profile-scraper`) Actor

Scrape any TikTok profile: videos, reposts, stories and playlists with views, likes, comments, shares, music, hashtags and author stats. Optional followers, comments, transcripts and media downloads. Clean JSON, live results, no login needed.

- **URL**: https://apify.com/insights_data/tiktok-profile-scraper.md
- **Developed by:** [Insights Data](https://apify.com/insights_data) (community)
- **Stats:** 28 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 results

This Actor is paid per event and usage. You are charged both the fixed price for specific events and for Apify platform usage.
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 is TikTok Profile Scraper?

**TikTok Profile Scraper** lets you collect public TikTok profile data: one record per video, repost, active story or playlist video, with caption, upload date, views, hearts, comments, shares, saves, author stats, music and hashtags. It's made for marketers, influencer managers, social media analysts and researchers: add profile URLs or usernames and click **Start**, with no coding, TikTok login or cookies needed. On the Apify Free plan, each run returns up to **10 results in total** (shared by all profiles in the run); paid plans don't have this cap.

On top of the posts, this TikTok profile data scraper can collect followers and following lists, comments and replies, media files, subtitles and speech-to-text transcripts. It's a TikTok scraper for profiles: you get the posts of the accounts you choose, not hashtag or search results.

What you can use it for:

- **Influencer vetting:** check follower counts, views and hearts per post, and the sponsored, ad and TikTok Shop flags before you pay a creator.
- **TikTok competitor analysis:** compare how often brands post, which hashtags and sounds they use, and how their videos perform.
- **Content research:** collect captions, hashtags and subtitles of a creator's videos, and use the built-in TikTok transcript extractor for videos without subtitles.
- **Audience research:** export follower and following lists and the comments under each post.
- **Creator lists:** collect TikTok creator data from many accounts in one run and keep it in your own spreadsheet or tool.
- **AI and data pipelines:** send structured JSON captions and transcripts to LLMs, vector stores or analytics tools.

#### What can TikTok Profile Scraper do?

- 🔗 **Scrape profiles in bulk** from profile URLs, video URLs of the profile, usernames (with or without @) or numeric user IDs. Duplicate profiles are removed.
- 📂 **Choose the sections:** the profile's own videos, reposts, the currently active story and the videos inside its playlists.
- 🎯 **Filter posts** by upload date (exact or relative), hearts, views, post type (videos or slideshows), hashtags and caption words, and skip pinned posts if you like.
- 👥 **Followers, following and comments:** a TikTok followers scraper and a comments collector are built in; each list is saved in its own dataset.
- ⬇️ **Save media files** (videos, covers, slideshow images, avatars, music) plus subtitles and transcripts to a key-value store.
- ⚡ **Live output:** each record is saved as soon as it's ready, so the **Output** tab fills while the run is going.
- 🔌 **Use the Apify platform:** run it via API, schedule and monitor runs, export to JSON, CSV, Excel, XML or HTML, and connect Make, Zapier, Google Sheets and more.
- 🛡️ **Proxy handled for you:** the Actor starts without a proxy and switches to Apify Proxy by itself when TikTok blocks the requests (see the proxy notes in the cost section).

***

### What data can TikTok Profile Scraper extract?

Every post becomes one row in the main **Posts** dataset. These are the main field groups:

| | |
|---|---|
| 🆔 Post ID `id` | 📝 Caption `text` and caption language `textLanguage` |
| 📅 Upload time `createTime`, `createTimeISO` | 🔗 Post link `webVideoUrl` |
| 👁️ Views `playCount` | ❤️ Hearts `diggCount` |
| 💬 Comments `commentCount` | 🔁 Shares `shareCount` |
| 🔖 Saves `collectCount` | 🔄 Reposts `repostCount` |
| 👤 Author `authorMeta` (username, nickname, verified, private, bio, bio link, followers, following, total hearts, video count, friends, account creation date, avatar, seller and live status) | 🎵 Music `musicMeta` (sound name, artist, album, original sound flag, duration, audio link) |
| 🎬 Video `videoMeta` (size, duration, quality, cover, subtitle tracks, transcript link, download link) | 📸 Media links `mediaUrls`, `slideshowImageLinks` |
| #️⃣ Hashtags `hashtags`, `hashtagNames` | 🙋 Mentions `mentions`, `detailedMentions` |
| ✨ Effects and stickers `effectStickers`, `stickerTexts` | 📍 Location `locationCreated`, `locationMeta` |
| 📌 Flags `isPinned`, `isSlideshow`, `isStory`, `isAd`, `isSponsored`, `hasTikTokShopProduct`, `isMuted` | 📂 Section and position `fromProfileSection`, `profilePosition` |
| 🎞️ Playlist `playlistId`, `playlistMeta` | 📝 Transcript `transcript`, `transcriptionError` |
| ⬇️ Stored files `mediaDownloaded` | 🕒 Collection time `scrapedAt` |

The engagement fields are the raw TikTok engagement metrics: views, hearts, comments, shares, saves and reposts. Each post also carries the creator's TikTok user profile data in `authorMeta`: bio, bio link, follower and following counts, total hearts and account creation date. Looking for a TikTok video data extractor? `videoMeta` holds width, height, duration, quality, cover, subtitle tracks and, when you download videos, the link to the stored file.

Each record also has a second, simpler set of fields with the same values (`title`, `views`, `likes`, `comments`, `shares`, `bookmarks`, `channel`, `uploadedAt`, `video`, `song` and more; the output section maps them one to one), plus post settings such as `duetEnabled`, `stitchEnabled`, `commentsDisabled` and `isAigc`. The `input` field tells you which of your input lines a record came from.

> **Note:** Every post record has the same fields, but some are empty (`null`) when they don't apply: `textLanguage` and `locationCreated` when TikTok doesn't show them, `locationMeta` when the post has no tagged place, `playlistMeta` for posts outside the Playlists section, `commentsDatasetUrl` when no comments were collected for the post, `commentsScraped` when comments are off, and `transcript` when no transcript was created (if a transcript fails, `transcriptionError` gives the reason). `authorMeta.region` is always `null`, because TikTok doesn't show it to visitors who aren't logged in.

The ready-made table views help you read the data in the Output tab: **Overview**, **Engagement**, **Author**, **Video & media**, **Music**, **Hashtags, mentions & location**, **Simple view** and **Notes & errors**.

#### What data can't TikTok Profile Scraper extract?

- Posts of private accounts (you get one note row with the public profile data instead)
- Data that needs a TikTok login, such as a user's liked or favorite videos, private videos or your own account analytics
- Expired stories (only the currently active story)
- Hashtag pages, keyword search results or sound pages: the input must be profiles
- Engagement rates or other calculated metrics (you get the raw counts and can calculate them yourself)

If comments are your main goal, see [TikTok Comments & Replies Scraper](https://apify.com/insights_data/tiktok-comments-replies-scraper), which extracts TikTok comments and replies from videos, photo posts and whole profiles.

***

### How to scrape TikTok videos from a profile

TikTok Profile Scraper is designed for an easy start, even if you've never extracted data from the web before. If you're wondering how to scrape TikTok without code, follow these steps.

1. [Create a free Apify account](https://console.apify.com/sign-up) using your email.
2. Open [TikTok Profile Scraper](https://apify.com/insights_data/tiktok-profile-scraper).
3. In **TikTok profile URLs or usernames** (`urls`), add one profile per line, for example `https://www.tiktok.com/@nike` or `@nike`. To paste a column from your spreadsheet, use **Bulk edit**.
4. (Optional) Want only recent videos? In **Posts published on or after**, type `30 days` (or a date such as `2026-09-01`) and keep **Profile video sorting** on **Latest**. The Videos section then stops as soon as it reaches older posts.
5. Click **Start**. Posts appear in the **Output** tab while the run is going.
6. Download your data in JSON, CSV, Excel, XML or HTML. For a clean spreadsheet, see **Getting it into a spreadsheet** in the output section.

#### Recommended first run

Keep the prefilled input: one profile (`https://www.tiktok.com/@nike`), the **Videos** section, **Latest** sorting and 10 posts. That's up to 10 results, which fits the Free plan cap and costs at most $0.015 in result events (10 × $0.0015 at the Free plan price), plus the start fee and platform usage (see the next section). Check the output, then add more profiles, sections or extras.

**Testing your own creator list on the Free plan?** The 10-result cap is shared by the whole run, not counted per profile. Profiles are processed in parallel, so results arrive in the order they finish, not in your list order, and with a long list you can't predict which creators make it into the 10. To see every creator, keep the list short and lower **Max posts per profile**: for example, 5 creators × 2 posts = 10 results. Leave followers, comments and the profile summary row off for this test, because they count toward the same 10 results. Note rows for private or missing profiles don't use up any of the 10.

***

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

TikTok Profile Scraper uses **pay-per-event** pricing. Your bill has three parts:

| Part | Price |
|---|---|
| 💲 Results | **$1.50 per 1,000 results** ($0.0015 per result) on the Free plan (lower on paid plans, see below) |
| 🚀 Actor start | A tiny fee each time a run starts: **$0.0002 per run** with the default settings. It's priced at $0.00005 per GB of run memory (the amount of computer memory Apify reserves for the run), and this Actor's default is 4 GB, so you don't need to change anything. If you change the memory in the run options, the start fee changes with it. |
| ⚙️ Apify platform usage | The computing time, storage and proxy traffic your run uses, paid on top of the event prices. It changes from run to run, so there's no fixed number up front. After a small test run, open the run's detail page in Apify Console to see what it used. |

| Apify plan | Price per result | Price per 1,000 results |
|---|---|---|
| Free | $0.0015 | $1.50 |
| Starter | $0.00125 | $1.25 |
| Scale | $0.001 | $1.00 |
| Business and higher | $0.00075 | $0.75 |

Paid Apify plans get a lower result price. The plan discount applies to that price only. The start fee is the same on every plan, and platform usage is billed at your Apify plan's own rates.

Example result costs at the Free plan price (the start fee and platform usage come on top):

| Results saved | Result cost |
|---|---|
| 10 (the recommended first run) | $0.015 |
| 100 (for example 5 profiles × 20 posts; needs a paid plan, so the real cost is lower, see the plan table above) | $0.15 |
| 1,000 | $1.50 |

So scraping 1,000 posts costs $1.50 in result events at the Free plan price (from $1.25 down to $0.75 on paid plans) plus $0.0002 for the Actor start, plus platform usage. We recommend a small test run first to see the real total for your settings, then scale up. See the [pricing tab](https://apify.com/insights_data/tiktok-profile-scraper/pricing) for the current events.

#### What counts as a result?

- **Charged:** every saved post (video, repost, story or playlist video), every profile summary row (when `includeProfileRecord` is on), every follower or following row, and every comment or reply.
- **Not charged:** note rows (private, empty, not found or invalid inputs), records your `customMapFunction` drops, and posts that fail during processing (they aren't saved either).
- Media downloads, subtitles and transcripts have no event price of their own, but they make the run longer and store files, which adds to platform usage.

Set a maximum cost per run in the run options to control your spend. When it's reached, the run stops cleanly and keeps the results already saved.

#### What does "Apify Proxy" mean for my account and costs?

Apify Proxy is Apify's own proxy service: it sends the run's requests through other IP addresses. You don't need it to start; the Actor only switches to it by itself when TikTok blocks the requests. Which proxy access an account has depends on its Apify plan, and you can check yours in the **Proxy** section of Apify Console. Proxy traffic counts as platform usage. If your account can't use Apify Proxy, the run carries on without it; profiles that TikTok keeps blocking can then return fewer posts or a note row.

#### Is scraping TikTok free?

You can try it for free. The Apify Free plan includes $5 of monthly platform credit, which pays for both the event charges and the platform usage of your runs.

Separately, the Actor limits Free plan runs to **10 results per run in total**, counted across posts, profile summary rows, followers and following, and comments. On the Free plan, **Max posts per profile** (`resultsPerPage`) is also reduced to 10 if you set a higher number. The run log shows this limit at the start of every Free plan run. When a run reaches 10 results, it stops, the status message shows the free plan limit, and the run still finishes with a success status. There's no monthly limit from the Actor. To test several creators, see the creator-list tip under **Recommended first run**. Paid plans don't have this cap; your own settings, the stop conditions and your spend limit still apply.

***

### TikTok Profile Scraper input

To run TikTok Profile Scraper, you only need **one or more profiles** in `urls`. Every other field has a default or is optional, so you can start with a single line.

Here's an example that collects the 10 newest videos from Nike's profile:

```json
{
  "urls": ["https://www.tiktok.com/@nike"],
  "profileScrapeSections": ["videos"],
  "profileSorting": "latest",
  "resultsPerPage": 10
}
```

See the [input tab](https://apify.com/insights_data/tiktok-profile-scraper/input-schema) for a full description of all fields.

| Field | What it does | Default |
|---|---|---|
| `urls` | Profile URLs, video URLs of the profile, usernames or numeric user IDs (required) | none |
| `profileScrapeSections` | `videos`, `reposts`, `stories`, `playlists` (any combination) | `["videos"]` |
| `profileSorting` | `latest`, `popular` or `oldest`; applies to the Videos section only | `latest` |
| `resultsPerPage` | Max posts per profile, per selected section | `10` |
| `oldestPostDateUnified` / `newestPostDate` | Date window (UTC) | empty |
| `leastDiggs` / `mostDiggs` | Minimum hearts (inclusive) / hearts below (exclusive) | empty |
| `leastPlays` / `mostPlays` | Minimum views (inclusive) / views below (exclusive) | empty |
| `postTypes` | `all`, `videos` or `slideshows` | `all` |
| `filterHashtags` / `filterKeywords` | Keep posts with any of these hashtags / caption words (not case-sensitive) | empty |
| `excludePinnedPosts` | Skip pinned posts | `false` |
| `maxFollowersPerProfile` / `maxFollowingPerProfile` | Follower / followed accounts per profile (0 = off) | `0` |
| `commentsPerPost`, `topLevelCommentsPerPost`, `maxRepliesPerComment` | Comment limits per post | `0` |
| `shouldDownloadVideos`, `shouldDownloadCovers`, `shouldDownloadSlideshowImages`, `shouldDownloadAvatars`, `shouldDownloadMusic` | Save these files to a key-value store | `false` |
| `downloadSubtitlesOptions` | Subtitles and transcription mode | `NEVER_DOWNLOAD_SUBTITLES` |
| `transcriptionModel` / `transcriptionLanguage` | `tiny`, `base`, `small`, `medium` or `large-v3`; optional two-letter language code | `base` / auto-detect |
| `videoKvStoreIdOrName` | Name or ID of the key-value store for downloaded files | the run's default store |
| `includeProfileRecord` | Add one profile summary row per profile | `false` |
| `customMapFunction` | Optional Python that reshapes each record | empty |
| `concurrency`, `max_retries`, `request_delay` | Parallel profiles, retries per request, pause before each request (0 to 10 seconds) | `4`, `3`, `0` |
| `proxyConfiguration` | Optional proxy to start the run with | no proxy |

API callers can also send `profiles`, `startUrls` and `usernames` (merged with `urls`), plus `until` and `since`. Careful, the names can feel reversed: `until` means "posts **newer** than this date" (the same as `oldestPostDateUnified`), and `since` means "posts **older** than this date" (the same as `newestPostDate`). `until` is used only when `oldestPostDateUnified` is empty, and `since` only when `newestPostDate` is empty.

#### TikTok profile URLs or usernames (`urls`)

Each line is one profile. You can also separate profiles with commas and paste a whole list with **Bulk edit**. Profiles are de-duplicated by username (not case-sensitive), user ID or URL; the same account given once as a username and once as a numeric ID isn't merged.

- ✅ Good: `https://www.tiktok.com/@nike`, `@nike`, `nike`, a video URL of the profile, a numeric user ID
- ❌ Bad: a hashtag, search or sound link such as `https://www.tiktok.com/tag/running`. Any line that looks like a link is accepted, but if it doesn't lead to a profile you get a not-found note row (not charged) instead of posts.
- ❌ Bad: text that is neither a link nor a valid username or ID, such as `nike official`. It's skipped with an invalid-input note row (not charged).

#### Max posts per profile (`resultsPerPage`)

The limit counts **per profile and per selected section**. With Videos and Reposts selected and `resultsPerPage` set to 50, you can get up to 100 posts per profile. All playlists of a profile share one limit. Posts that your filters remove don't count toward the limit.

A section stops when it reaches `resultsPerPage`, when TikTok has no more posts or stops returning the section, when the date window is passed (Videos section with Latest or Oldest sorting), or at an internal page limit on very large profiles. The whole run stops at the Free plan cap or at your spend limit.

- ✅ Good: `10` for a first test, or `2` when you test 5 creators on the Free plan
- ❌ Bad: expecting 50 posts in total when two sections are selected (that's up to 100)

> ⚠️ A profile can return fewer posts than you asked for. On the Free plan, the value is reduced to 10 and the run stops at 10 results in total.

#### Date filters (`oldestPostDateUnified`, `newestPostDate`)

**Posts published on or after** is the older end of your window: it keeps posts from that date onward. It accepts a date (`YYYY-MM-DD`) or a relative value such as `30 days` (`1 day` = today only, `2 days` = yesterday and today; a week counts as 7 days, a month as 30 and a year as 365). **Posts published on or before** is the newer end of your window and includes the whole day until 23:59:59. All dates are UTC, so "today" follows UTC time, which can differ from your local date.

With Latest or Oldest sorting, the Videos section stops paging as soon as a post falls outside your window (pinned posts don't trigger this stop), which saves time.

- ✅ Good: `"oldestPostDateUnified": "30 days"` with `"profileSorting": "latest"`
- ❌ Bad: date filters with Popular sorting

> ⚠️ Popular sorting is limited by TikTok to roughly the 400 to 500 most popular videos of a profile. With Popular, date filters only filter those videos and can't stop early.

#### Followers and following (`maxFollowersPerProfile`, `maxFollowingPerProfile`)

**Followers per profile** collects follower accounts, and **Following per profile** collects the accounts a profile follows. Both are saved in the separate **Followers and following** dataset, with `type` set to `follower` or `following`. A list stops at your number, when TikTok has no more accounts, when a page brings no new accounts, or at an internal page limit.

- ✅ Good: `"maxFollowersPerProfile": 100`
- ❌ Bad: expecting the lists of accounts that hide them. If a list is hidden by the account owner, `authorMeta.followListError` tells you.

> ⚠️ Every follower and following row is a charged result.

#### Comments and replies (`commentsPerPost`, `topLevelCommentsPerPost`, `maxRepliesPerComment`)

Comments are collected only when `commentsPerPost` or `topLevelCommentsPerPost` is above 0. `commentsPerPost` caps comments plus replies per post; `topLevelCommentsPerPost` caps top-level comments; `maxRepliesPerComment` sets the replies under each top-level comment. With `commentsPerPost` at 0 and `topLevelCommentsPerPost` above 0, there's no total cap, only the top-level cap plus replies.

- ✅ Good: `"commentsPerPost": 20, "maxRepliesPerComment": 2`
- ❌ Bad: `"maxRepliesPerComment": 5` with both comment caps at 0 (no comments are collected)

> ⚠️ Posts with thousands of comments can return fewer, and collecting every reply isn't guaranteed. Every comment and reply is a charged result.

#### Media downloads (`shouldDownloadVideos` and other download options)

To download TikTok videos from profile pages you scrape, switch on `shouldDownloadVideos`. Covers, slideshow images, profile avatars and music have their own switches. Files go to a key-value store, and the record links (for example `videoMeta.downloadAddr`) point to the stored files. If a download fails, the record keeps the original TikTok link.

The number of downloaded videos follows the posts you collect, so `resultsPerPage`, your filters and the stop conditions above also limit the downloads.

#### Subtitles and transcription (`downloadSubtitlesOptions`)

| Mode | What happens |
|---|---|
| `NEVER_DOWNLOAD_SUBTITLES` | No subtitle files (default) |
| `DOWNLOAD_SUBTITLES` | Saves the subtitle files TikTok provides |
| `DOWNLOAD_AND_TRANSCRIBE_VIDEOS_WITHOUT_SUBTITLES` | Saves the available subtitles and creates a speech-to-text transcript for videos that have no subtitles |
| `TRANSCRIBE_ALL_VIDEOS` | Saves the available subtitles and creates a transcript for each non-slideshow video |

To extract TikTok transcript text, pick one of the two transcription modes. Choose the model with `transcriptionModel` (bigger is more accurate but slower; `large-v3` needs more memory) and optionally set `transcriptionLanguage`.

> ⚠️ Transcription needs the video file. In **both** transcription modes, every non-slideshow video is downloaded and stored in the key-value store, even when `shouldDownloadVideos` is off, and even videos that already have subtitles (and so aren't transcribed in the "without subtitles" mode). Slideshows are never transcribed. Transcription takes extra time per video, so it adds to platform usage. If a transcript fails, the reason is in `transcriptionError` and the run continues.

#### Storage name for media files (`videoKvStoreIdOrName`)

Leave it empty to use the run's default key-value store, which is removed after the data retention period. Enter a name to keep the files until you delete them.

- ✅ Good: `my-tiktok-files`
- ❌ Bad: `my tiktok files` (use letters, digits and hyphens only)

#### Custom map function (`customMapFunction`)

Optional Python that reshapes each record in the Posts dataset (not followers or comments): one expression over `record`, or a full `def map_function(record):`. Returning `None` drops the record, and dropped records aren't charged. If the function doesn't compile, records are saved unchanged; if it fails on a record, that record is saved unchanged.

- ✅ Good: `{"id": record["id"], "views": record["views"]}`
- ❌ Bad: returning `id` as a number instead of text (keep the original value types)

#### Proxy (`proxyConfiguration`)

You don't need a proxy to start. The Actor starts without a proxy and switches to Apify Proxy by itself when TikTok blocks the requests, if your account can use Apify Proxy (see the cost section). Pick a proxy here only if you want the run to start with it.

***

### TikTok Profile Scraper output

Results are stored in datasets in the **Output** or **Storage** tab. You can view them as a table or JSON and download them in JSON, CSV, Excel, XML or HTML. The Output tab has up to five parts: **Posts**, **Followers and following**, **Comments**, **Media files** and **Profile pictures** (both in the run's default key-value store).

Each record is saved as soon as it's ready, so the output order follows completion, not the order of your profiles. Use `profilePosition` to see a post's position within its section.

#### JSON example

Results for the input example above (one record, shortened):

```json
[
  {
    "id": "7693986066830839054",
    "text": "Kim and Kris take the new NikeSKIMS Shanghai store. Shop their picks online now. ",
    "textLanguage": "en",
    "createTime": 1791395763,
    "createTimeISO": "2026-10-07T17:56:03.000Z",
    "webVideoUrl": "https://www.tiktok.com/@nike/video/7693986066830839054",
    "playCount": 443900,
    "diggCount": 49000,
    "commentCount": 156,
    "shareCount": 638,
    "collectCount": 1820,
    "repostCount": 0,
    "isPinned": false,
    "isSlideshow": false,
    "isAd": false,
    "fromProfileSection": "videos",
    "authorMeta": {
      "name": "nike",
      "nickName": "Nike",
      "verified": true,
      "fans": 9282960,
      "following": 91,
      "heart": 49676613,
      "video": 1095,
      "signature": "Just Do It.",
      "bioLink": "http://empli.fi/niketiktok",
      "createTimeISO": "2017-03-20T21:16:05.000Z"
    },
    "musicMeta": { "musicName": "original sound", "musicAuthor": "Nike", "musicOriginal": true },
    "videoMeta": { "width": 720, "height": 1280, "duration": 84, "definition": "720p", "subtitleLinks": [ { "language": "eng-US", "source": "ASR" } ] },
    "hashtags": [],
    "mentions": [],
    "views": 443900,
    "likes": 49000,
    "channel": { "username": "nike", "name": "Nike", "followers": 9282960 },
    "input": "https://www.tiktok.com/@nike",
    "profilePosition": 1,
    "scrapedAt": "2026-10-08T16:17:45.876Z"
  }
]
```

#### Getting it into a spreadsheet

- **Choose the columns in the export options.** The table views (**Overview**, **Simple view** and the others) only change what you see in the Output tab; a download contains every field unless you list the fields you want under **Select fields** in the export dialog. For a short sheet, select the fields of the **Simple view**: `inputSource`, `channel`, `title`, `views`, `likes`, `comments`, `shares`, `bookmarks`, `uploadedAtFormatted` and `postPage`.
- **Nested fields become several columns.** Blocks such as `authorMeta`, `videoMeta`, `musicMeta` or `channel` are split into one column per inner field in CSV and Excel files.
- **Some values appear twice under different names.** They hold exactly the same value, so you only need one of each pair:

| Simple field | Same value as |
|---|---|
| `title` | `text` (caption) |
| `views` | `playCount` |
| `likes` | `diggCount` (hearts on the post) |
| `comments` | `commentCount` |
| `shares` | `shareCount` |
| `bookmarks` | `collectCount` (saves) |
| `uploadedAt` / `uploadedAtFormatted` | `createTime` / `createTimeISO` |
| `postPage` | `webVideoUrl` |
| `inputSource` | `input` |
| `channel.followers` | `authorMeta.fans` |
| `channel.likes` | `authorMeta.heart` (the creator's total hearts, not the post's) |

- **Note rows are in the same file.** Private, missing or invalid profiles get a note row in the Posts dataset (see **Note rows** below). In your sheet, filter out rows where `id` is empty to keep only posts. Profile summary rows (when **Add a profile summary row** is on) also have an empty `id`, so keep them aside if you need them.

#### Followers and following dataset

Open the **Followers and following** output to export TikTok followers. Each row is one account: `type` (`follower` or `following`), `sourceProfile`, `sourceProfileUrl`, `id`, `name`, `nickName`, `profileUrl`, `signature`, `verified`, `privateAccount`, `fans`, `following`, `heart`, `video`, `friends`, `relation` and `scrapedAt`. To export TikTok following lists only, filter on `type` = `following`. Each post record links to this dataset in `authorMeta.followDatasetUrl`.

#### Comments dataset

Open the **Comments** output to export TikTok comments. Each row is one comment or reply: `videoId`, `videoWebUrl`, `cid`, `text`, `createTimeISO`, `diggCount`, `replyCommentTotal`, `isReply`, `parentCid`, `isAuthorLiked`, `commentLanguage`, `uniqueId`, `nickname`, `profileUrl` and `scrapedAt`. The comments of a post are saved right after the post, and the post links to them in `commentsDatasetUrl`.

#### Note rows

Every input is accounted for, unless the run stops early at the Free plan cap or your spend limit; in that case, profiles that haven't started yet get no row. A private profile, a profile that can't be found or loaded, an empty or unavailable section, an invalid input line or a profile that stops with an error gets one note row in the Posts dataset, with `note`, `error` and, when there is one, `errorCode`. Note rows have an empty `id`, aren't charged and don't count toward the Free plan cap. Open the **Notes & errors** view to see them, and see **If something goes wrong** below for what each code means.

***

### TikTok Profile Scraper tips and advanced usage

#### How many results can you scrape with TikTok Profile Scraper?

There's no fixed total on paid plans. Each profile returns up to `resultsPerPage` posts per selected section. The real number depends on how many posts the profile has, your filters and sections, the date window, TikTok's rate limits, the internal page limit on very large profiles or lists, the Free plan cap and your spend limit. The best way to know for your profiles is a quick test run.

#### How to get faster or cheaper results

- Start with the default 10 posts per profile and only the sections you need.
- Use date filters with Latest or Oldest sorting, so the Videos section stops once it passes your window.
- Leave followers, comments, downloads and transcription off unless you need them. Comments and followers add charged results; downloads and transcripts add platform usage.
- Use the `base` or `tiny` transcription model for large batches.
- Set a maximum cost per run in the run options.

#### How to track TikTok stats over time

Each run is a snapshot of the numbers at that moment, so there's no built-in TikTok stats tracker with history. To build one, save your input as a task, [schedule it](https://docs.apify.com/platform/schedules) daily or weekly, and compare the datasets by `scrapedAt`. Add `includeProfileRecord` if you want one summary row per profile with follower, heart and video counts.

#### If something goes wrong

- **The run failed right away:** the status message on the run page names the input problem, for example that no profiles were given or that a setting has an invalid value. Fix the input and start again.
- **A creator is missing from the results:** open the **Notes & errors** view. Each problem profile has a note row (if the run stopped early at the Free plan cap or your spend limit, profiles that hadn't started yet have none), and its `errorCode` field tells you what to do:

| `errorCode` | What it means | What to do |
|---|---|---|
| `NOT_FOUND` | The profile doesn't exist, or the line isn't a profile link; for a numeric user ID or short link, the lookup may also have been blocked or failed to load | Check the spelling of the username, or replace a hashtag, search or sound link (or a user ID or short link) with the profile link |
| `INVALID_INPUT` | The line isn't a link, a username or a numeric ID | Fix the line: use `@name`, `name` or the profile URL, without spaces |
| `PROFILE_UNAVAILABLE` | TikTok didn't return the profile during this run | Run that profile again in a new run |
| `SECTION_UNAVAILABLE` | One section (videos, reposts, story or playlists) couldn't be loaded | Run that profile again in a new run |
| `EXCEPTION` | Collecting this profile stopped with an error | Run that profile again on its own; if the same code comes back, report it (see below) |
| empty | The profile is private, or the section is empty or hidden | Nothing to fix; there are no public posts to collect there |

- **Fewer results than expected:** see the FAQ "Why am I getting fewer results than expected?" below.
- **TikTok blocks the run:** the Actor switches to Apify Proxy by itself when your account can use it (see the proxy notes in the cost section). If a run ends with a failed status and nothing saved, try again later.
- **Still stuck?** Open an issue on the [Issues tab](https://apify.com/insights_data/tiktok-profile-scraper/issues/open) and include your run link.

Note rows are never charged, so problem profiles don't cost you anything.

#### Known issues

- When TikTok limits a profile's video list, only the newest videos can be collected for that profile, and those post records have the `note` field filled to say so.
- When TikTok keeps limiting profile requests, `authorMeta.createTimeISO` (account creation date) and `authorMeta.language` can stay empty for the remaining profiles, and `authorMeta.isLive` (live status) can show `false` even for an account that is live.
- Posts are de-duplicated across the sections of one profile (a video already saved from Videos is skipped in Playlists), but not across profiles. The same reposted video from two profiles can be saved, and charged, twice.
- A failed media download keeps the original TikTok link, and the file isn't stored.

***

### Integrations and API

#### Can I use TikTok Profile Scraper as a TikTok profile API?

Yes, if you mean calling it from your own code. Through the [Apify API](https://docs.apify.com/api/v2) you send the input as JSON, start a run and read the records back from the dataset. Use the `apify-client` [NPM package](https://apify.com/insights_data/tiktok-profile-scraper/api/javascript) for Node.js or the `apify-client` [PyPI package](https://apify.com/insights_data/tiktok-profile-scraper/api/python) for Python, and see the [API tab](https://apify.com/insights_data/tiktok-profile-scraper/api) for ready-to-use code.

It isn't the official TikTok API and isn't connected to TikTok. It's an Apify Actor that you call through the Apify API, and it reads the public data any visitor can see.

#### TikTok scraper Python example

This short script calls the Actor as a TikTok scraper API from Python: it runs the input example above and prints each post.

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")
run_input = {
    "urls": ["https://www.tiktok.com/@nike"],
    "profileScrapeSections": ["videos"],
    "profileSorting": "latest",
    "resultsPerPage": 10,
}
run = client.actor("insights_data/tiktok-profile-scraper").call(run_input=run_input)

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item.get("webVideoUrl"), item.get("playCount"), item.get("diggCount"))
```

Note rows and profile summary rows have `webVideoUrl` set to `null`, so they print `None`.

#### Can I integrate TikTok Profile Scraper with other apps?

Yes. Connect this TikTok data extractor through [Apify integrations](https://apify.com/integrations): **Make, Zapier, Slack, Google Sheets, Google Drive, Airbyte, GitHub, LangChain** and more. Use [webhooks](https://docs.apify.com/integrations/webhooks) to trigger actions when a run finishes. For example, schedule a weekly run for your competitors' profiles and send the new rows to Google Sheets, where your team compares views and hearts.

#### Can I use TikTok Profile Scraper with AI agents (MCP)?

Yes. Connect it to Claude and other AI assistants through the Apify MCP server. Open the [MCP tab](https://apify.com/insights_data/tiktok-profile-scraper/api/mcp) for setup steps. The agent can then use it as a TikTok profile data extractor: it fills in the input and reads the posts back as JSON.

***

### Other scrapers from Insights Data

These Actors from the same author cover TikTok comments and other social, market and job data:

| Actor | What it does |
|---|---|
| 💬 [TikTok Comments & Replies Scraper](https://apify.com/insights_data/tiktok-comments-replies-scraper) | Extracts TikTok comments and replies from videos, photo posts and whole profiles: text, likes, reply counts, dates, mentions and commenter details (bio, verified badge) as JSON |
| 📈 [Stocktwits Scraper](https://apify.com/insights_data/stocktwits-scraper) | Scrapes Stocktwits stock and crypto messages, bullish/bearish sentiment, price targets and trending symbols |
| 📢 [Google Ads Transparency Center Scraper & API](https://apify.com/insights_data/google-ads-transparency-center-scraper-api) | Extracts ads across Search, YouTube, Shopping, Maps and Play by brand, domain or advertiser ID, for competitor ad intelligence |
| 💼 [Advanced LinkedIn Job Search API](https://apify.com/insights_data/advanced-linkedin-job-search-api) | Scrapes public LinkedIn jobs by search URL, job URL or title and location, with title, company, salary, seniority, applicants and full description |

***

### TikTok Profile Scraper FAQ

#### Is it legal to scrape TikTok?

TikTok Profile Scraper only reads public data that anyone can see without logging in. Whether scraping is allowed for your project depends on your country, the data you collect and how you use it. Results can contain personal data (usernames, bios, comments), which laws such as GDPR protect, so only collect it with a legitimate reason. Videos and music can also be protected by copyright. Take [TikTok's Terms of Service](https://www.tiktok.com/legal/page/us/terms-of-service/en) into account. This is not legal advice; if you're unsure, ask a lawyer.

#### How does TikTok Profile Scraper work?

It works like a visitor browsing a public profile, only faster. You add profiles. The Actor opens each profile, reads the profile details, then goes through the selected sections page by page, applies your filters and saves every matching post as soon as it's ready. If you ask for them, it also collects followers and following, comments and replies, downloads media files, fetches subtitles and creates transcripts. Private, empty or unknown profiles get a note row. If TikTok blocks the requests, it retries and switches to Apify Proxy by itself, when your account can use Apify Proxy.

#### How is TikTok Profile Scraper different from TikTok Comments & Replies Scraper?

| | TikTok Profile Scraper | TikTok Comments & Replies Scraper |
|---|---|---|
| Main output | One record per post with author, music, video, hashtag and engagement data | Comments and replies with text, likes, reply counts, dates, mentions and commenter details |
| Best for | Posts and creator stats; also works as a TikTok video scraper when you switch on video downloads | Comment research |
| Comments | Optional add-on, saved in a separate Comments dataset | The main output |
| TikTok account or cookies | Not needed | Not needed |

Pick TikTok Profile Scraper when you need a TikTok user profile scraper for posts and creator stats, and the [comments Actor](https://apify.com/insights_data/tiktok-comments-replies-scraper) when comments are the focus.

#### Why scrape TikTok profile data?

Manual checks don't scale when you follow dozens of creators. With structured data you can:

- **Build a TikTok influencer database:** run the Actor on the creators you're considering and keep the results as your own dataset. The Actor isn't a database and doesn't search creators for you; you choose the profiles.
- **Build a TikTok creator database for outreach:** keep usernames, bios, bio links, follower counts and verified status in one table, the same details a TikTok user info scraper would give you.
- **Benchmark brands:** compare views, hearts, shares and posting dates across competitors.
- **Find what works:** see which hashtags, sounds and caption topics get the most views.
- **Feed AI tools:** use captions and transcripts in LLM, search or classification pipelines.

#### Can I use it as a TikTok user scraper for profile stats only?

Partly. Turn on **Add a profile summary row** (`includeProfileRecord`) to get one row per profile with author data and statistics. Posts are always collected as well, so set **Max posts per profile** to 1 to keep it small; each profile then gives up to 2 charged results (the summary row and one post). Called through the API, the summary row works like a TikTok user profile API response for author stats.

#### How do I extract TikTok captions and sound data?

Every post record has the caption in `text` (also in `title`) and the sound details in `musicMeta`: sound name, artist, album, original sound flag, duration and audio link. To extract TikTok sound files as well, switch on **Download music**.

#### How to scrape TikTok followers?

Set **Followers per profile** (`maxFollowersPerProfile`) to the number you want, then open the **Followers and following** output. For the accounts a profile follows, set **Following per profile** too; that part works as a TikTok following scraper for the same profiles. Lists hidden by the account owner can't be collected.

#### How to scrape TikTok accounts in bulk?

Add one profile per line, or paste a whole spreadsheet column with **Bulk edit**. Duplicates are removed, and every account gets either posts or a note row, unless the run stops early at the Free plan cap or your spend limit (profiles that haven't started yet then get no row). Each post carries the account details in `authorMeta`, so a run doubles as a TikTok account data extractor for your whole list. On the Free plan, remember the shared 10-result cap (see **Recommended first run**).

#### Can I download TikTok videos from username or profile URL?

Yes. Add the username (for example `@nike`) or the profile URL, and switch on **Download videos** (`shouldDownloadVideos`). This TikTok profile video scraper then saves each video to the key-value store, and `videoMeta.downloadAddr` points to each stored file. The number of videos follows `resultsPerPage` and your filters.

#### Can it scrape private TikTok accounts?

No. For a private account you get one note row with the public profile data and no posts, and that note row isn't charged. If you asked for followers, following or a profile summary row, the Actor tries those before it sees that the account is private: a summary row is saved and charged like for any other profile, and follower or following rows are charged only if TikTok actually returns them. A hidden list returns nothing, costs nothing, and `authorMeta.followListError` tells you it was hidden.

#### Why am I getting fewer results than expected?

- Check `resultsPerPage`: it counts per profile and per section, and the default is 10.
- On the Free plan, a run saves at most 10 results in total, across all record types.
- Your filters (date, hearts, views, post type, hashtags, caption words, pinned) may remove posts.
- With Latest or Oldest sorting and a date filter, the Videos section stops when it passes your window.
- Popular sorting covers roughly the 400 to 500 most popular videos.
- The profile may have fewer posts, be private, or have no story or playlists. Look at the **Notes & errors** view.
- Very large profiles or lists can stop at an internal page limit before your number.
- Check whether the run hit your spend limit.

***

### Support and feedback

Found a bug or have a feature request? Please create an issue on the [Issues tab](https://apify.com/insights_data/tiktok-profile-scraper/issues/open) and include your run link.

Need a **custom solution**, another field or help with a TikTok data project? Contact us at hello.insights.data@gmail.com.

Built and maintained by [Insights Data](https://apify.com/insights_data).

# Actor input Schema

## `urls` (type: `array`):

One or more TikTok profiles. Each line can be a profile URL (https://www.tiktok.com/@nike), a video URL of the profile, a username with or without @ (nike, @nike) or a numeric user ID. Use Bulk edit to paste a whole list.

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

Which parts of each profile to collect. Videos = the profile's own posts, Reposts = videos the account reposted, Stories = the currently active story, Playlists = every video inside the profile's playlists.

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

Latest = newest videos first, Oldest = oldest videos first, Popular = most popular videos first. Date filters work best with Latest and Oldest. Popular is limited by TikTok to roughly the 400-500 most popular videos of a profile. Applies to the Videos section only.

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

How many posts to collect from every profile (per selected section). Free plan users get up to 10 results per run in total (posts, followers and comments together); paid Apify plans have no limit.

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

Only posts uploaded on or after this date are collected. Pick a date (YYYY-MM-DD) or a relative value: 1 day = today only, 2 days = yesterday and today, and so on.

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

Only posts uploaded on or before this date (YYYY-MM-DD) are collected.

## `leastDiggs` (type: `integer`):

Only posts with at least this many hearts (likes).

## `mostDiggs` (type: `integer`):

Only posts with fewer hearts (likes) than this number.

## `leastPlays` (type: `integer`):

Only posts with at least this many views.

## `mostPlays` (type: `integer`):

Only posts with fewer views than this number.

## `postTypes` (type: `string`):

Collect all posts, only videos, or only photo slideshows.

## `filterHashtags` (type: `array`):

Keep posts that carry ANY of these hashtags (with or without #). Leave empty to keep all.

## `filterKeywords` (type: `array`):

Keep posts whose caption contains ANY of these words (not case-sensitive). Leave empty to keep all.

## `excludePinnedPosts` (type: `boolean`):

Skip the posts the creator pinned to the top of the profile.

## `maxFollowersPerProfile` (type: `integer`):

Number of follower accounts to collect from each profile. They are saved in the separate Followers output; the link is in authorMeta.followDatasetUrl. 0 = off.

## `maxFollowingPerProfile` (type: `integer`):

Number of followed accounts to collect from each profile, saved in the Followers output with type "following". 0 = off.

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

Maximum comments (replies included) to collect from every post. They are saved in the separate Comments output; the link is in commentsDatasetUrl. The real number can be lower for posts with thousands of comments. 0 = off.

## `topLevelCommentsPerPost` (type: `integer`):

Maximum top-level (non-reply) comments per post. 0 = no separate cap.

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

Maximum replies to collect under each top-level comment. Collecting every reply is not guaranteed. 0 = no replies.

## `shouldDownloadVideos` (type: `boolean`):

Save every video file to the key-value store; videoMeta.downloadAddr then points to the stored file.

## `shouldDownloadCovers` (type: `boolean`):

Save every post's cover image (thumbnail).

## `shouldDownloadSlideshowImages` (type: `boolean`):

Save every image of photo slideshow posts.

## `shouldDownloadAvatars` (type: `boolean`):

Save the author's profile picture.

## `shouldDownloadMusic` (type: `boolean`):

Save the sound used in each post.

## `downloadSubtitlesOptions` (type: `string`):

Download the subtitles TikTok provides and/or create a speech-to-text transcript of the video. Transcription needs the video file and takes extra time per video.

## `transcriptionModel` (type: `string`):

Speech-to-text model size. Bigger models are more accurate but slower.

## `transcriptionLanguage` (type: `string`):

Optional two-letter language code (for example en, es, de). Leave empty to detect the language automatically.

## `videoKvStoreIdOrName` (type: `string`):

Name or ID of the key-value store that receives downloaded files. A named store keeps files until you delete it; leave empty to use the run's default store (removed after the data retention period). Letters, digits and hyphens only.

## `includeProfileRecord` (type: `boolean`):

Also save one summary row per profile (author data and statistics only, no post fields).

## `customMapFunction` (type: `string`):

Optional Python that reshapes every record before it is saved: either one expression over record (for example {"id": record\["id"], "views": record\["views"]}) or a full def map_function(record): ... that returns the new record. Returning None drops the record. Keep the original value types of the fields you keep (for example id stays text), otherwise the record cannot be saved. Not meant for filtering.

## `concurrency` (type: `integer`):

How many profiles and requests run at the same time.

## `max_retries` (type: `integer`):

How many times a failed request is retried before it is given up.

## `request_delay` (type: `number`):

Optional pause before each request. 0 = as fast as possible.

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

Same as TikTok profile URLs or usernames; kept for API callers that already send this key.

## `startUrls` (type: `array`):

TikTok profile URLs; merged with the main profile list. Kept for API compatibility.

## `usernames` (type: `array`):

TikTok usernames without @; merged with the main profile list. Kept for API compatibility.

## `until` (type: `string`):

Returns posts newer than this date (YYYY-MM-DD). Used only when Posts published on or after is empty.

## `since` (type: `string`):

Returns posts older than this date (YYYY-MM-DD). Used only when Posts published on or before is empty.

## `proxyConfiguration` (type: `object`):

By default the Actor starts without a proxy. If TikTok blocks the requests it switches to a datacenter proxy, then to a residential proxy, and keeps the residential proxy for the rest of the run. Pick a proxy here to start with it instead.

## Actor input object example

```json
{
  "urls": [
    "https://www.tiktok.com/@nike"
  ],
  "profileScrapeSections": [
    "videos"
  ],
  "profileSorting": "latest",
  "resultsPerPage": 10,
  "postTypes": "all",
  "excludePinnedPosts": false,
  "maxFollowersPerProfile": 0,
  "maxFollowingPerProfile": 0,
  "commentsPerPost": 0,
  "topLevelCommentsPerPost": 0,
  "maxRepliesPerComment": 0,
  "shouldDownloadVideos": false,
  "shouldDownloadCovers": false,
  "shouldDownloadSlideshowImages": false,
  "shouldDownloadAvatars": false,
  "shouldDownloadMusic": false,
  "downloadSubtitlesOptions": "NEVER_DOWNLOAD_SUBTITLES",
  "transcriptionModel": "base",
  "includeProfileRecord": false,
  "concurrency": 4,
  "max_retries": 3,
  "request_delay": 0,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

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

All collected posts with author, music, video, hashtag and engagement data.

## `followers` (type: `string`):

Follower and following accounts of each profile (only when requested).

## `comments` (type: `string`):

Comments and replies of each collected post (only when requested).

## `media` (type: `string`):

Downloaded videos, covers, images, avatars, music, subtitles and transcripts stored in the run's default key-value store (only when downloads are switched on and no storage name is given).

## `avatars` (type: `string`):

Downloaded profile pictures in the run's default key-value store (only when profile picture downloads are switched on and no storage name is given).

# 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 = {
    "urls": [
        "https://www.tiktok.com/@nike"
    ],
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("insights_data/tiktok-profile-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 = {
    "urls": ["https://www.tiktok.com/@nike"],
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("insights_data/tiktok-profile-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 '{
  "urls": [
    "https://www.tiktok.com/@nike"
  ],
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call insights_data/tiktok-profile-scraper --silent --output-dataset

```

## MCP server setup

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