# TikTok Scraper — Profiles, Posts & Video Details (`scrapingmonkey/tiktok-scraper`) Actor

Extract TikTok profiles, recent posts, video and photo details, photo search results, playlists, and LIVE status with low-traffic HTTP requests.

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

## Pricing

from $1.50 / 1,000 tiktok 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## TikTok Scraper — Profiles, Posts, Videos, Photos and LIVE Status

Extract structured public TikTok data with low-traffic HTTP requests. The Actor does not start Chrome, Playwright, or another browser and does not require a TikTok account, cookies, or an API key.

- Collect complete public profile identity, biography, counts, avatars, and account flags
- Return one profile row plus up to 22 recent media rows for each username
- Enrich recent posts with complete public engagement, author, music, hashtag, video, and photo data
- Extract individual video and photo/slideshow details from URLs or IDs
- Paginate public TikTok Photo Search results
- Resolve public creator playlist metadata and LIVE status
- Process inputs concurrently with retry, proxy-session rotation, filtering, sorting, and deduplication
- Export one stable 113-field contract through a single Results table

### What can you do with this Actor?

| Mode | Input | Output | Best for |
| --- | --- | --- | --- |
| `auto` | Supported TikTok URLs | Automatically detected profile, media, playlist, or LIVE rows | Mixed URL batches |
| `profile` | Usernames or profile URLs | Public identity, biography, avatars, counts, and account flags | Creator research |
| `profilePosts` | Usernames or profile URLs | One profile row plus up to 22 recent video/photo rows | Creator content monitoring |
| `video` | Video URLs or numeric IDs | Complete public video metadata | Post and campaign analysis |
| `photo` | Photo URLs or numeric IDs | Slideshow metadata and ordered image URLs | Visual content research |
| `searchPhotos` | Keywords | Paginated public Photo Search rows | Visual trend discovery |
| `playlist` | Complete playlist URLs | Matching public playlist metadata | Series and collection research |
| `liveStatus` | Usernames, LIVE URLs, or room IDs | Public room availability/status | Stream monitoring |

Top Search, Video Search, User Search, hashtag/music feeds, Explore, For You, and LIVE discovery are intentionally not advertised: current public web routes require short-lived TikTok signatures or a live browser session. Removing those modes keeps the Actor fast and economically sustainable.

### Quick start

1. Select **Profile and recent posts**.
2. Enter one or more usernames such as `tiktok` or `nasa`.
3. Keep `maxResults` at 10 for the first run.
4. Leave HTTP enrichment enabled when complete engagement and media fields are required.
5. Start the Actor and open the single **Results** table.

### Input examples

#### Profile details

```json
{"mode":"profile","targets":["tiktok","nasa"],"maxResults":1,"country":"US","language":"en"}
```

#### Profile plus recent posts

```json
{"mode":"profilePosts","targets":["tiktok"],"maxResults":20,"enrichPartialResults":true,"country":"US"}
```

#### Fast profile posts without per-item enrichment

```json
{"mode":"profilePosts","targets":["tiktok"],"maxResults":20,"enrichPartialResults":false,"country":"US"}
```

#### Auto-detect a mixed URL batch

```json
{"mode":"auto","startUrls":[{"url":"https://www.tiktok.com/@tiktok"},{"url":"https://www.tiktok.com/@axl17_/video/7627482636847435026"}],"maxResults":10}
```

#### Video details

```json
{"mode":"video","startUrls":[{"url":"https://www.tiktok.com/@axl17_/video/7627482636847435026"}]}
```

#### Photo or slideshow details

```json
{"mode":"photo","startUrls":[{"url":"https://www.tiktok.com/@creator/photo/7650904787013127438"}]}
```

#### Photo Search

```json
{"mode":"searchPhotos","searchTerms":["home decor","street style"],"maxResults":50,"country":"US"}
```

#### Playlist metadata

```json
{"mode":"playlist","startUrls":[{"url":"https://www.tiktok.com/@tiktok/playlist/Behind-The-Breakthrough-7659874208872221471"}]}
```

#### LIVE status

```json
{"mode":"liveStatus","targets":["creator","7672717264355003156"],"maxResults":1}
```

`maxResults` applies to media rows for each profile or Photo Search keyword. `profilePosts` also returns one profile row. TikTok's unsigned public embed route currently exposes at most 22 recent profile posts. `maxTotalResults` caps the combined deduplicated run.

### Complete output examples

The implementation always initializes the complete 113-field top-level contract. Optional public data is represented by `null`; list fields use `[]`. No separate dataset error records or Errors view are created. Safe failure counts are written to `RUN_SUMMARY` and the run log. `raw` is `null` unless `includeRaw` is enabled; when enabled it contains a sanitized source-defined TikTok object whose session, cookie, token, signature and device identifiers are removed.

#### Complete `profile` output — 113 top-level fields

The profile details row uses the same stable 113-field contract. Fields that do not apply to this record type are explicitly returned as `null` or `[]`.

