Douyin 抖音视频 Video Scraper - Metadata & No-Watermark URL avatar

Douyin 抖音视频 Video Scraper - Metadata & No-Watermark URL

Pricing

from $2.99 / 1,000 videos

Go to Apify Store
Douyin 抖音视频 Video Scraper - Metadata & No-Watermark URL

Douyin 抖音视频 Video Scraper - Metadata & No-Watermark URL

抖音视频详情 for any public Douyin (抖音) post: description, publish time, length, likes, comments, shares, saves, hashtags, music, cover and the watermark-free play URL. Paste video links, /note/ album links, v.douyin.com share links or bare IDs. No login.

Pricing

from $2.99 / 1,000 videos

Rating

0.0

(0)

Developer

Lantern Lab

Lantern Lab

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

7 days ago

Last modified

Share

Douyin 抖音视频 Video Scraper

Read the full public detail (抖音视频详情) of any Douyin (抖音) post: description, publish time, length, likes, comments, shares, saves, hashtags, music, cover image and the watermark-free MP4 play URL - exact numbers, not Douyin's rounded 9.8万. Paste video links, /note/ album links, v.douyin.com share links or bare IDs; no login, no cookies, no account of your own. $2.99 per 1,000 videos, plus $0.005 per run. See Pricing.

Input:

{
"videoUrls": [
"https://www.douyin.com/video/7683413288402612731",
"https://v.douyin.com/iJSMnqRm/"
]
}

Output - one row per video (recordType: "video"), plus one free row per input line and a RUN_SUMMARY. Sample from a real run; nickname partially masked, URLs shortened:

{
"recordType": "video",
"platform": "douyin",
"dataSource": "guest_web",
"awemeId": "7683413288402612731",
"url": "https://www.douyin.com/video/7683413288402612731",
"postType": "video",
"desc": "果树补钙用绿陇糖醇钙,移动性强,好吸收!#糖醇钙 #果树种植 #农资肥料 #钙肥",
"createTime": 1788934062,
"publishedAt": "2026-09-09T06:07:42+00:00",
"durationSec": 38.4,
"author": {
"nickname": "绿陇***",
"secUid": "MS4wLjABAAAA…",
"uid": "1051…",
"douyinId": "lvlong2018",
"url": "https://www.douyin.com/user/MS4wLjABAAAA…",
"verified": true
},
"diggCount": 41,
"commentCount": 2,
"shareCount": 3,
"collectCount": 6,
"playCount": null,
"hashtags": ["糖醇钙", "果树种植", "农资肥料", "钙肥"],
"musicTitle": "@绿陇生物创作的原声",
"musicAuthor": "绿陇***",
"coverUrl": "https://p3-pc-sign.douyinpic.com/…",
"videoPlayUrl": "https://v3-web.douyinvod.com/…",
"imageUrls": [],
"location": null,
"input": "https://www.douyin.com/video/7683413288402612731",
"videoStatus": "available",
"accessMode": "direct",
"collectionStatus": "complete",
"partial": false,
"partialReason": null,
"elapsedMs": 1842,
"collectedAt": "2026-10-24T05:41:12+00:00"
}

Limits:

  • Public data only. The Actor reads what Douyin shows a signed-out visitor and never logs in. No comments, no private or login-only posts, and nothing about the author beyond the public display name and IDs on the post.
  • No MP4 is downloaded. videoPlayUrl is the watermark-free stream Douyin's own player uses, handed to you as a link. It is signed and short-lived, so fetch it soon after the run and send a douyin.com referer. Copying the bytes through Apify storage would bill you for video traffic you may not want.
  • Every row says how complete it is. A post Douyin would not describe - taken down, private, withheld - is reported as such with the reason, never as a video with zero likes.
  • Your limits stop collection and appear in the row: the maxUpstreamRequests request ceiling, the residential-fallback budget (maxFallbackVideos) and the maximum charge per run (see Pricing).

