# Douyin 抖音 Profile Scraper - 博主 Followers, Posts & Hashtags (`zen-studio/douyin-profile-scraper`) Actor

Extract Douyin (抖音) 博主 profiles, 粉丝 counts, engagement stats, hashtags, and Douyin's server-classified video categories. 28 fields per post + 22 per author. Accepts profile URLs, share links, UserSecIDs, and numeric user IDs. Profile-only 数据采集 mode for cheap follower tracking.

- **URL**: https://apify.com/zen-studio/douyin-profile-scraper.md
- **Developed by:** [Zen Studio](https://apify.com/zen-studio) (community)
- **Categories:** Social media, Videos, Automation
- **Stats:** 3 total users, 2 monthly users, 85.7% runs succeeded, NaN bookmarks
- **User rating**: No ratings yet

## Pricing

from $4.49 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are a software tools running on the Apify platform, for all kinds of web data extraction and automation use cases.
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.

In JavaScript/TypeScript projects, use official [JavaScript/TypeScript client](https://docs.apify.com/api/client/js.md):

```bash
npm install apify-client
```

In Python projects, use official [Python client library](https://docs.apify.com/api/client/python.md):

```bash
pip install apify-client
```

In shell scripts, use [Apify CLI](https://docs.apify.com/cli/docs.md):

````bash
# MacOS / Linux
curl -fsSL https://apify.com/install-cli.sh | bash
# Windows
irm https://apify.com/install-cli.ps1 | iex
```bash

In AI frameworks, you might use the [Apify MCP server](https://docs.apify.com/platform/integrations/mcp.md).

If your project is in a different language, use 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

## Douyin Profile Scraper (抖音) — Followers, Posts, Bio, Likes (2026)

<blockquote style="border-left:4px solid #4C945E;background:#F0FDF4;padding:12px 16px">
<span style="font-size:16px;font-weight:700;color:#1C1917">1,000 Douyin (抖音) posts per profile in under 60 seconds</span> <span style="font-size:15px;color:#57534E"> — followers, engagement, hashtags, music, and the full creator profile in clean structured JSON.</span>
</blockquote>

![Douyin Profile Scraper](https://iili.io/BQdin72.png)

#### Copy to your AI assistant

````

zen-studio/douyin-profile-scraper on Apify. Scrapes Douyin profiles + posts with follower counts, engagement, hashtags, and server-classified videoTags. Call ApifyClient("TOKEN").actor("zen-studio/douyin-profile-scraper").call(run\_input={...}), then client.dataset(run\["defaultDatasetId"]).list\_items().items. profileUrls accepts URLs/share links/UserSecIDs/numeric uids; maxPostsPerProfile=0 for profile-only. Full spec: GET https://api.apify.com/v2/acts/zen-studio~douyin-profile-scraper/builds/default (Bearer TOKEN) → inputSchema, actorDefinition.storages.dataset, readme. Token: https://console.apify.com/account/integrations

````

<table>
<tr>
<td colspan="4" style="padding:10px 14px;background:#4C945E;border:none;border-radius:4px 4px 0 0">
<span style="color:#FAFAF9;font-size:14px;font-weight:700;letter-spacing:0.5px">Zen Studio Social & Video</span>
<span style="color:#E8F5E9;font-size:13px">&nbsp;&nbsp;&bull;&nbsp;&nbsp;Structured creator data from every major platform</span>
</td>
</tr>
<tr>
<td style="padding:12px 16px;border:1px solid #E7E5E4;border-radius:0 0 0 4px;background:#E8F5E9;border-right:none;border-top:none;vertical-align:top;width:25%">
<img src="https://iili.io/BQdin72.png" width="24" height="24" style="vertical-align:middle"> &nbsp;<a href="https://apify.com/zen-studio/douyin-profile-scraper" style="color:#4C945E;text-decoration:none;font-weight:700;font-size:14px">Douyin Profile</a><br>
<span style="color:#4C945E;font-size:12px;font-weight:600">&#10148; You are here</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%">
<img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-dexCSKEZtKS8hg4fT-lD4weyiYga-shigua-____-scraper-logo.jpg" width="24" height="24" style="vertical-align:middle"> &nbsp;<a href="https://apify.com/zen-studio/xigua-video-search-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:14px">Xigua Search</a><br>
<span style="color:#78716C;font-size:12px">Keyword + comments + MP4</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;border-right:none;border-top:none;vertical-align:top;width:25%">
<img src="https://apify-image-uploads-prod.s3.us-east-1.amazonaws.com/NWYsOG96fMDy8ycdf-actor-usNpBTMSjLmc3hT8f-DIQK9OpLQP-shigua-____-scraper-logo.jpg" width="24" height="24" style="vertical-align:middle"> &nbsp;<a href="https://apify.com/zen-studio/xigua-video-detail-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:14px">Xigua Detail</a><br>
<span style="color:#78716C;font-size:12px">70+ fields + MP4 download</span>
</td>
<td style="padding:12px 16px;border:1px solid #E7E5E4;border-radius:0 0 4px 0;border-top:none;vertical-align:top;width:25%">
<img src="https://iili.io/BQdin72.png" width="24" height="24" style="vertical-align:middle"> &nbsp;<a href="https://apify.com/zen-studio/douyin-video-scraper" style="color:#1C1917;text-decoration:none;font-weight:700;font-size:14px">Douyin Video</a><br>
<span style="color:#78716C;font-size:12px">Metadata + MP4 download</span>
</td>
</tr>
</table>

### How to Scrape Douyin Profiles & Posts

#### Basic — one creator, last 100 posts

```json
{
  "profileUrls": ["https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS"],
  "maxPostsPerProfile": 100
}
````

#### Profile only — track follower count without scraping posts

```json
{
  "profileUrls": ["1929015166249580"],
  "maxPostsPerProfile": 0
}
```

#### Recent activity only — last 30 days across multiple creators

```json
{
  "profileUrls": [
    "https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS",
    "MS4wLjABAAAAjjwfy25gmtDlk8Wg6FNIBzHdHicG6BpZZNvWoTLL8S4",
    "1929015166249580"
  ],
  "maxPostsPerProfile": 200,
  "recentDays": 30,
  "excludePinnedPosts": true
}
```

### Input Parameters

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `profileUrls` | string\[] | *required* | Douyin profile URLs, share links, UserSecIDs, or bare numeric user IDs. |
| `maxPostsPerProfile` | integer | `100` | How many recent posts per profile (0–10,000). Set to `0` for profile-only mode. |
| `recentDays` | integer | — | Only include posts from the last N days (e.g. `30` for last month). Easier alternative to `oldestPostDate`. |
| `oldestPostDate` | string | — | Only include posts on or after this absolute date (`YYYY-MM-DD`). When both `recentDays` and `oldestPostDate` are set, `recentDays` wins. |
| `excludePinnedPosts` | boolean | `false` | Skip posts pinned to the top of the profile. |

#### Accepted profile input formats

| Format | Example |
|---|---|
| Browser address bar URL | `https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS` |
| App share link (auto-resolved) | `https://v.douyin.com/iAbc123/` |
| Legacy share URL | `https://www.iesdouyin.com/share/user/1929015166249580` |
| Bare UserSecID | `MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS` |
| Bare numeric user ID | `1929015166249580` |

### What Data Can You Extract from Douyin?

Two output shapes depending on `maxPostsPerProfile`:

- **`maxPostsPerProfile > 0` (default)** — one row per post (28 fields), with the creator's profile metadata nested under `authorMeta` (46 fields).
- **`maxPostsPerProfile = 0`** — one row per profile (48 fields), profile fields promoted to the top level. Fastest, cheapest mode.

#### Per-post fields

- **Identity** — `id`, `type` (`video`/`imageText`/`story`), `url`, `shareUrl`, `inputUrl`, `region` (creator IP), `city` + `cityCode` (post upload location, GB/T 2260), `descLanguage`
- **Content** — `text` (caption), `thumb`, `images` (for image-text posts)
- **Timing** — `createTime` (unix), `createDate` (ISO YYYY-MM-DD)
- **Flags** — `isPinned`, `isAd`, `isPgc`, `isShared`, `crossPostedToXigua`
- **Engagement** — `statistics`: `diggCount`, `commentCount`, `shareCount`, `collectCount`, `downloadCount`, `playCount`, `forwardCount`
- **Categorisation** — `hashtags` (`[{id, name}]` — creator-typed with stable IDs), `videoTags` (Douyin's server-classified 3-level taxonomy), `mentions`
- **Media** — `musicMeta` (track id, name, author, owner, duration, play URL, cover, isOriginal), `videoMeta` (cover, duration, dimensions, format, play URL, download URL, bit-rate variants, HDR, watermark, **`cdnUrlExpiresAt`** — unix-seconds when video URLs die, typically ~1h after scrape)
- **Structure** — `chapters` (`[{startMs, title, coverUrl}]`), `series` (`{id, name, episode, total, coverUrl, shareUrl, updateTime}` for posts in a 合集), `location`
- **Permissions** — `canDuet`, `canStitch`, `canDownload`, `canShare`, `canComment`

#### Per-author (`authorMeta`) fields

**Identity:** `id`, `secUid`, `name`, `username`, `customUsername`, `customUsernameUpdatedAt` (unix timestamp of last handle change), `verified`, `verifyType` (0/1/2 = none/normal/enterprise), `customVerifyText` (e.g. `"时尚创作者"`), `enterpriseVerifyReason`, `verificationReason`, `signature` (bio), `country` (e.g. `"CN"`), `language`, `gender` (`unknown`/`male`/`female`).

**Demographics:** `userAge` (when set), `birthday` (when set), `constellation` (1–12 zodiac index when set, else null).

**Avatars:** `avatarThumb`, `avatarLarge` (existing), plus `avatar168` (168×168), `avatarMedium` (720×720), `avatar300` (300×300), `bgImage` (profile background), `shareQrCodeUri` (Douyin's share-QR asset path).

**Engagement metrics:** `followersCount`, `followersCountStr` (e.g. `"4.8万"`), `followingCount`, `heartCount` (legacy total likes from userhome), `videoCount`, `videoPlayCount`, `videoShareCount`, `totalLikesReceived` (lifetime cumulative likes — the canonical creator-economy metric, often differs from `heartCount`), `awemeCount` (real total post count), `likesGivenCount` (likes the creator gave to others).

**Live & commerce:** `isLiving`, `roomId` (live-room ID when live), `isStar` (Douyin's "star creator" tier), `withShopEntry` (has a Douyin Shop), `commerceUserLevel` (0–5).

**Locality & associations:** `ipLocation` (creator IP region), `school` (`{id, name, category, type}` for student creators, else null), `usesSeries` (publishes 合集), `mcnInfo` (`{name, uid}` for managed creators, else null), `crossPlatform` (`{instagram, twitter, youtube, weibo}` handles when set, else null), `shareUrl`.

#### Output Example

```json
{
  "id": "7628905002311994670",
  "type": "video",
  "text": "英语磨耳朵：热爱待在家的人的心理 #英语听力训练 #英语学习打卡 #启蒙英语 #英语没那么难 #每天英语一分钟",
  "descLanguage": "zh",
  "createTime": 1776298080,
  "createDate": "2026-04-16",
  "url": "https://www.douyin.com/video/7628905002311994670",
  "shareUrl": "https://www.iesdouyin.com/share/video/7628905002311994670/",
  "thumb": "https://p11-sign.douyinpic.com/tos-cn-i-dy/40e0d6...~tplv-dy-resize.heic?...",
  "isPinned": false,
  "isAd": false,
  "isPgc": false,
  "isShared": false,
  "region": "河北",
  "city": "Hebei",
  "cityCode": "130100",
  "authorMeta": {
    "id": "1929015166249580",
    "secUid": "MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS",
    "name": "木木英语",
    "username": "63970939507",
    "customUsername": null,
    "customUsernameUpdatedAt": 1777798069,
    "verified": true,
    "verifyType": 1,
    "customVerifyText": "英语创作者",
    "enterpriseVerifyReason": null,
    "verificationReason": "英语创作者",
    "signature": "📚英语爱好者\n🧸努力学习英语中\n❤️好好吃饭💛好好睡觉💚好好生活",
    "avatarThumb": "https://p26.douyinpic.com/img/aweme-avatar/...c5_300x300.jpeg?from=2956013662",
    "avatarLarge": "https://p26.douyinpic.com/img/aweme-avatar/...c5_300x300.jpeg?from=2956013662",
    "avatar168": "https://p26.douyinpic.com/img/aweme-avatar/...c5_168x168.jpeg",
    "avatarMedium": "https://p26.douyinpic.com/img/aweme-avatar/...c5_720x720.jpeg",
    "avatar300": "https://p26.douyinpic.com/img/aweme-avatar/...c5_300x300.jpeg",
    "bgImage": "https://p11-sign.douyinpic.com/obj/douyin-user-image-file/...?...",
    "shareQrCodeUri": "2f1f800070d01d38cc905",
    "followingCount": 15,
    "followersCount": 48875,
    "followersCountStr": "4.8万",
    "heartCount": 87153,
    "totalLikesReceived": 87153,
    "videoCount": 189,
    "awemeCount": 189,
    "likesGivenCount": 312,
    "videoPlayCount": null,
    "videoShareCount": null,
    "isLiving": false,
    "roomId": null,
    "isStar": false,
    "withShopEntry": false,
    "commerceUserLevel": 0,
    "ipLocation": "山东",
    "country": "CN",
    "gender": "unknown",
    "language": "zh-Hans",
    "userAge": 9,
    "birthday": null,
    "constellation": 1,
    "school": null,
    "usesSeries": true,
    "mcnInfo": null,
    "crossPlatform": null,
    "shareUrl": "https://www.iesdouyin.com/xg/user/1929015166249580"
  },
  "musicMeta": {
    "id": "7628905006464944923",
    "name": "@木木英语创作的原声",
    "author": "木木英语",
    "album": null,
    "isOriginal": true,
    "isPgc": false,
    "isCommerce": false,
    "duration": 221,
    "playUrl": "https://sf5-hl-ali-cdn-tos.douyinstatic.com/obj/ies-music/7628905080950901550.mp3",
    "coverThumb": "https://p11.douyinpic.com/aweme-avatar/...",
    "coverLarge": "https://p26.douyinpic.com/aweme/1080x1080/aweme-avatar/...",
    "owner": {
      "id": "1929015166249580",
      "handle": "63970939507",
      "nickname": "木木英语"
    }
  },
  "videoMeta": {
    "cover": "https://p11-sign.douyinpic.com/tos-cn-i-dy/40e0d6...~tplv-dy-resize.heic?...",
    "originCover": "https://p11-sign.douyinpic.com/tos-cn-p-0015/oUeILU...~tplv-dy-360p.heic?...",
    "dynamicCover": "https://p11-sign.douyinpic.com/obj/tos-cn-i-dy/40e0d6...?...",
    "height": 1280,
    "width": 720,
    "ratio": "720p",
    "duration": 221937,
    "format": "mp4",
    "isLongVideo": false,
    "playUrl": "https://v95-hzyy-thr-daily-colda.douyinvod.com/.../?...",
    "downloadUrl": "https://v5-se-ws-cold.douyinvod.com/.../?...",
    "bitRates": [
      { "quality": "adapt_lowest_1080_1", "bitRate": 247531, "isH265": true, "fps": 30, "url": "https://..." },
      { "quality": "adapt_lower_540_1", "bitRate": 155050, "isH265": true, "fps": 30, "url": "https://..." }
    ],
    "isHdr": false,
    "hasWatermark": true,
    "cdnUrlExpiresAt": 1777883276
  },
  "images": [],
  "statistics": {
    "diggCount": 106,
    "shareCount": 14,
    "commentCount": 4,
    "collectCount": 47,
    "downloadCount": 1,
    "playCount": 0,
    "forwardCount": 0
  },
  "mentions": [],
  "hashtags": [
    { "id": "1664320797481997", "name": "英语听力训练" },
    { "id": "7541656378260408383", "name": "英语学习打卡" },
    { "id": "7402916912059680777", "name": "启蒙英语" }
  ],
  "videoTags": [
    { "name": "校园教育", "level": 1 },
    { "name": "考试考证", "level": 2 },
    { "name": "语言学习", "level": 3 }
  ],
  "chapters": [],
  "series": null,
  "location": null,
  "permissions": {
    "canDuet": true,
    "canStitch": false,
    "canDownload": false,
    "canShare": true,
    "canComment": true
  },
  "crossPostedToXigua": false,
  "inputUrl": "1929015166249580"
}
```

### Important: URL Durability

Different URL types in the output have very different lifespans. Plan your downstream pipeline accordingly.

| Field | Lifespan | Note |
|---|---|---|
| `url` (canonical post URL) | **Permanent** | `https://www.douyin.com/video/<id>` — never expires. The reliable reference. |
| `shareUrl` | **Permanent** | `https://www.iesdouyin.com/share/video/<id>/` — also permanent. |
| `authorMeta.shareUrl`, `authorMeta.profileUrl` | **Permanent** | Profile share/canonical URLs. |
| `authorMeta.avatarThumb`, `authorMeta.avatarLarge` | **Permanent** | CDN-direct, no signature. |
| `musicMeta.playUrl`, `musicMeta.coverLarge` | **Permanent** | CDN-direct, no signature. |
| `thumb`, `videoMeta.cover`, `videoMeta.originCover`, `videoMeta.dynamicCover`, `images[].url`, `authorMeta.bgImage` | **~14–30 days** | Signed CDN URLs (`*-sign.douyinpic.com`). The query string holds the signature; download or re-upload to your own storage if you need them long-term. |
| `videoMeta.playUrl`, `videoMeta.downloadUrl`, `videoMeta.bitRates[].url` | **~1 hour** | Short-lived video CDN URLs. The exact expiry time is in **`videoMeta.cdnUrlExpiresAt`** (unix-seconds) — check it before downloading. |

The `id` and `url` fields are the only truly permanent references. Build your downstream pipeline around them, then re-resolve fresh media URLs whenever you need them.

### Advanced Usage

#### Track follower growth across many creators (cheapest)

```json
{
  "profileUrls": ["1929015166249580", "75736792009", "..."],
  "maxPostsPerProfile": 0
}
```

One row per creator, no posts. Pair with a daily schedule to build a follower-tracking dashboard.

#### Pull only this week's posts from a creator

```json
{
  "profileUrls": ["MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS"],
  "maxPostsPerProfile": 500,
  "recentDays": 7
}
```

The actor stops fetching as soon as it crosses the 7-day boundary, so you only pay for posts within the window.

#### Bulk creator audit

```json
{
  "profileUrls": [
    "1929015166249580",
    "75736792009",
    "63485583690",
    "..."
  ],
  "maxPostsPerProfile": 30,
  "excludePinnedPosts": true
}
```

Fast snapshot of recent (non-pinned) activity across a list of creators. Up to 30 profiles run in parallel.

### Pricing — Pay Per Event (PPE)

**$6.99 per 1,000 results** (base price). Each row written to the dataset counts as one result, whether it's a post row or a profile-only row.

| Event | Per call | Per 1,000 |
|-------|----------|-----------|
| `result` (one dataset row) | $0.00699 | $6.99 |

### FAQ

**How many fields are returned per post?**
28 top-level fields per post (in posts mode), with `authorMeta` containing a further 22 fields nested. In profile-only mode (`maxPostsPerProfile: 0`) the same 22 author fields are promoted to the top level alongside `profileUrl` and `inputUrl`, for 24 fields total.

**What types of profile inputs are accepted?**
Browser address-bar URLs (`/user/MS4w...`), app share links (`v.douyin.com/...`), legacy share URLs (`iesdouyin.com/share/user/<numeric>`), bare UserSecIDs (`MS4w...`), and bare numeric user IDs. You can mix all of them in one `profileUrls` array.

**How fresh is the data?**
Live — every field is fetched on demand at run time. No caching.

**Do video URLs work after the run finishes?**
Image URLs (covers, avatars, image-post photos, profile background) stay valid for roughly 14–30 days. Video play URLs and download URLs are short-lived — they typically expire within hours. The post `url` (`https://www.douyin.com/video/<id>`) is permanent and is the safe long-term reference. See the URL Durability section above.

**What's the difference between `hashtags` and `videoTags`?**
`hashtags` are the `#tag`s the creator typed in the caption. `videoTags` is Douyin's own 3-level content classification — for example a video might be tagged `校园教育` (level 1, top-level category) → `考试考证` (level 2) → `语言学习` (level 3, leaf). The classification is server-assigned and is one of the more interesting signals on the platform.

**What's profile-only mode for?**
Setting `maxPostsPerProfile` to `0` returns just the creator's profile metadata — followers, following, total likes, video count, bio, avatar, region. One row per creator. Ideal for daily follower-tracking dashboards where post-level data isn't needed.

**Why are some `username` fields empty?**
Not every Douyin creator has a `short_id` set on their profile — when they don't, that field comes back empty. The numeric `id` and the `secUid` are always present.

**Can I scrape comments / followers / liked videos?**
Not in this actor. Profile + posts only. Other actors in this collection cover those use cases separately.

**What's the maximum posts per profile?**
10,000. The vast majority of creators have fewer than 1,000 posts, so the cap rarely binds. Cost scales linearly with this value, so set what you actually need.

**Does the actor work for any Douyin creator?**
Public profiles only. Private accounts and accounts that have blocked external access are not addressable.

### Support

- **Bugs**: Issues tab
- **Features**: Issues tab

### Legal Compliance

Extracts publicly available data from Douyin (抖音). Users must comply with Douyin's terms of service and applicable data protection regulations (GDPR, CCPA).

***

*Structured Douyin profile + post data — followers, engagement, video tags, music, bio — for any creator, in clean JSON.*

# Actor input Schema

## `profileUrls` (type: `array`):

Add one or more Douyin profiles you want to scrape.<br><br>Accepted formats:<ul><li>Browser address bar: <code>https://www.douyin.com/user/MS4wLj...</code></li><li>App share link: <code>https://v.douyin.com/iAbc123/</code></li><li>Legacy share: <code>https://www.iesdouyin.com/share/user/...</code></li><li>Bare UserSecID: <code>MS4wLj...</code> (the long base-64 string)</li><li>Bare numeric user ID: <code>1929015166249580</code></li></ul>If both <b>Profile URLs</b> and <b>Start URLs</b> are set, <b>Profile URLs</b> wins.

## `maxPostsPerProfile` (type: `integer`):

How many recent posts (videos and image-text) to include for each profile.<br><br><ul><li>Set to <code>0</code> to scrape <b>profile metadata only</b> — followers, bio, verification, totals — without any posts. Fastest and cheapest mode.</li><li>Maximum is <code>10000</code>. The vast majority of creators have fewer than 1,000 posts, so the cap rarely binds.</li><li>Cost scales linearly with this value, so set what you actually need.</li></ul>

## `recentDays` (type: `integer`):

Only include posts from the last N days. Easier than picking a date — set to <code>30</code> for last month, <code>7</code> for last week, etc.<br><br>Leave blank to keep all recent posts.<br><br>If both this and <b>Posts published on or after</b> are set, <b>Recent days only</b> wins.

## `oldestPostDate` (type: `string`):

Only include posts published on or after this date. Use this when you need a specific cutoff date — otherwise <b>Recent days only</b> above is simpler.<br><br>Format: <code>YYYY-MM-DD</code>. Leave blank to keep all recent posts.<br><br>If both this and <b>Recent days only</b> are set, <b>Recent days only</b> wins.

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

When enabled, posts pinned to the top of the creator's profile are skipped. Pinned posts can be old, so you might want to exclude them when looking at recent activity.

## Actor input object example

```json
{
  "profileUrls": [
    "https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS",
    "1929015166249580"
  ],
  "maxPostsPerProfile": 100,
  "excludePinnedPosts": false
}
```

# Actor output Schema

## `profiles` (type: `string`):

Link to the dataset containing all scraped Douyin profiles and their posts.

# 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 = {
    "profileUrls": [
        "https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS",
        "1929015166249580"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("zen-studio/douyin-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 = { "profileUrls": [
        "https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS",
        "1929015166249580",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("zen-studio/douyin-profile-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "profileUrls": [
    "https://www.douyin.com/user/MS4wLjABAAAAk1tZ-L085zZf2yW_H5dnVFZWyk8Rt8v4RAvf9KhTyPoVdMDxTs7Q_rvgTJGWXezS",
    "1929015166249580"
  ]
}' |
apify call zen-studio/douyin-profile-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=zen-studio/douyin-profile-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

```json
{
    "openapi": "3.0.1",
    "info": {
        "title": "Douyin 抖音 Profile Scraper - 博主 Followers, Posts & Hashtags",
        "description": "Extract Douyin (抖音) 博主 profiles, 粉丝 counts, engagement stats, hashtags, and Douyin's server-classified video categories. 28 fields per post + 22 per author. Accepts profile URLs, share links, UserSecIDs, and numeric user IDs. Profile-only 数据采集 mode for cheap follower tracking.",
        "version": "0.0",
        "x-build-id": "TvlMnCDqhfO4dfN8J"
    },
    "servers": [
        {
            "url": "https://api.apify.com/v2"
        }
    ],
    "paths": {
        "/acts/zen-studio~douyin-profile-scraper/run-sync-get-dataset-items": {
            "post": {
                "operationId": "run-sync-get-dataset-items-zen-studio-douyin-profile-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for its completion, and returns Actor's dataset items in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        },
        "/acts/zen-studio~douyin-profile-scraper/runs": {
            "post": {
                "operationId": "runs-sync-zen-studio-douyin-profile-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor and returns information about the initiated run in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK",
                        "content": {
                            "application/json": {
                                "schema": {
                                    "$ref": "#/components/schemas/runsResponseSchema"
                                }
                            }
                        }
                    }
                }
            }
        },
        "/acts/zen-studio~douyin-profile-scraper/run-sync": {
            "post": {
                "operationId": "run-sync-zen-studio-douyin-profile-scraper",
                "x-openai-isConsequential": false,
                "summary": "Executes an Actor, waits for completion, and returns the OUTPUT from Key-value store in response.",
                "tags": [
                    "Run Actor"
                ],
                "requestBody": {
                    "required": true,
                    "content": {
                        "application/json": {
                            "schema": {
                                "$ref": "#/components/schemas/inputSchema"
                            }
                        }
                    }
                },
                "parameters": [
                    {
                        "name": "token",
                        "in": "query",
                        "required": true,
                        "schema": {
                            "type": "string"
                        },
                        "description": "Enter your Apify token here"
                    }
                ],
                "responses": {
                    "200": {
                        "description": "OK"
                    }
                }
            }
        }
    },
    "components": {
        "schemas": {
            "inputSchema": {
                "type": "object",
                "properties": {
                    "profileUrls": {
                        "title": "👥 Profile URLs or UserSecIDs",
                        "type": "array",
                        "description": "Add one or more Douyin profiles you want to scrape.<br><br>Accepted formats:<ul><li>Browser address bar: <code>https://www.douyin.com/user/MS4wLj...</code></li><li>App share link: <code>https://v.douyin.com/iAbc123/</code></li><li>Legacy share: <code>https://www.iesdouyin.com/share/user/...</code></li><li>Bare UserSecID: <code>MS4wLj...</code> (the long base-64 string)</li><li>Bare numeric user ID: <code>1929015166249580</code></li></ul>If both <b>Profile URLs</b> and <b>Start URLs</b> are set, <b>Profile URLs</b> wins.",
                        "items": {
                            "type": "string"
                        }
                    },
                    "maxPostsPerProfile": {
                        "title": "📺 Maximum posts per profile",
                        "minimum": 0,
                        "maximum": 10000,
                        "type": "integer",
                        "description": "How many recent posts (videos and image-text) to include for each profile.<br><br><ul><li>Set to <code>0</code> to scrape <b>profile metadata only</b> — followers, bio, verification, totals — without any posts. Fastest and cheapest mode.</li><li>Maximum is <code>10000</code>. The vast majority of creators have fewer than 1,000 posts, so the cap rarely binds.</li><li>Cost scales linearly with this value, so set what you actually need.</li></ul>",
                        "default": 100
                    },
                    "recentDays": {
                        "title": "📅 Recent days only",
                        "minimum": 1,
                        "maximum": 3650,
                        "type": "integer",
                        "description": "Only include posts from the last N days. Easier than picking a date — set to <code>30</code> for last month, <code>7</code> for last week, etc.<br><br>Leave blank to keep all recent posts.<br><br>If both this and <b>Posts published on or after</b> are set, <b>Recent days only</b> wins."
                    },
                    "oldestPostDate": {
                        "title": "📅 Posts published on or after",
                        "type": "string",
                        "description": "Only include posts published on or after this date. Use this when you need a specific cutoff date — otherwise <b>Recent days only</b> above is simpler.<br><br>Format: <code>YYYY-MM-DD</code>. Leave blank to keep all recent posts.<br><br>If both this and <b>Recent days only</b> are set, <b>Recent days only</b> wins."
                    },
                    "excludePinnedPosts": {
                        "title": "Exclude pinned posts",
                        "type": "boolean",
                        "description": "When enabled, posts pinned to the top of the creator's profile are skipped. Pinned posts can be old, so you might want to exclude them when looking at recent activity.",
                        "default": false
                    }
                }
            },
            "runsResponseSchema": {
                "type": "object",
                "properties": {
                    "data": {
                        "type": "object",
                        "properties": {
                            "id": {
                                "type": "string"
                            },
                            "actId": {
                                "type": "string"
                            },
                            "userId": {
                                "type": "string"
                            },
                            "startedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "finishedAt": {
                                "type": "string",
                                "format": "date-time",
                                "example": "2025-01-08T00:00:00.000Z"
                            },
                            "status": {
                                "type": "string",
                                "example": "READY"
                            },
                            "meta": {
                                "type": "object",
                                "properties": {
                                    "origin": {
                                        "type": "string",
                                        "example": "API"
                                    },
                                    "userAgent": {
                                        "type": "string"
                                    }
                                }
                            },
                            "stats": {
                                "type": "object",
                                "properties": {
                                    "inputBodyLen": {
                                        "type": "integer",
                                        "example": 2000
                                    },
                                    "rebootCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "restartCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "resurrectCount": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "computeUnits": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "options": {
                                "type": "object",
                                "properties": {
                                    "build": {
                                        "type": "string",
                                        "example": "latest"
                                    },
                                    "timeoutSecs": {
                                        "type": "integer",
                                        "example": 300
                                    },
                                    "memoryMbytes": {
                                        "type": "integer",
                                        "example": 1024
                                    },
                                    "diskMbytes": {
                                        "type": "integer",
                                        "example": 2048
                                    }
                                }
                            },
                            "buildId": {
                                "type": "string"
                            },
                            "defaultKeyValueStoreId": {
                                "type": "string"
                            },
                            "defaultDatasetId": {
                                "type": "string"
                            },
                            "defaultRequestQueueId": {
                                "type": "string"
                            },
                            "buildNumber": {
                                "type": "string",
                                "example": "1.0.0"
                            },
                            "containerUrl": {
                                "type": "string"
                            },
                            "usage": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "integer",
                                        "example": 1
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            },
                            "usageTotalUsd": {
                                "type": "number",
                                "example": 0.00005
                            },
                            "usageUsd": {
                                "type": "object",
                                "properties": {
                                    "ACTOR_COMPUTE_UNITS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATASET_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "KEY_VALUE_STORE_WRITES": {
                                        "type": "number",
                                        "example": 0.00005
                                    },
                                    "KEY_VALUE_STORE_LISTS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_READS": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "REQUEST_QUEUE_WRITES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_INTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "DATA_TRANSFER_EXTERNAL_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_RESIDENTIAL_TRANSFER_GBYTES": {
                                        "type": "integer",
                                        "example": 0
                                    },
                                    "PROXY_SERPS": {
                                        "type": "integer",
                                        "example": 0
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
    }
}
```
