# Douyin Video Scraper API – Metadata, Creator & Engagement Data (`lance_api/douyin-video-scraper-api`) Actor

Scrape structured data from public Douyin videos, including creator profiles, engagement metrics, music, hashtags, timestamps, covers, and direct media URLs. Supports short links, share text, aweme IDs, and batches up to 200 works.

- **URL**: https://apify.com/lance\_api/douyin-video-scraper-api.md
- **Developed by:** [LanceAPI](https://apify.com/lance_api) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.50 / 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/actors/running/actors-in-store.md#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

## Douyin Video Scraper API

**Scrape complete structured data from public Douyin videos — including direct media URLs, creator details, engagement metrics, music, hashtags, covers, and timestamps.**

Submit a Douyin video URL, short link, copied share text, or aweme ID and receive one clean Dataset result ready for analytics, enrichment, APIs, monitoring, and automation.

Need more than a download URL? Get the video plus the data around it — creator details, engagement metrics, music, hashtags, timestamps, covers, and available direct media URLs in one structured result. Process up to 1,000 inputs in one run without providing a Douyin login Cookie.

Pay only when a substantive structured result is returned — failed and duplicate inputs are not charged.

This is an unofficial Actor and is not affiliated with, endorsed by, or sponsored by Douyin or ByteDance.

### Key features

- **Complete video metadata:** Get title, description, timestamps, creator data, engagement metrics, music, hashtags, covers, and available media URLs in one result.
- **Direct media URLs included:** Use available `videoUrl`, `audioUrl`, and `coverUrl` values directly in downstream workflows.
- **Flexible Douyin input formats:** Submit video/note URLs, short links, share links, copied share text, modal URLs, or bare aweme IDs.
- **Batch up to 1,000 works:** Process large input lists while keeping failures isolated per item.
- **Clean structured Dataset output:** Receive normalized results suitable for APIs, analytics, databases, spreadsheets, and automation.
- **No Douyin Cookie required:** Scrape supported public works without providing your Douyin login Cookie.

### Quick start

1. Paste one or more public Douyin video links, short links, share text, or aweme IDs into `urls`.
2. Click **Start**.
3. Open **Output** or **Dataset → Overview**.
4. Use the returned media URLs, creator data, engagement, music, hashtags, and timestamps.

```json
{
  "urls": [
    "https://www.douyin.com/video/7534679152504376595"
  ]
}
```

### Supported inputs

| Input type | Supported example |
| --- | --- |
| Video URL | `https://www.douyin.com/video/7534679152504376595` |
| Note URL | `https://www.douyin.com/note/{awemeId}` |
| Share URL | `https://www.iesdouyin.com/share/video/7677496358793694515` |
| Short link | `https://v.douyin.com/.../` |
| Modal URL | `https://www.douyin.com/jingxuan?modal_id=7534679152504376595` |
| Discover URL | `https://www.douyin.com/discover?modal_id=7534679152504376595` |
| Share text | Copied Douyin text containing a supported URL |
| Aweme ID | Bare numeric ID such as `7534679152504376595` |

Supported note/slides share variants and Markdown-wrapped links such as `[URL](URL)` are also recognized. Profiles, feeds, search pages, comments, private works, and logged-in-only content are outside this Actor's scope.

### Input

| Field | Type | Required | Default | Limits | Description |
| --- | --- | --- | --- | --- | --- |
| `urls` | `array[string]` | Yes | — | 1–1,000 | Public Douyin video/note URLs, short/share links, copied share text, modal URLs, or bare aweme IDs. |

### Output

Each input is processed independently. One unique aweme ID can produce at most one chargeable structured result in a run; later inputs resolving to the same aweme ID are returned as uncharged `duplicate` items. Concurrent batches do not guarantee Dataset order, so match results using `input` or `awemeId`.

The example below is based on a real public Douyin work. Temporary signed media query parameters are shortened because they may expire.

```json
{
  "input": "https://www.douyin.com/video/7534679152504376595",
  "normalizedUrl": "https://www.douyin.com/video/7534679152504376595",
  "awemeId": "7534679152504376595",
  "contentType": "video",
  "title": "雨天开车秒变“睁眼瞎”？玻璃起雾别慌！3步极速除雾法， 新手必存...",
  "description": "雨天开车秒变“睁眼瞎”？玻璃起雾别慌！3步极速除雾法， 新手必存...",
  "createTime": 1754304200,
  "createTimeIso": "2025-08-04T10:43:20.000Z",
  "duration": 67.756,
  "videoUrl": "https://www.douyin.com/aweme/v1/play/?...temporary-parameters...",
  "audioUrl": "https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7534679156710247206.mp3",
  "coverUrl": "https://p3-pc-sign.douyinpic.com/...jpeg?...temporary-parameters...",
  "author": {
    "nickname": "懂车小彬",
    "avatarUrl": "https://p3-pc.douyinpic.com/aweme/100x100/...jpeg",
    "followerCount": 384795,
    "totalFavorited": 3717158
  },
  "engagement": {
    "playCount": 0,
    "diggCount": 11993,
    "commentCount": 617,
    "shareCount": 4887,
    "collectCount": 13171,
    "recommendCount": 472
  },
  "music": {
    "title": "@懂车小彬创作的原声",
    "author": "懂车小彬",
    "audioUrl": "https://sf6-cdn-tos.douyinstatic.com/obj/ies-music/7534679156710247206.mp3",
    "duration": 67
  },
  "hashtags": ["雨天开车除雾正确方法", "新手司机", "新手开车", "青年创作者成长计划"],
  "success": true,
  "status": "success",
  "error": null,
  "scrapedAt": "2026-09-01T...Z"
}
```

The sample's `playCount: 0` is not a fallback: Douyin explicitly returned the `playCount` field with a value of `0` for this work. **Missing optional metrics and profile/music values are returned as `null`, not guessed, estimated, or silently replaced with zero.** Missing list data is returned as an empty array or omitted when the field is optional. Counts are point-in-time values, and direct media URLs may expire.

### Output field reference

| Field | Type | Meaning |
| --- | --- | --- |
| `input` | string | Original submitted input. |
| `normalizedUrl` | string or null | Canonical Douyin video or note URL. |
| `awemeId` | string or null | Unique Douyin work ID. |
| `contentType` | string or null | Normalized type: `video`, `image`, or `unknown`. |
| `title` | string | Work title derived from the source description; an empty string when unavailable. |
| `description` | string | Original work description; an empty string when unavailable. |
| `createTime` | integer or null | Source creation time as a Unix timestamp. |
| `createTimeIso` | string or null | Source creation time in ISO 8601 format. |
| `duration` | number or null | Video duration in seconds. |
| `videoUrl` | string or null | Preferred direct video media URL. |
| `audioUrl` | string or null | Separate direct audio URL when genuinely exposed and accessible. |
| `coverUrl` | string or null | Cover or preview image URL. |
| `author` | object | Available creator information. |
| `engagement` | object | Available public engagement metrics. |
| `music` | object | Available music and audio metadata. |
| `hashtags` | array of strings | Hashtags extracted from source detail. |
| `images` | array of strings | Image-note media URLs when reliably exposed; otherwise omitted. |
| `success` | boolean | Whether a substantive structured result was produced. |
| `status` | string | Stable result classification. |
| `error` | object or null | Safe error details; `null` for `success` and `partial`. |
| `scrapedAt` | string | ISO 8601 timestamp when scraping completed. |

#### Author fields

| Field | Type | Meaning |
| --- | --- | --- |
| `nickname` | string or null | Creator display name. |
| `avatarUrl` | string or null | Creator avatar URL. |
| `followerCount` | integer or null | Public follower count supplied by Douyin. |
| `totalFavorited` | integer or null | Public total-favorites count supplied by Douyin. |

#### Engagement fields

| Field | Type | Meaning |
| --- | --- | --- |
| `playCount` | integer or null | Play count supplied by Douyin. |
| `diggCount` | integer or null | Like count. |
| `commentCount` | integer or null | Comment count. |
| `shareCount` | integer or null | Share count. |
| `collectCount` | integer or null | Collection/save count. |
| `recommendCount` | integer or null | Recommendation count when exposed. |

#### Music fields

| Field | Type | Meaning |
| --- | --- | --- |
| `title` | string or null | Music or original-sound title. |
| `author` | string or null | Music author or owner name. |
| `audioUrl` | string or null | Direct audio URL when available and accessible. |
| `duration` | number or null | Music duration in seconds. |

### Status and errors

| Status | Meaning | Charged? |
| --- | --- | --- |
| `success` | Structured Douyin work data was returned and the direct video URL passed lightweight validation. | Yes |
| `partial` | Structured Douyin work data was returned, but a usable direct video URL was unavailable or failed validation. | Yes |
| `duplicate` | The same aweme ID was already processed in this run. | No |
| `invalid_input` / `unsupported_url` | Input is malformed or outside supported forms. | No |
| `not_found` / `unavailable` / `private` | The work cannot be accessed publicly. | No |
| `blocked` / `login_required` / `rate_limited` | Douyin rejected or limited the anonymous request. | No |
| `timeout` / `upstream_error` / `parsing_failed` | A request or response-parsing problem prevented a structured result. | No |
| `internal_error` | An unexpected safe-to-report processing error occurred. | No |

`partial` is chargeable because the Scraper's product value is structured Douyin detail, not only a downloadable video URL. Both `success` and `partial` are written as substantive results with `success: true`; all failure and duplicate items are uncharged.

```json
{
  "input": "not a Douyin URL",
  "normalizedUrl": null,
  "awemeId": null,
  "success": false,
  "status": "invalid_input",
  "error": {
    "code": "INVALID_INPUT",
    "message": "The input does not contain a supported Douyin URL."
  },
  "scrapedAt": "2026-09-01T...Z"
}
```

### API examples

JavaScript:

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lance_api/douyin-video-scraper-api').call({
  urls: ['https://www.douyin.com/video/7534679152504376595'],
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items);
```

Python:

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ['APIFY_TOKEN'])
run = client.actor('lance_api/douyin-video-scraper-api').call(run_input={
    'urls': ['https://www.douyin.com/video/7534679152504376595'],
})
items = client.dataset(run['defaultDatasetId']).list_items().items
print(items)
```