What it does

  • Reads each post's detail the way Douyin's own video page shows it, and writes exactly one row per video - even for a post that could not be read.
  • Accepts every link shape Douyin hands out: /video/<id>, /note/<id> and /slides/<id>, v.douyin.com share links (followed to the post), ?modal_id=<id> links, and bare numeric IDs.
  • Costs one Douyin request per video. A run of 100 videos is one browser session and 100 requests.
  • Deduplicates inside a run: the same post asked for twice is fetched once and charged once, and the second line is reported as a duplicate.
  • Handles 图文 (image-album) posts: their pictures come back in imageUrls, and they carry no videoPlayUrl because Douyin serves none.
  • Marks a row partial with a reason when the post was not read: your request limit, your cost limit, or a refusal by Douyin.
  • Runs without a proxy by default. If Douyin refuses the request for a post, that one post is retried through an Apify residential proxy exiting in China (limited per run, can be turned off). A post Douyin does answer about - gone, private, withheld - is never retried, because no exit changes that answer.
  • Stops minting fresh visitor sessions once a run has seen two posts refused and none answered: Douyin withholds from every visitor, not from one session, so a third page load would only buy the same answer. Each post is still asked once, so each keeps its own evidence.
  • Writes a RUN_SUMMARY - last row of the dataset and a key-value record - with the totals, the requests sent against the ceiling in force, and why the run stopped.

What it does not do

  • No video files. The play URL is handed over; nothing is downloaded or re-hosted, so you are never billed for video traffic.
  • No keyword search. Bring links or IDs. To find videos by keyword first, use the Douyin keyword search Actor.
  • No comments - use the Douyin comments Actor. No account profile numbers - use the Douyin profile Actor.
  • No play counts. Douyin's web API answers a constant 0 for plays whatever the real number, so playCount is null rather than a figure the platform never stated.
  • No private data. Only what Douyin's own video page shows. No email, no phone, no personal name - just the author's public display name, their public IDs and the badge Douyin itself displays.
  • No login-only or age-restricted posts, no live streams, no scheduling built in.

Input