```json
{
  "recordType": "profile",
  "resultType": "profile",
  "id": "10001",
  "url": "https://www.tiktok.com/@creator",
  "sourceMode": "profile",
  "sourceTarget": "creator",
  "sourceUrl": "https://www.tiktok.com/@creator",
  "finalUrl": "https://www.tiktok.com/@creator",
  "sourceEndpoints": [
    "/api/example/"
  ],
  "transport": "httpHtml",
  "position": 1,
  "scrapedAt": "2026-08-11T12:00:00Z",
  "country": "US",
  "language": "en",
  "availability": "public",
  "isPartial": false,
  "fallbackUsed": false,
  "username": "creator",
  "nickname": "Creator",
  "authorId": "10001",
  "secUid": "MS4wLjABAAAA_public",
  "signature": "Public profile biography",
  "avatarThumb": "https://p16-sign.tiktokcdn-us.com/avatar.jpeg",
  "avatarMedium": "https://p16-sign.tiktokcdn-us.com/avatar-medium.jpeg",
  "avatarLarge": "https://p16-sign.tiktokcdn-us.com/avatar-large.jpeg",
  "isVerified": true,
  "isPrivate": false,
  "isBusinessAccount": false,
  "bioLink": "https://example.com",
  "followersCount": 1250000,
  "followingCount": 120,
  "friendsCount": 80,
  "heartsCount": 24000000,
  "likesGivenCount": 340,
  "videosCount": 275,
  "description": null,
  "createTime": null,
  "createTimeIso": null,
  "mediaType": null,
  "durationSeconds": null,
  "width": null,
  "height": null,
  "ratio": null,
  "format": null,
  "codecType": null,
  "definition": null,
  "videoUrl": null,
  "downloadUrl": null,
  "coverUrl": null,
  "dynamicCoverUrl": null,
  "originCoverUrl": null,
  "imageUrls": [],
  "imageCount": null,
  "isAd": null,
  "isOriginal": null,
  "isOfficial": null,
  "isSecret": null,
  "isCollected": null,
  "isReviewing": null,
  "commentsEnabled": null,
  "downloadEnabled": null,
  "duetEnabled": null,
  "stitchEnabled": null,
  "textLanguage": null,
  "aigcDescription": null,
  "likesCount": null,
  "commentsCount": null,
  "sharesCount": null,
  "viewsCount": null,
  "savesCount": null,
  "hashtags": [],
  "mentions": [],
  "musicId": null,
  "musicTitle": null,
  "musicAuthor": null,
  "musicAlbum": null,
  "musicUrl": null,
  "musicCoverUrl": null,
  "musicDurationSeconds": null,
  "musicOriginal": null,
  "musicCopyrighted": null,
  "musicCommercial": null,
  "hashtagId": null,
  "hashtagName": null,
  "hashtagTitle": null,
  "hashtagDescription": null,
  "hashtagVideoCount": null,
  "hashtagViewCount": null,
  "playlistId": null,
  "playlistName": null,
  "playlistVideoCount": null,
  "playlistCoverUrl": null,
  "roomId": null,
  "liveStatus": null,
  "isLive": null,
  "liveTitle": null,
  "liveViewerCount": null,
  "liveLikeCount": null,
  "liveStartTime": null,
  "liveCoverUrl": null,
  "liveStreamUrls": [],
  "liveHashtag": null,
  "liveAgeRestricted": null,
  "author": {
    "id": "10001",
    "uniqueId": "creator",
    "nickname": "Creator",
    "avatarThumb": "https://p16-sign.tiktokcdn-us.com/avatar.jpeg",
    "avatarMedium": "https://p16-sign.tiktokcdn-us.com/avatar-medium.jpeg",
    "avatarLarger": "https://p16-sign.tiktokcdn-us.com/avatar-large.jpeg",
    "signature": "Public profile biography",
    "verified": true,
    "secUid": "MS4wLjABAAAA_public",
    "secret": false,
    "ftc": false,
    "relation": 0,
    "openFavorite": true,
    "commentSetting": 0,
    "duetSetting": 0,
    "stitchSetting": 0,
    "privateAccount": false,
    "isADVirtual": false,
    "downloadSetting": 0,
    "isEmbedBanned": false
  },
  "authorStats": {
    "followerCount": 1250000,
    "followingCount": 120,
    "friendCount": 80,
    "heartCount": 24000000,
    "diggCount": 340,
    "videoCount": 275
  },
  "stats": null,
  "video": null,
  "images": null,
  "music": null,
  "hashtag": null,
  "playlist": null,
  "live": null,
  "raw": null
}
```

#### Complete `media-video` output — 113 top-level fields

The video media row uses the same stable 113-field contract. Fields that do not apply to this record type are explicitly returned as `null` or `[]`.