cURL:

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/lance_api~douyin-video-scraper-api/run-sync-get-dataset-items' \
  -H 'Authorization: Bearer APIFY_TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"urls":["https://www.douyin.com/video/7534679152504376595"]}'
```

The synchronous endpoint returns the run's default Dataset items. For large batches, start the Actor asynchronously and retrieve items from `run.defaultDatasetId` after completion.

### Pricing

This Actor uses pay-per-result pricing. One `result` event is charged when a substantive structured result is successfully produced and written to the Dataset.

| Apify plan | Per 1,000 chargeable results | Per chargeable result |
| --- | ---: | ---: |
| Free | $5.00 | $0.0050 |
| Starter | $4.50 | $0.0045 |
| Scale | $4.00 | $0.0040 |
| Business | $3.50 | $0.0035 |

- `success` and `partial` each create one result charge.
- Invalid, unsupported, unavailable, private, blocked, rate-limited, timed-out, parsing-failed, and internal-error items are not charged.
- Duplicate items are not charged. Different input forms that resolve to the same aweme ID can create at most one chargeable result per run.
- Creator, engagement, music, hashtag, timestamp, image, and media fields do not create separate charges.

**One unique substantive Douyin work = at most one `result` charge per run.**

Check the Actor's **Pricing** tab for the current published prices.

### Use cases

- **Content analytics:** Collect structured metadata and engagement metrics for public Douyin videos.
- **Creator research:** Combine available author information with video-level metrics for creator and content analysis.
- **Social listening and monitoring:** Feed normalized public video data into internal monitoring and reporting systems.
- **Media enrichment:** Enrich existing URLs with creator, music, engagement, timestamps, hashtags, covers, and direct media links.
- **Data pipelines:** Load structured Douyin video data into databases, BI tools, spreadsheets, and analytics workflows.
- **AI and automation workflows:** Pass returned metadata into downstream classification, summarization, transcription, moderation, or agent workflows.

### Use with AI agents

Use this Actor through the Apify MCP Server in compatible AI and automation workflows to turn Douyin video URLs into structured video metadata.

An AI agent can take a Douyin URL, retrieve structured creator, engagement, music, hashtag, and media data, then use that result for downstream summarization, classification, research, monitoring, or automation.

### FAQ

#### What data can I scrape from a Douyin video?

Available fields include description, timestamps, duration, creator information, engagement metrics, music, hashtags, cover, direct video/audio URLs, and processing status.

#### Does it return direct video and audio URLs?

Yes, when Douyin exposes accessible media URLs. Missing or inaccessible audio is returned as `null`; the Actor does not invent an MP3 URL.

#### Does it support short links and copied Douyin share text?

Yes. It resolves supported `v.douyin.com` short links, `iesdouyin.com` share links, copied share text, and the other forms listed above.

#### Does it require a Douyin Cookie or login?

No user Cookie or login is required. Only publicly accessible works are supported.

#### Can it scrape private videos?

No. Private, removed, logged-in-only, region-restricted, or otherwise inaccessible works cannot be scraped.

#### Does it support image notes?

The Actor accepts supported Douyin note URLs because Douyin may expose mixed video/image work types through related endpoints. The product is optimized for video scraping; `images` is returned only when image-note media is reliably available.

#### Are media URLs permanent?

No. Direct media and signed cover URLs may expire. Use or store permitted media promptly.

#### What does `partial` mean?

A `partial` result means structured Douyin work data was successfully returned, but a usable direct video URL was unavailable or failed validation. It still has `success: true` because the core scraper result succeeded, and it creates one result charge.

#### Are failed inputs charged?

No. Failed items are returned for batch visibility but do not trigger a result charge.

#### Are duplicate inputs charged twice?

No. Deduplication uses the resolved aweme ID. Only the first unique structured result can be charged; later duplicate items are not charged.

#### How much does each result cost?

The price depends on the Apify plan: $0.0050 on Free, $0.0045 on Starter, $0.0040 on Scale, and $0.0035 on Business.

#### Can it scrape profiles, feeds, search results, or comments?

No. This Actor handles individual public Douyin works only.

### Limitations

- Public individual works only; no profiles, search results, feeds, comments, private works, or user Cookie input.
- The product is optimized for videos. Image-note fields are best effort and appear only when reliably exposed.
- Media URLs are temporary and may expire; the Actor does not copy media into Apify storage.
- Metadata depends on the fields Douyin exposes for each work. Missing optional metrics and profile/music values are `null`; list fields are empty or omitted; values are never estimated.
- Regional, age, anti-bot, login, or rate restrictions may prevent access to some public-looking works.
- Douyin can change its response structure, which may temporarily affect parsing.
- Dataset order is not guaranteed for concurrent batches. Match items using `input` or `awemeId`.

### Responsible use

Use this Actor only for content you are legally permitted to access and process. Respect copyright, privacy, applicable law, contractual restrictions, and platform terms.

### Support

Contact <lanceapi2026@hotmail.com> or open an issue on the Actor page.

Include the run ID, a safe public input URL, the returned `status`, and `error.code`. Never send Apify tokens, cookies, signatures, authorization headers, passwords, or proxy credentials. Keep API tokens out of source code, screenshots, prompts, and logs.

# Actor input Schema

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

Add 1–1000 public Douyin video or note links. Full douyin.com URLs, iesdouyin.com share links, v.douyin.com short links, jingxuan/discover links, copied share text, Markdown-wrapped links, and bare aweme IDs are supported. Each item is processed independently, so one invalid URL does not stop the batch.

## Actor input object example

```json
{
  "urls": [
    "https://www.douyin.com/video/7534679152504376595"
  ]
}
```

# Actor output Schema

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

One Dataset item per processed unique Douyin work.

# 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.douyin.com/video/7534679152504376595"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lance_api/douyin-video-scraper-api").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.douyin.com/video/7534679152504376595"] }

# Run the Actor and wait for it to finish
run = client.actor("lance_api/douyin-video-scraper-api").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.douyin.com/video/7534679152504376595"
  ]
}' |
apify call lance_api/douyin-video-scraper-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lance_api/douyin-video-scraper-api"
        }
    }
}

```

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/gpYTdE1QlvU03AHRI/builds/Dg2Cm7ddiWsW4vMtP/openapi.json