FieldDefaultMeaning
videoUrls-Video links (https://www.douyin.com/video/7...), album links (/note/7...), share links (https://v.douyin.com/...), links carrying modal_id=..., or bare numeric video IDs.
maxUpstreamRequestsworked out from your inputHard ceiling on Douyin requests for the whole run, retries included. Leave empty and the Actor derives one, so a run is never unbounded.
proxyConfigurationno proxyStandard Apify proxy setting for all requests.
residentialFallbacktrueRetry a refused video through a residential proxy in China.
maxFallbackVideos3Videos per run that may use that fallback, at most 20. 0 turns it off.
requestDelaySecs1Minimum pause between two requests from one visitor session.
maxIdentityRotations6Fresh visitor sessions a run may mint after a refusal.
msTokenWaitSecs20How long a new visitor page may take to receive its security token.

Output

Three row kinds in the default dataset, so three different facts can never be mistaken for each other.

recordTypeOne perCharged
videovideo looked uponly when it carries data
input_statusinput line - what it resolved to (found, duplicate, invalid_url, not_collected)never
RUN_SUMMARYrun, as the last row (also in the key-value store)never

Fields on a video row:

FieldMeaning
awemeIdDouyin's own post ID, as a string - it is past the JavaScript safe integer range.
url, postTypeThe post's page, and whether it is a video or an image_album (图文).
descThe description exactly as Douyin shows it, hashtags included. Douyin has one description field; there is no separate title.
createTime, publishedAtThe author's publish time, as Unix epoch seconds and as UTC ISO 8601.
durationSecVideo length in seconds. null for an album.
authornickname, secUid (the permanent MS4w... ID), numeric uid, douyinId (抖音号), profile url, verified.
diggCount, commentCount, shareCount, collectCountLikes, comments, shares and saves - exact, not rounded to 万.
playCountAlways null; see What it does not do.
hashtagsHashtags without the leading #, in Douyin's order.
musicTitle, musicAuthorThe track on the post, and who Douyin credits.
coverUrl, coverUrlsThe cover image, and every cover mirror Douyin served to fail over between.
videoPlayUrlThe watermark-free MP4 stream. Signed and short-lived; expects a douyin.com referer.
imageUrlsEvery picture of an album post, in page order. Empty for a video.
locationThe place name on the post, when the author attached one.
input, collectedAt, elapsedMsYour input line, when the row was collected (UTC, ISO 8601), and time spent on it.
videoStatusavailable, unavailable, deleted, private or unknown. See below.
accessModedirect, custom_proxy or residential_fallback.
collectionStatus, partial, partialReasonHow complete the row is, and why not.

A row never carries an invented value: a field Douyin stated nothing about is null, not 0 and not an empty string. A missing like count and a like count of zero are different facts.

Video status

videoStatusMeaning
availableThe post was read. The only status that is charged.
unavailableDouyin answered but would not describe the post - withdrawn, under review, or withheld. Not "an empty video".
deleted, privateDouyin said so explicitly. Whatever metadata it still returned is kept, flagged.
unknownThe request was refused, or the run stopped before sending it.

What partial means

partial is true whenever collectionStatus is not complete, and partialReason says why:

ReasonMeaning
cap:maxUpstreamRequests=NThe run's request ceiling stopped it - yours, or the one derived from your input. RUN_SUMMARY.upstreamCapSource says which.
cap:maxTotalChargeUsdYour Maximum cost per run was reached; rows past it are not stored.
cap:maxInputs=NMore input lines than one run accepts; the rest are listed, not collected.
blocked:<accessMode>:...Douyin refused the request on that exit, after fresh visitor sessions. The text keeps the classification and Douyin's own status code.
detail:filtered:<Douyin's wording>Douyin answered about the post but would not describe it, in its own words.
detail:is_delete, detail:private_statusDouyin says the post is deleted or private.
fallback_cap:maxFallbackVideos=NThe post was refused and the run had used up its residential retries.
input:no_aweme_idNo Douyin post ID in that input line.
input:duplicate_in_runThe same post was already collected earlier in this run.

collectionStatus is complete when the post was read, blocked when Douyin refused the request, and not_collected when nothing could be read or nothing was attempted.

Pricing

Pay per event: $2.99 per 1,000 videos, plus $0.005 for each run. Apify platform usage, including the browser session and the residential fallback, is included; these two events are the whole price.

EventPriceCharged for
result$0.00299 ($2.99 per 1,000)Each row that carries a video.
run-start$0.005, once per runThe signed-out browser session every run opens before it reads any post.

A row that only reports a failure - an input line with no post ID, a duplicate, a post Douyin would not describe, a post the run never reached - is written free. A run that reads no post at all still pays the $0.005 session.

The session is a flat fee per run, not per video, so a batch costs less per video than many small runs: 10 videos cost $0.035 ($0.0035 each), 100 videos cost $0.304 ($0.0030 each), 1,000 videos cost $2.995.

To cap a run, set Maximum cost per run in the run options. When the cap is reached the Actor stores no further rows, stops before the next video, marks what it cut short partial with cap:maxTotalChargeUsd, and records it in RUN_SUMMARY.

Resources

  • Runs with 1 GB memory by default; 1-8 GB can be chosen in the run options. A visitor session is minted in a real browser, which needs 1 GB.
  • A run opens a visitor session first (about 20-40 seconds), then takes a couple of seconds per video.

Notes

  • Respect Douyin's terms and local law, and only collect what you need. Nicknames and descriptions are personal data in many jurisdictions.
  • Douyin changes its web client often. RUN_SUMMARY reports request outcomes per endpoint, so a change shows up there first.