```json
{
  "recordType": "media",
  "resultType": "video",
  "id": "7412345678901234567",
  "url": "https://www.tiktok.com/@creator/video/7412345678901234567",
  "sourceMode": "video",
  "sourceTarget": "https://www.tiktok.com/@creator/video/7412345678901234567",
  "sourceUrl": "https://www.tiktok.com/@creator/video/7412345678901234567",
  "finalUrl": "https://www.tiktok.com/@creator/video/7412345678901234567",
  "sourceEndpoints": [
    "/api/example/"
  ],
  "transport": "httpHtml",
  "position": 1,
  "scrapedAt": "2026-08-11T12:00:00Z",
  "country": "US",
  "language": "en",
  "availability": "public",
  "isPartial": false,
  "fallbackUsed": false,
  "username": "creator",
  "nickname": "Creator",
  "authorId": "10001",
  "secUid": "MS4wLjABAAAA_public",
  "signature": "Public profile biography",
  "avatarThumb": "https://p16-sign.tiktokcdn-us.com/avatar.jpeg",
  "avatarMedium": "https://p16-sign.tiktokcdn-us.com/avatar-medium.jpeg",
  "avatarLarge": "https://p16-sign.tiktokcdn-us.com/avatar-large.jpeg",
  "isVerified": true,
  "isPrivate": false,
  "isBusinessAccount": null,
  "bioLink": null,
  "followersCount": null,
  "followingCount": null,
  "friendsCount": null,
  "heartsCount": null,
  "likesGivenCount": null,
  "videosCount": null,
  "description": "A public TikTok video #travel @friend",
  "createTime": 1786468800,
  "createTimeIso": "2026-08-11T12:00:00Z",
  "mediaType": "video",
  "durationSeconds": 21,
  "width": 1080,
  "height": 1920,
  "ratio": "720p",
  "format": "mp4",
  "codecType": "h264",
  "definition": "720p",
  "videoUrl": "https://v16-webapp.tiktok.com/video.mp4",
  "downloadUrl": "https://v16-webapp.tiktok.com/download.mp4",
  "coverUrl": "https://p16-sign.tiktokcdn-us.com/cover.jpeg",
  "dynamicCoverUrl": "https://p16-sign.tiktokcdn-us.com/dynamic.webp",
  "originCoverUrl": "https://p16-sign.tiktokcdn-us.com/origin.jpeg",
  "imageUrls": [],
  "imageCount": 0,
  "isAd": false,
  "isOriginal": true,
  "isOfficial": false,
  "isSecret": false,
  "isCollected": false,
  "isReviewing": false,
  "commentsEnabled": true,
  "downloadEnabled": true,
  "duetEnabled": true,
  "stitchEnabled": true,
  "textLanguage": "en",
  "aigcDescription": "",
  "likesCount": 182400,
  "commentsCount": 4200,
  "sharesCount": 8100,
  "viewsCount": 3200000,
  "savesCount": 50700,
  "hashtags": [
    "travel"
  ],
  "mentions": [
    "friend"
  ],
  "musicId": "7300000000000000001",
  "musicTitle": "Original sound",
  "musicAuthor": "Creator",
  "musicAlbum": "",
  "musicUrl": "https://sf16-ies-music.tiktokcdn.com/audio.mp3",
  "musicCoverUrl": "https://p16-sign.tiktokcdn-us.com/music.jpeg",
  "musicDurationSeconds": 21,
  "musicOriginal": true,
  "musicCopyrighted": false,
  "musicCommercial": false,
  "hashtagId": null,
  "hashtagName": null,
  "hashtagTitle": null,
  "hashtagDescription": null,
  "hashtagVideoCount": null,
  "hashtagViewCount": null,
  "playlistId": null,
  "playlistName": null,
  "playlistVideoCount": null,
  "playlistCoverUrl": null,
  "roomId": null,
  "liveStatus": null,
  "isLive": null,
  "liveTitle": null,
  "liveViewerCount": null,
  "liveLikeCount": null,
  "liveStartTime": null,
  "liveCoverUrl": null,
  "liveStreamUrls": [],
  "liveHashtag": null,
  "liveAgeRestricted": null,
  "author": {
    "id": "10001",
    "uniqueId": "creator",
    "nickname": "Creator",
    "avatarThumb": "https://p16-sign.tiktokcdn-us.com/avatar.jpeg",
    "avatarMedium": "https://p16-sign.tiktokcdn-us.com/avatar-medium.jpeg",
    "avatarLarger": "https://p16-sign.tiktokcdn-us.com/avatar-large.jpeg",
    "signature": "Public profile biography",
    "verified": true,
    "secUid": "MS4wLjABAAAA_public",
    "secret": false,
    "ftc": false,
    "relation": 0,
    "openFavorite": true,
    "commentSetting": 0,
    "duetSetting": 0,
    "stitchSetting": 0,
    "privateAccount": false,
    "isADVirtual": false,
    "downloadSetting": 0,
    "isEmbedBanned": false
  },
  "authorStats": {
    "followerCount": 1250000,
    "followingCount": 120,
    "heartCount": 24000000,
    "videoCount": 275,
    "diggCount": 340,
    "friendCount": 80
  },
  "stats": {
    "diggCount": 182400,
    "shareCount": 8100,
    "commentCount": 4200,
    "playCount": 3200000,
    "collectCount": 50700
  },
  "video": {
    "id": "7412345678901234567",
    "height": 1920,
    "width": 1080,
    "duration": 21,
    "ratio": "720p",
    "cover": "https://p16-sign.tiktokcdn-us.com/cover.jpeg",
    "originCover": "https://p16-sign.tiktokcdn-us.com/origin.jpeg",
    "dynamicCover": "https://p16-sign.tiktokcdn-us.com/dynamic.webp",
    "playAddr": "https://v16-webapp.tiktok.com/video.mp4",
    "downloadAddr": "https://v16-webapp.tiktok.com/download.mp4",
    "format": "mp4",
    "codecType": "h264",
    "definition": "720p",
    "size": 2345678,
    "videoID": "v10044",
    "zoomCover": {}
  },
  "images": {},
  "music": {
    "id": "7300000000000000001",
    "title": "Original sound",
    "authorName": "Creator",
    "album": "",
    "duration": 21,
    "coverLarge": "https://p16-sign.tiktokcdn-us.com/music.jpeg",
    "coverMedium": "https://p16-sign.tiktokcdn-us.com/music-medium.jpeg",
    "coverThumb": "https://p16-sign.tiktokcdn-us.com/music-thumb.jpeg",
    "playUrl": "https://sf16-ies-music.tiktokcdn.com/audio.mp3",
    "original": true,
    "private": false,
    "isCopyrighted": false,
    "is_commerce_music": false,
    "is_unlimited_music": false,
    "shoot_duration": 21,
    "tt2dsp": {}
  },
  "hashtag": null,
  "playlist": null,
  "live": null,
  "raw": null
}
```

#### Complete `media-photo` output — 113 top-level fields

The photo or slideshow media row uses the same stable 113-field contract. Fields that do not apply to this record type are explicitly returned as `null` or `[]`.

```json
{
  "recordType": "media",
  "resultType": "photo",
  "id": "7412345678901234567",
  "url": "https://www.tiktok.com/@creator/photo/7412345678901234567",
  "sourceMode": "searchPhotos",
  "sourceTarget": "street food",
  "sourceUrl": "https://www.tiktok.com/@creator/photo/7412345678901234567",
  "finalUrl": "https://www.tiktok.com/@creator/photo/7412345678901234567",
  "sourceEndpoints": [
    "/api/example/"
  ],
  "transport": "httpHtml",
  "position": 1,
  "scrapedAt": "2026-08-11T12:00:00Z",
  "country": "US",
  "language": "en",
  "availability": "public",
  "isPartial": false,
  "fallbackUsed": false,
  "username": "creator",
  "nickname": "Creator",
  "authorId": "10001",
  "secUid": "MS4wLjABAAAA_public",
  "signature": "Public profile biography",
  "avatarThumb": "https://p16-sign.tiktokcdn-us.com/avatar.jpeg",
  "avatarMedium": "https://p16-sign.tiktokcdn-us.com/avatar-medium.jpeg",
  "avatarLarge": "https://p16-sign.tiktokcdn-us.com/avatar-large.jpeg",
  "isVerified": true,
  "isPrivate": false,
  "isBusinessAccount": null,
  "bioLink": null,
  "followersCount": null,
  "followingCount": null,
  "friendsCount": null,
  "heartsCount": null,
  "likesGivenCount": null,
  "videosCount": null,
  "description": "A street food photo carousel #food",
  "createTime": 1786468800,
  "createTimeIso": "2026-08-11T12:00:00Z",
  "mediaType": "photo",
  "durationSeconds": 0,
  "width": 1080,
  "height": 1920,
  "ratio": "720p",
  "format": "mp4",
  "codecType": "h264",
  "definition": "720p",
  "videoUrl": null,
  "downloadUrl": null,
  "coverUrl": "https://p16-sign.tiktokcdn-us.com/cover.jpeg",
  "dynamicCoverUrl": null,
  "originCoverUrl": "https://p16-sign.tiktokcdn-us.com/origin.jpeg",
  "imageUrls": [
    "https://p16-sign.tiktokcdn-us.com/photo-1.jpeg",
    "https://p16-sign.tiktokcdn-us.com/photo-2.jpeg"
  ],
  "imageCount": 2,
  "isAd": false,
  "isOriginal": true,
  "isOfficial": false,
  "isSecret": false,
  "isCollected": false,
  "isReviewing": false,
  "commentsEnabled": true,
  "downloadEnabled": true,
  "duetEnabled": true,
  "stitchEnabled": true,
  "textLanguage": "en",
  "aigcDescription": "",
  "likesCount": 182400,
  "commentsCount": 4200,
  "sharesCount": 8100,
  "viewsCount": 3200000,
  "savesCount": 50700,
  "hashtags": [
    "food"
  ],
  "mentions": [],
  "musicId": "7300000000000000001",
  "musicTitle": "Original sound",
  "musicAuthor": "Creator",
  "musicAlbum": "",
  "musicUrl": "https://sf16-ies-music.tiktokcdn.com/audio.mp3",
  "musicCoverUrl": "https://p16-sign.tiktokcdn-us.com/music.jpeg",
  "musicDurationSeconds": 21,
  "musicOriginal": true,
  "musicCopyrighted": false,
  "musicCommercial": false,
  "hashtagId": null,
  "hashtagName": null,
  "hashtagTitle": null,
  "hashtagDescription": null,
  "hashtagVideoCount": null,
  "hashtagViewCount": null,
  "playlistId": null,
  "playlistName": null,
  "playlistVideoCount": null,
  "playlistCoverUrl": null,
  "roomId": null,
  "liveStatus": null,
  "isLive": null,
  "liveTitle": null,
  "liveViewerCount": null,
  "liveLikeCount": null,
  "liveStartTime": null,
  "liveCoverUrl": null,
  "liveStreamUrls": [],
  "liveHashtag": null,
  "liveAgeRestricted": null,
  "author": {
    "id": "10001",
    "uniqueId": "creator",
    "nickname": "Creator",
    "avatarThumb": "https://p16-sign.tiktokcdn-us.com/avatar.jpeg",
    "avatarMedium": "https://p16-sign.tiktokcdn-us.com/avatar-medium.jpeg",
    "avatarLarger": "https://p16-sign.tiktokcdn-us.com/avatar-large.jpeg",
    "signature": "Public profile biography",
    "verified": true,
    "secUid": "MS4wLjABAAAA_public",
    "secret": false,
    "ftc": false,
    "relation": 0,
    "openFavorite": true,
    "commentSetting": 0,
    "duetSetting": 0,
    "stitchSetting": 0,
    "privateAccount": false,
    "isADVirtual": false,
    "downloadSetting": 0,
    "isEmbedBanned": false
  },
  "authorStats": {
    "followerCount": 1250000,
    "followingCount": 120,
    "heartCount": 24000000,
    "videoCount": 275,
    "diggCount": 340,
    "friendCount": 80
  },
  "stats": {
    "diggCount": 182400,
    "shareCount": 8100,
    "commentCount": 4200,
    "playCount": 3200000,
    "collectCount": 50700
  },
  "video": {
    "id": "7412345678901234567",
    "height": 1920,
    "width": 1080,
    "duration": 0,
    "ratio": "720p",
    "cover": "https://p16-sign.tiktokcdn-us.com/cover.jpeg",
    "originCover": "https://p16-sign.tiktokcdn-us.com/origin.jpeg",
    "dynamicCover": null,
    "playAddr": null,
    "downloadAddr": null,
    "format": "mp4",
    "codecType": "h264",
    "definition": "720p",
    "size": 2345678,
    "videoID": "v10044",
    "zoomCover": {}
  },
  "images": {
    "title": "Street food",
    "images": [
      {
        "imageURL": {
          "urlList": [
            "https://p16-sign.tiktokcdn-us.com/photo-1.jpeg"
          ]
        },
        "displayImage": {
          "urlList": [
            "https://p16-sign.tiktokcdn-us.com/photo-display.jpeg"
          ]
        }
      }
    ],
    "cover": {
      "urlList": [
        "https://p16-sign.tiktokcdn-us.com/cover.jpeg"
      ]
    },
    "shareCover": {
      "urlList": [
        "https://p16-sign.tiktokcdn-us.com/share.jpeg"
      ]
    }
  },
  "music": {
    "id": "7300000000000000001",
    "title": "Original sound",
    "authorName": "Creator",
    "album": "",
    "duration": 21,
    "coverLarge": "https://p16-sign.tiktokcdn-us.com/music.jpeg",
    "coverMedium": "https://p16-sign.tiktokcdn-us.com/music-medium.jpeg",
    "coverThumb": "https://p16-sign.tiktokcdn-us.com/music-thumb.jpeg",
    "playUrl": "https://sf16-ies-music.tiktokcdn.com/audio.mp3",
    "original": true,
    "private": false,
    "isCopyrighted": false,
    "is_commerce_music": false,
    "is_unlimited_music": false,
    "shoot_duration": 21,
    "tt2dsp": {}
  },
  "hashtag": null,
  "playlist": null,
  "live": null,
  "raw": null
}
```

#### Complete `playlist` output — 113 top-level fields

The playlist details row uses the same stable 113-field contract. Fields that do not apply to this record type are explicitly returned as `null` or `[]`.

```json
{
  "recordType": "playlist",
  "resultType": "playlist",
  "id": "7312345678901234567",
  "url": "https://www.tiktok.com/@creator/playlist/Travel-7312345678901234567",
  "sourceMode": "playlist",
  "sourceTarget": "https://www.tiktok.com/@creator/playlist/Travel-7312345678901234567",
  "sourceUrl": "https://www.tiktok.com/@creator/playlist/Travel-7312345678901234567",
  "finalUrl": "https://www.tiktok.com/@creator/playlist/Travel-7312345678901234567",
  "sourceEndpoints": [
    "/api/example/"
  ],
  "transport": "httpJson",
  "position": 1,
  "scrapedAt": "2026-08-11T12:00:00Z",
  "country": "US",
  "language": "en",
  "availability": "public",
  "isPartial": false,
  "fallbackUsed": false,
  "username": null,
  "nickname": null,
  "authorId": null,
  "secUid": null,
  "signature": null,
  "avatarThumb": null,
  "avatarMedium": null,
  "avatarLarge": null,
  "isVerified": null,
  "isPrivate": null,
  "isBusinessAccount": null,
  "bioLink": null,
  "followersCount": null,
  "followingCount": null,
  "friendsCount": null,
  "heartsCount": null,
  "likesGivenCount": null,
  "videosCount": null,
  "description": null,
  "createTime": null,
  "createTimeIso": null,
  "mediaType": null,
  "durationSeconds": null,
  "width": null,
  "height": null,
  "ratio": null,
  "format": null,
  "codecType": null,
  "definition": null,
  "videoUrl": null,
  "downloadUrl": null,
  "coverUrl": null,
  "dynamicCoverUrl": null,
  "originCoverUrl": null,
  "imageUrls": [],
  "imageCount": null,
  "isAd": null,
  "isOriginal": null,
  "isOfficial": null,
  "isSecret": null,
  "isCollected": null,
  "isReviewing": null,
  "commentsEnabled": null,
  "downloadEnabled": null,
  "duetEnabled": null,
  "stitchEnabled": null,
  "textLanguage": null,
  "aigcDescription": null,
  "likesCount": null,
  "commentsCount": null,
  "sharesCount": null,
  "viewsCount": null,
  "savesCount": null,
  "hashtags": [],
  "mentions": [],
  "musicId": null,
  "musicTitle": null,
  "musicAuthor": null,
  "musicAlbum": null,
  "musicUrl": null,
  "musicCoverUrl": null,
  "musicDurationSeconds": null,
  "musicOriginal": null,
  "musicCopyrighted": null,
  "musicCommercial": null,
  "hashtagId": null,
  "hashtagName": null,
  "hashtagTitle": null,
  "hashtagDescription": null,
  "hashtagVideoCount": null,
  "hashtagViewCount": null,
  "playlistId": "7312345678901234567",
  "playlistName": "Travel",
  "playlistVideoCount": 24,
  "playlistCoverUrl": "https://p16-sign.tiktokcdn-us.com/playlist.jpeg",
  "roomId": null,
  "liveStatus": null,
  "isLive": null,
  "liveTitle": null,
  "liveViewerCount": null,
  "liveLikeCount": null,
  "liveStartTime": null,
  "liveCoverUrl": null,
  "liveStreamUrls": [],
  "liveHashtag": null,
  "liveAgeRestricted": null,
  "author": null,
  "authorStats": null,
  "stats": null,
  "video": null,
  "images": null,
  "music": null,
  "hashtag": null,
  "playlist": {
    "id": "7312345678901234567",
    "mixId": "7312345678901234567",
    "mixName": "Travel",
    "name": "Travel",
    "videoCount": 24,
    "cover": "https://p16-sign.tiktokcdn-us.com/playlist.jpeg",
    "creator": {
      "id": "10001",
      "uniqueId": "creator",
      "nickname": "Creator"
    }
  },
  "live": null,
  "raw": null
}
```

#### Complete `live-status` output — 113 top-level fields

The LIVE status row uses the same complete contract. An offline creator has `isLive: false`; when TikTok exposes a room ID, the Actor also calls the public status endpoint.

```json
{
  "recordType": "live",
  "resultType": "liveStatus",
  "id": "creator",
  "url": "https://www.tiktok.com/@creator",
  "sourceMode": "liveStatus",
  "sourceTarget": "creator",
  "sourceUrl": "https://www.tiktok.com/@creator/live",
  "finalUrl": "https://www.tiktok.com/@creator",
  "sourceEndpoints": [],
  "transport": "httpHtml",
  "position": 1,
  "scrapedAt": "2026-08-11T23:16:54.774915Z",
  "country": "US",
  "language": "en",
  "availability": "notLive",
  "isPartial": true,
  "fallbackUsed": true,
  "username": "creator",
  "nickname": null,
  "authorId": null,
  "secUid": null,
  "signature": null,
  "avatarThumb": null,
  "avatarMedium": null,
  "avatarLarge": null,
  "isVerified": null,
  "isPrivate": null,
  "isBusinessAccount": null,
  "bioLink": null,
  "followersCount": null,
  "followingCount": null,
  "friendsCount": null,
  "heartsCount": null,
  "likesGivenCount": null,
  "videosCount": null,
  "description": null,
  "createTime": null,
  "createTimeIso": null,
  "mediaType": null,
  "durationSeconds": null,
  "width": null,
  "height": null,
  "ratio": null,
  "format": null,
  "codecType": null,
  "definition": null,
  "videoUrl": null,
  "downloadUrl": null,
  "coverUrl": null,
  "dynamicCoverUrl": null,
  "originCoverUrl": null,
  "imageUrls": [],
  "imageCount": null,
  "isAd": null,
  "isOriginal": null,
  "isOfficial": null,
  "isSecret": null,
  "isCollected": null,
  "isReviewing": null,
  "commentsEnabled": null,
  "downloadEnabled": null,
  "duetEnabled": null,
  "stitchEnabled": null,
  "textLanguage": null,
  "aigcDescription": null,
  "likesCount": null,
  "commentsCount": null,
  "sharesCount": null,
  "viewsCount": null,
  "savesCount": null,
  "hashtags": [],
  "mentions": [],
  "musicId": null,
  "musicTitle": null,
  "musicAuthor": null,
  "musicAlbum": null,
  "musicUrl": null,
  "musicCoverUrl": null,
  "musicDurationSeconds": null,
  "musicOriginal": null,
  "musicCopyrighted": null,
  "musicCommercial": null,
  "hashtagId": null,
  "hashtagName": null,
  "hashtagTitle": null,
  "hashtagDescription": null,
  "hashtagVideoCount": null,
  "hashtagViewCount": null,
  "playlistId": null,
  "playlistName": null,
  "playlistVideoCount": null,
  "playlistCoverUrl": null,
  "roomId": null,
  "liveStatus": "offline",
  "isLive": false,
  "liveTitle": null,
  "liveViewerCount": null,
  "liveLikeCount": null,
  "liveStartTime": null,
  "liveCoverUrl": null,
  "liveStreamUrls": [],
  "liveHashtag": null,
  "liveAgeRestricted": null,
  "author": null,
  "authorStats": null,
  "stats": null,
  "video": null,
  "images": null,
  "music": null,
  "hashtag": null,
  "playlist": null,
  "live": null,
  "raw": null
}
```

### What data can you extract?

Every output key is listed below.

| Category | Fields |
| --- | --- |
| Record and source | `recordType`, `resultType`, `id`, `url`, `sourceMode`, `sourceTarget`, `sourceUrl`, `finalUrl`, `sourceEndpoints`, `transport`, `position`, `scrapedAt`, `country`, `language`, `availability`, `isPartial`, `fallbackUsed` |
| Creator identity | `username`, `nickname`, `authorId`, `secUid`, `signature`, `avatarThumb`, `avatarMedium`, `avatarLarge`, `isVerified`, `isPrivate`, `isBusinessAccount`, `bioLink` |
| Creator metrics | `followersCount`, `followingCount`, `friendsCount`, `heartsCount`, `likesGivenCount`, `videosCount` |
| Content | `description`, `createTime`, `createTimeIso`, `mediaType`, `durationSeconds`, `width`, `height`, `ratio`, `format`, `codecType`, `definition` |
| Media URLs | `videoUrl`, `downloadUrl`, `coverUrl`, `dynamicCoverUrl`, `originCoverUrl`, `imageUrls`, `imageCount` |
| Content flags | `isAd`, `isOriginal`, `isOfficial`, `isSecret`, `isCollected`, `isReviewing`, `commentsEnabled`, `downloadEnabled`, `duetEnabled`, `stitchEnabled`, `textLanguage`, `aigcDescription` |
| Engagement | `likesCount`, `commentsCount`, `sharesCount`, `viewsCount`, `savesCount` |
| Tags | `hashtags`, `mentions` |
| Music | `musicId`, `musicTitle`, `musicAuthor`, `musicAlbum`, `musicUrl`, `musicCoverUrl`, `musicDurationSeconds`, `musicOriginal`, `musicCopyrighted`, `musicCommercial` |
| Hashtag | `hashtagId`, `hashtagName`, `hashtagTitle`, `hashtagDescription`, `hashtagVideoCount`, `hashtagViewCount` |
| Playlist | `playlistId`, `playlistName`, `playlistVideoCount`, `playlistCoverUrl` |
| LIVE | `roomId`, `liveStatus`, `isLive`, `liveTitle`, `liveViewerCount`, `liveLikeCount`, `liveStartTime`, `liveCoverUrl`, `liveStreamUrls`, `liveHashtag`, `liveAgeRestricted` |
| Complete nested data | `author`, `authorStats`, `stats`, `video`, `images`, `music`, `hashtag`, `playlist`, `live`, `raw` |

### Input parameters

| Parameter | Type | Required | Default | Description |
| --- | --- | --- | --- | --- |
| `mode` | string | Yes | `profilePosts` | `auto`, `profile`, `profilePosts`, `video`, `photo`, `searchPhotos`, `playlist`, or `liveStatus` |
| `startUrls` | request\[] | By mode | `[]` | Supported public TikTok URLs |
| `targets` | string\[] | By mode | `["tiktok"]` | Usernames, URLs, media IDs, or LIVE room IDs |
| `searchTerms` | string\[] | Photo Search | `[]` | Photo Search keywords |
| `maxResults` | integer | No | `20` | Media rows per profile or keyword, 0 for every HTTP-accessible result |
| `maxTotalResults` | integer | No | `0` | Combined run cap; 0 disables the additional cap |
| `country` | string | No | `US` | Residential proxy country and regional request hint |
| `language` | string | No | `en` | HTML/API language and Accept-Language locale |
| `sort` | string | No | `relevance` | `relevance`, `latest`, `popular`, or `oldest` |
| `publishedAfter` | ISO string | No | — | Remove older media after extraction |
| `publishedBefore` | ISO string | No | — | Remove newer media after extraction |
| `minLikes` | integer | No | `0` | Minimum public likes; use enrichment for reliable post filtering |
| `minComments` | integer | No | `0` | Minimum public comment count; use enrichment for reliable post filtering |
| `minViews` | integer | No | `0` | Minimum public views/play count |
| `includeRaw` | boolean | No | `false` | Include sanitized public source objects; increases Dataset size |
| `enrichPartialResults` | boolean | No | `true` | Fetch complete public media HTML for lightweight recent-post rows |
| `maxConcurrency` | integer | No | `5` | Parallel HTTP targets/enrichments, 1–25 |
| `maxSessionRotations` | integer | No | `3` | Fresh residential proxy/session attempts, 1–6 |
| `navigationTimeoutSecs` | integer | No | `45` | Per-request timeout, 15–120 seconds |

### Use cases

#### Creator and influencer research

Collect creator identity, biography, verification, privacy flags, follower/following counts, total hearts, and video totals without opening profiles manually.

#### Recent creator content

Return the profile and up to 22 recent video/photo records together. Enable HTTP enrichment for complete likes, comments, shares, saves, music, hashtags, mentions, and media fields.

#### Individual post analysis

Extract complete public video or slideshow metadata from specific URLs, including engagement, author, sound attribution, ordered image URLs, and available playback/cover URLs.

#### Visual trend discovery

Paginate Photo Search by keyword and apply local date, engagement, popularity, and total-result controls.

#### Playlist and LIVE monitoring

Resolve public creator playlist metadata and schedule repeated LIVE-status checks through Apify schedules, webhooks, or API integrations.

### Performance and cost

The Actor uses HTTP/2-capable browser-TLS impersonation but never starts a browser. It downloads only the required HTML documents and JSON responses; it does not load JavaScript bundles, fonts, videos, or background browser resources.

Measured local smoke examples through residential test proxies:

| Workflow | Requests | Decoded response bytes | Rows |
| --- | ---: | ---: | ---: |
| Profile | 1 | about 368 KB | 1 |
| Profile plus five lightweight posts | 2 | about 379 KB | 6 |
| Video detail | 1 | about 392 KB | 1 |
| Photo Search, five results | 2 | about 410 KB | 5 |
| Playlist metadata | 2 | about 374 KB | 1 |

These are decoded application bytes from representative runs, not guaranteed proxy-billing bytes. Response size varies by profile, locale, TikTok experiments, and optional enrichment. Enriching five recent posts adds up to five media-detail HTTP requests.

Only successfully saved Dataset rows trigger result events. Empty pages, retries, blocks, duplicates, filters, and failed inputs do not create a custom error event.

| Saved row | PPE event |
| --- | --- |
| Public profile | `profile-result` |
| Video or photo | `video-photo-result` |
| Playlist metadata | `playlist-result` |
| LIVE status | `live-result` |

The Store **Pricing** tab is the source of truth for current prices.

### API usage

After a run, retrieve the single Results view through the Dataset API:

```text
https://api.apify.com/v2/datasets/<DATASET_ID>/items?view=overview&clean=true&format=json
```

Run the Actor through the Apify API, schedule recurring checks, or connect successful runs to webhooks and downstream automations. The same complete field contract is available in JSON, CSV, Excel, XML, and RSS exports.

### Best for / not for

**Best for:** public creator intelligence, recent creator posts, individual video/photo details, photo trend datasets, playlist inventories, and public LIVE-status monitoring.

**Not for:** Top/Video/User Search, hashtag or music feeds, Explore, For You, LIVE discovery, private profiles, follower/following lists, comment threads, TikTok Shop, authenticated feeds, media-file downloads, stream recording, or CAPTCHA-protected content.

### Limits and good to know

- `profilePosts` exposes at most 22 recent items through TikTok's unsigned embed route. Cursor pagination is not available on that route.
- Lightweight recent-post rows contain description, author identifiers, play count, covers, and playback URL. They are marked `isPartial: true` until successfully enriched.
- Enrichment remains HTTP-only but performs one additional public media request per partial row.
- Individual photo pages are resolved through the same public SSR data path TikTok uses for the media ID, allowing ordered slideshow image URLs to be extracted without a browser.
- Photo Search requires one lightweight HTML warm-up request per keyword before JSON pagination.
- Country selects the mandatory residential proxy region, but TikTok ultimately controls regional availability and ranking.
- Signed CDN media URLs can expire. Store or process them promptly when your workflow permits.
- The 113-field contract is stable, but fields that do not apply to a record type use `null` or `[]`.
- `includeRaw` can substantially increase Dataset transfer and storage.

### Frequently asked questions

#### What input should I provide?

Use usernames for profile workflows, complete TikTok URLs for media/playlist workflows, keywords for Photo Search, and usernames or numeric room IDs for LIVE status. Auto mode accepts only the URL types listed above.

#### Why does Profile posts return one extra row?

The first row is the requested public profile. `maxResults` limits the following media rows, matching the common creator-research workflow of receiving profile context and recent posts together.

#### How many recent profile posts can I extract?

Up to 22 per username with the current unsigned public embed endpoint. Higher values do not create browser pagination or hidden additional charges.

#### Why are some recent-post fields empty?

The low-traffic embed response intentionally contains fewer fields. Keep `enrichPartialResults` enabled to request complete public details for each post. Failed enrichment keeps the lightweight row with `isPartial: true` instead of discarding useful data.

#### Can I process multiple inputs?

Yes. Add multiple usernames, URLs, room IDs, or Photo Search keywords. `maxResults` applies independently and `maxTotalResults` caps the combined run.

#### Do I need a TikTok account, API key, cookies, or proxy settings?

No account, API key, saved cookies, or user-facing proxy configuration is required. Published runs automatically use Apify Residential Proxy, and first-party cookies live only inside an isolated HTTP session.

#### Does the Actor extract comments or follower lists?

No. Media rows include public comment counts, while complete comment threads and follower/following lists are outside this public HTTP-only product boundary.

### Responsible use

Use the Actor only for lawful collection of publicly available data. Respect privacy, intellectual-property rights, platform terms, applicable laws, and reasonable request volumes. Do not use it to bypass access controls or collect private information.

### Support

If a public target repeatedly returns no rows, include the mode, sanitized input, run ID, country, and approximate time in an Apify issue. Never post proxy credentials, cookies, signed media URLs, or authentication data in a public issue.

# Actor input Schema

## `mode` (type: `string`):

Choose a public TikTok surface supported by the low-traffic HTTP engine. Auto detects supported URL types.

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

Public TikTok profile, video, photo, playlist or LIVE URLs. Auto mode detects each supported URL type.

## `targets` (type: `array`):

Usernames, TikTok URLs, video/photo IDs or LIVE room IDs accepted by the selected mode.

## `searchTerms` (type: `array`):

Keywords for the public Photo Search mode.

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

Maximum media records per profile or keyword. Profile posts exposes up to 22 recent items through TikTok's public embed endpoint. Detail modes return one row. Use 0 for every HTTP-accessible result.

## `maxTotalResults` (type: `integer`):

Optional hard cap after all inputs are combined and deduplicated. 0 means no additional run-wide cap.

## `country` (type: `string`):

ISO 3166-1 alpha-2 country used for the residential proxy session and TikTok locale, for example US, GB or DE.

## `language` (type: `string`):

Interface and Accept-Language locale, for example en, de or pt-BR.

## `sort` (type: `string`):

Keep TikTok relevance order or locally reorder extracted media by publication time or popularity.

## `publishedAfter` (type: `string`):

Optional ISO date or timestamp. Media older than this value is removed after extraction.

## `publishedBefore` (type: `string`):

Optional ISO date or timestamp. Media newer than this value is removed after extraction.

## `minLikes` (type: `integer`):

Keep media with at least this many likes.

## `minComments` (type: `integer`):

Keep media with at least this many comments.

## `minViews` (type: `integer`):

Keep media with at least this many public plays or views.

## `includeRaw` (type: `boolean`):

Keep the underlying public TikTok object after session, token, cookie and signature fields are removed. This can substantially increase dataset size.

## `enrichPartialResults` (type: `boolean`):

Enrich lightweight recent-post records with complete public video or photo data using extra HTTP requests. No browser is started.

## `maxConcurrency` (type: `integer`):

Maximum TikTok targets or enrichment requests processed in parallel. Start with 5 for reliable residential proxy sessions.

## `maxSessionRotations` (type: `integer`):

Fresh HTTP session, residential proxy IP and cookies tried after a rate limit, login redirect or empty challenge response.

## `navigationTimeoutSecs` (type: `integer`):

Maximum time allowed for one TikTok HTTP request.

## Actor input object example

```json
{
  "mode": "profilePosts",
  "startUrls": [],
  "targets": [
    "tiktok"
  ],
  "searchTerms": [],
  "maxResults": 20,
  "maxTotalResults": 0,
  "country": "US",
  "language": "en",
  "sort": "relevance",
  "minLikes": 0,
  "minComments": 0,
  "minViews": 0,
  "includeRaw": false,
  "enrichPartialResults": true,
  "maxConcurrency": 5,
  "maxSessionRotations": 3,
  "navigationTimeoutSecs": 45
}
```

# Actor output Schema

## `dataset` (type: `string`):

All public profile, video, photo, Photo Search, playlist and LIVE-status fields in one Results table.

## `runSummary` (type: `string`):

Source, retry, block, filtering and result counts for this run.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("scrapingmonkey/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 = {}

# Run the Actor and wait for it to finish
run = client.actor("scrapingmonkey/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 '{}' |
apify call scrapingmonkey/tiktok-scraper --silent --output-dataset

```

## MCP server setup

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