Douyin Data API Test: 672 Posts in 34 Pages
We read a museum's Douyin account: profile, 34 pages of posts (672 items, 0 duplicates), video details and comments. The post list cost $0.0189.

On November 14, 2026, we used Python requests to read one public Douyin account. The account belongs to the National Museum of China. We called the profile, the post list, one video detail, comments, comment replies and one transcript. The post list took 34 pages and returned 672 items. After de-duplication by post id, there were 0 duplicates. Paging the list to the end cost $0.018904, or about $0.028 per 1,000 items.
Of the 672 items, 655 have the museum as the author. The other 17 are co-created posts from 10 other accounts. The median like count of these 17 posts is 8,810. The median for the museum's own posts is 281.
The museum has 623 videos with a duration. Videos under 60 seconds have a median of 587 likes. Videos of 300 seconds or more have a median of 164.
We read one video three times in 48 minutes. Each time, the video detail call returned three fields that the list did not have. They are the author's Douyin ID, the author bio and the author's total likes. The video's likes went from 8,691 to 8,703.

Douyin user profile API: three routes, and who can read whose data
The official API reads only the accounts that authorized your app. On the Douyin Open Platform, the account and video endpoints use an access_token that a user authorized. The get public user info document gives the scope user_info and says that it needs user consent. It says that the endpoint returns the Douyin user's public information: nickname, avatar, gender and region. The response sample also has open_id and union_id.
The authorized account video list needs an access-token header, and the document says that "this token needs user consent". The same document says that a time filter is not supported yet. So the official route fits an institution that wants data for its own account. To read another museum or a science account, you must first ask that account to authorize your app.
Open-source scripts can read public profiles. But they need a web login session, or you must compute the request signatures yourself. The DouK-Downloader README says that the project no longer maintains its encryption parameter code, for legal compliance. When a platform update breaks a feature, the user must supply that code. MediaCrawler keeps a login session with Playwright. By default, it connects over CDP to a signed-in Chrome on your computer, Chrome 144 or later.
Its disclaimer forbids commercial use. The third route is a pay-per-call API. You send an account secUid or a video link, and you get structured JSON. You do not need the other account's consent, and you do not deploy or maintain scripts. You pay per call, and the API provider decides the fields.
| Item | Douyin Open Platform | Open-source scripts on GitHub | Pay-per-call API (EveryInfra in this test) |
|---|---|---|---|
| Whose profile and posts | Only accounts that authorized your app | Public pages; most projects need a login session | Public pages; send the secUid |
| Entry | Apply per capability; the platform reviews it; user interaction data is for organizations only | No entry check; you deploy it | Sign up and get a key |
| Profile fields | user_info returns nickname, avatar, gender and region | Depends on the project; names follow web endpoints | 24 catalog fields; 16 had values in this test |
| Post list | Video list of the authorized account; cursor pages; no time filter | Most support it; one README warns that you may get only a few posts | 20 items per page in this run; page until next_page_token is gone |
| Upkeep | Server certificate upgrade due by October 31, 2026 | Signatures, login sessions, risk checks; a recent issue reports no post details after a new login | The API provider maintains it |
| Price | The capability is free; staff time and review are extra | You pay for servers and proxies | $0.000556 per call; comments and replies cost $0.000556 per 20 items |
Sources for the official column: the user interaction data capability page, the public user info capability page and the certificate notice. The open-source column comes from the README files and issues that we quote below. Prices in the pay-per-call column come from the EveryInfra capability catalog, which we read on November 14, 2026, at 13:05 Singapore time.
The official Douyin Open Platform: consent first, then data
The Douyin Open Platform splits account data and video data into separate capabilities. You apply for each one, and each one has its own review. The video data capability page says that, with user consent, you can query video data. This includes basic video information, such as the title, cover, pinned status and creation time, and the official like, play, share and comment counts. Its use case is to pair it with the "publish to Douyin" capability and show the consent window when a user publishes a video. The video data query document says that it returns only public video data and that the data is real time.
If a video is private, the record has a creation time of 0. The statistics object in the response sample has six counts: likes, downloads, plays, shares, forwards and comments. The play count play_count is one of them. After the owner gives consent, you can read it. For an institution's own account, this is the most direct use of the official route.

The user interaction data product reads total followers, new followers per day and profile visitors. It also reads new plays, likes, comments and shares per day for each post. The use-case section says that developers cannot use it to build data service products for sale or to do platform statistics. The entry condition says that only companies, government bodies and public institutions can apply. The page also says that after the first consent, the full data appears on the next day.
For a museum's social media team, this route fits well. It is their own account, they give consent, and they get full counts that include plays. A researcher who wants to compare the public posts of 50 museums must get consent from all 50. Also, the capability page says that this data cannot support platform statistics.
Keep the consent token safe. The get access_token document says that a token stored on the client can be stolen, and it recommends storing it on the server. One note says that after you get an access_token, you must not use the temporary authorization code again, because that makes the earlier code expire. A scheduled job must treat "the token will expire soon, and the owner must authorize again" as an event that alerts a person.
Another change starts in November. The Open Platform updated its certificate notice on March 23, 2026. It says that from November 2026, the platform will use certificates without a cross-signed root. Three domains change: open.douyin.com, v.douyin.com and www.iesdouyin.com. Developers had to upgrade by October 31, 2026.
To check your system, use the G2 column in DigiCert's root certificate compatibility table. The FAQ in the notice says that only some old systems and old Java versions need the upgrade. The upgrade is free. A program that upgrades after the deadline works again after the upgrade.
The mini-program side has a version for business consent. The video data query with business consent first needs a binding to a brand, staff or partner account. Then the Douyin user must approve the business relationship. Even then, you can query only the videos that the token owner uploaded.
How this compares with TikTok's official APIs
TikTok uses the same design. The Display API getting started guide asks the app to get two scopes, user.info.basic and video.list. On the video list endpoint, max_count has a default of 10 and a maximum of 20. The paging cursor is a timestamp in milliseconds, so you can ask for videos posted before a given time.
The Research API reads public data for research institutions. TikTok says that applicants can typically expect a reply within 4 weeks. A Ph.D. candidate must also send an endorsement letter from a professor. On both platforms, the official API first asks who gave you consent, and then what you can read.
| Item | Douyin Open Platform | TikTok for Developers |
|---|---|---|
| Read your own account | Yes, after user consent | Display API with user.info.basic and video.list |
| Video list paging | Cursor pages; no time filter | Up to 20 videos per page; cursor is a timestamp |
| Public data for research | Not in the documents that we read | Research API; reply typically within 4 weeks |
| Entry limits | Some products only for organizations | Research API for researchers; Ph.D. candidates need a letter |
The developer type also controls which capabilities you can request. The user types and permissions page has two types: in-house developers and system service providers. Any registered user can choose the in-house type and gets the basic permissions after review. System service providers also get permissions for local services. Both types can verify as an enterprise account, which adds a set of enterprise capabilities. With the screenshot above, this means that user interaction data opens by organization type, and an institution must apply for full counts itself.
Open-source scripts: what the README files and issues say
Douyin_TikTok_Download_API version 5 makes guest identities with a headless browser and keeps its own identity pool. Its capability table checks "author profile" and "author posts" for Douyin. It also says that Douyin follower and following lists are open only to signed-in sessions, so it does not register those two endpoints. Search and hashtag feeds are the same: a guest cannot read them. On October 31, 2026, in issue #805, the maintainer replied to a user.
The direct video link has a hex expiry time in its path. That link expires about three hours after it is signed. After it expires, every domain returns 403. The maintainer suggests the instance's download endpoint, which parses the post again when a stored link expires.
The Chinese README of douyin-downloader is direct. It says that Douyin security checks now block the command-line version for single videos and image posts, collections, music, likes and favorites. For profile posts, you can try browser automation, but success is not certain. The first FAQ item asks why a profile returns only a few posts. The answer is to open a browser, turn off headless mode and pass the check yourself. The issue list has these titles in the last 30 days.
On October 26, #258 says that the security check allows only requests from inside the web page. It adds that retry or a new login does not help. On November 9, #263 says that Douyin returned no post details. The user had signed in again and got new cookies, and the tool worked a few weeks before; the desktop app was normal. An earlier issue, #253 on October 9, says that when the user downloaded their own favorites, every author nickname became "self".
f2 marks Douyin "user info", "profile posts" and "single post" as available with or without login. But by default, requests use its open-source "ab" signature. The title of issue #350 says that downloads fail after the user sets the interval to specific dates. The log in the issue shows 20 items per request and a date range from 2025-03-01 to 2025-07-06.
The douyin-cli README splits login into two lines. Web search, profile posts and single posts use browser cookies. Official user info and comment endpoints use an OAuth access token. It says that a web cookie cannot replace an OpenAPI token, and an OAuth token cannot replace a web cookie.
| Project | How it reads Douyin | What its own text says | Recent public issue |
|---|---|---|---|
| Douyin_TikTok_Download_API | Guest identities from a headless browser | Follower lists, search and hashtag feeds need login | #805, 2026-10-31: direct video links expire in about 3 hours |
| douyin-downloader | Cookies; browser automation for profiles | Security checks block single-video downloads on the command line | #263, 2026-11-09: no post details after a new login |
| f2 | Its own "ab" signature | Profile posts with or without login | #350: date-range download failed |
| douyin-cli | Browser cookies plus an OAuth token | One kind of credential cannot replace the other | None quoted |
| MediaCrawler | Playwright with a signed-in Chrome over CDP | For study and research only; no commercial use | None quoted |
Four of the five projects need a login session or a browser. Douyin_TikTok_Download_API makes guest identities with a headless browser. douyin-downloader and douyin-cli use cookies. MediaCrawler connects to a signed-in Chrome. Only f2 says that it reads profile posts without login, and it carries its own signature code for that.
The cost of the open-source route is in three areas: login sessions expire, signature code changes, and web risk checks stop command-line requests. In their disclaimers, most maintainers give legal responsibility back to the user. We did not run these projects. Every point in this section comes only from their public text.
The pay-per-call Douyin data API: five steps to read an account
We ran the third route ourselves. The EveryInfra catalog has six Douyin account and post capabilities: douyin/profile, douyin/user_posts (post list), douyin/video (single video detail), douyin/comments, douyin/comment_replies and douyin/transcript. Profile, post list, video detail and transcript cost $0.000556 per call. Comments and replies are charged in blocks of 20 items, $0.000556 per block. A block with no items costs nothing. Each capability has a page under the Douyin Scraper API, for example profile, user posts, video detail, comments and transcript.

Use the secUid to find an account. The catalog says that user_id is the Douyin user's secUid, which usually starts with MS4w. It is not the nickname or the short Douyin ID. You can take it from the web profile address, after douyin.com/user/, or from the author_id in search results. The museum's web profile is douyin.com/user/MS4wLjABAAAAH26VW7w8VFw_GxiN0TNSb0HyDLcHkQQdzE2EmUHEJJQ.
Its Douyin ID is chnmuseum. These are two different things. The Douyin ID is a short name that the user sets. The secUid is the long string in the web address.
The code uses the Python requests library, version 2.34.2 on our machine. Below is a simplified version. The key comes only from an environment variable. On a 429 response, the code waits for the Retry-After header. If there is no such header, it waits longer after each try.
import os, time, requests
API = "https://api.everyinfra.com/api/v1/social"
HEAD = {"Authorization": f"Bearer {os.environ['EVERYINFRA_API_KEY']}"}
def call(action, params):
for attempt in range(5):
r = requests.post(API, headers=HEAD, timeout=180,
json={"platform": "douyin", "action": action, "params": params})
if r.status_code == 429: # rate limit: use Retry-After, else back off
time.sleep(float(r.headers.get("Retry-After", 2 ** attempt * 5)))
continue
r.raise_for_status()
return r.json()
raise RuntimeError("429 retries exhausted")
SEC = "MS4wLjABAAAAH26VW7w8VFw_GxiN0TNSb0HyDLcHkQQdzE2EmUHEJJQ" # National Museum of China
profile = call("profile", {"user_id": SEC})["results"]
posts, token = [], "" # page 1: empty string
while True:
page = call("user_posts", {"user_id": SEC, "page_token": token})
posts += page["results"]
token = page.get("next_page_token")
if not token: # no next_page_token: last page
break
seen = {}
for p in posts: # de-duplicate by id
seen.setdefault(p["id"], p)
own = [p for p in seen.values() if p["author_id"] == SEC] # keep the account's own posts
url = max(own, key=lambda p: p["posted_at"])["url"] # newest post by posted_at
video = call("video", {"url": url})["results"]
comments = call("comments", {"url": url, "page_token": ""})
transcript = call("transcript", {"url": url})["results"]
print(profile["follower_count"], len(seen), len(own), video["like_count"])The same call with curl is below. From page 2, put the last page's next_page_token into page_token without change. Keep all other parameters the same. If you change them, the token stops working and the API returns 422. Then start again from page 1.
curl -s https://api.everyinfra.com/api/v1/social \
-H "Authorization: Bearer $EVERYINFRA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"platform":"douyin","action":"user_posts",
"params":{"user_id":"MS4wLjABAAAAH26VW7w8VFw_GxiN0TNSb0HyDLcHkQQdzE2EmUHEJJQ","page_token":""}}'If you use AI tools, the same capabilities are in the remote MCP server at https://api.everyinfra.com/mcp. See the MCP setup guide. For daily jobs and calls that retry by themselves, use REST and send an Idempotency-Key header. A replay with the same key is not charged again. See retries with an idempotency key.
Test 1: the profile, 24 catalog fields in one call
The first test time was 13:07–13:18 Singapore time on November 14, 2026. We sent douyin/profile at 13:07:15. It returned 1,067,081 followers, 26 following, 3,001,617 total likes and 659 posts. The verification text was "National Museum official Douyin account". is_verified was true and is_live was false. Over the three profile calls, the median time was 1.62 seconds.
The catalog lists 24 profile fields. In this test, 16 had values. The 8 empty fields were gender, IP location, country, language, likes given, shop, age and series (gender, ip_location, country, language, likes_given_count, has_shop, age, has_series). An institution does not fill in gender or age, and the web profile does not show the IP location, so this makes sense. These 8 fields may have values on personal accounts. Our sample has only one institutional account, so we can only say "empty in this sample".
Use profile data as a snapshot. Followers, total likes and post count are running totals. Read them once a day, and you can draw a growth curve. The post count is the number that the platform shows.
To count how many posts the account itself made, use the post table filtered by author_id. One call costs $0.000556. If you read 50 institutional accounts once a day, one month costs 50 × 30 × $0.000556 = $0.834.
Test 2: paging the post list to the end, and 17 co-created items
We paged the post list from 13:07:26 to 13:16:57 Singapore time, 34 pages in total. In this run, each page returned 20 items. Pages 14 and 33 had 19 each, and the last page had 14. The total is 672.
After de-duplication by id, there are still 672, with 0 duplicates. On page 34, the response had no next_page_token, and pagination.has_more was false. The 34 calls cost $0.018904.
Look at the time in two parts. We read page 1 once at each of the three test times, and the median was 13.08 seconds (3 calls). Pages 2 to 34 had a median of 2.29 seconds (33 calls). Set the timeout of a scheduled job for the slower page 1.
Of the 672 items, 655 have an author_id equal to the museum's secUid. The other 17 come from 10 other accounts: a publisher's flagship store, official accounts of ByteDance and Doubao, and some individual creators (names not shown). These are Douyin co-created posts. The other account started the post, and the museum is a co-creator, so the post shows in the museum's list.
The co-created posts get far more likes than the museum's own posts. The 17 posts have a median of 8,810 likes, and the top one has 225,867. The museum's 655 own posts have a median of 281. Most of the starting accounts are platform accounts with more followers, and the post shows on both profiles.
So the gap comes from the other account's audience, and you must not count it as the museum's own content result. For "how many posts did this account make" and "how does its own content do", use only the 655 items filtered by author_id. For "what content shows on this profile", use all 672.
| Item | Value | How we got it |
|---|---|---|
| Pages | 34 | From page_token="" until no next_page_token |
| Items returned | 672 | 20 per page; 19 on pages 14 and 33; 14 on page 34 |
After de-duplication by id | 672 | 0 duplicates |
| Author is the museum | 655 | author_id equals the museum secUid |
| Co-created posts | 17 items / 10 accounts | Author is another account |
| Median likes, co-created | 8,810 | like_count of the 17 items |
| Median likes, museum's own | 281 | like_count of the 655 items |
| Video / image posts | 640 / 32 | media_type |
| Charged | $0.018904 | 34 × $0.000556 |
| Per 1,000 items | $0.0281 | 0.018904 ÷ 672 × 1,000 |
The oldest post is from May 15, 2018 (UTC). The newest is the "nine dragons and nine phoenixes crown" exhibition video from November 10, 2026, 12:00 Beijing time. The catalog says that paging does not filter by since. To read a time window, page to the end and filter by posted_at yourself. The official video list also has no time filter.
For daily updates, read page 1 again at a fixed interval and merge it into your table by post id. Insert new IDs, and update the counts of IDs that you already have. The museum posts 2 to 15 times a month, so 20 items on page 1 once a day cover new posts. That is 1 call per account per day.
Test 3: what the Douyin video detail API adds to the list
We sent the first video detail call at 13:17:45 Singapore time. We used the newest post in the list: the exhibition video for "Ming Rites and Splendor: the Nine Dragons and Nine Phoenixes Crown of Empress Xiaoduan", posted on November 10, 2026. The National Museum organizes the exhibition. A CCTV report on November 10 says that it opened to the public on November 4, 2026. It is in the museum's North Hall 16, as a long-term special exhibition.
A museum preview from October 30, 2026 says that the crown left the "Ancient China" gallery from November 2, 2026. The exhibition page says that the crown came from the Dingling tomb in Changping, Beijing, in 1957. It is 48.5 cm high, weighs 2,320 g, and has 115 gems and 4,414 pearls. Xinhua published photos of the hall on the same day, taken on November 9.

For the same video, we read list page 1 and the video detail once at each of the three times. We count only the fields that had a usable value all three times; empty, 0 or "unknown" does not count. The list had 27 such fields for this video, and the detail had 29. Each time, the detail added three author snapshot fields: author_douyin_id (chnmuseum), author_bio (the account bio) and author_like_count (the account's total likes, 3,001,633 at 13:55).
Both calls share 26 fields with the post and basic author data. The post fields are id, link, text, hashtags, duration, width and height, and posting time. Others are the cover, animated cover, background music, the four counts, is_pinned and is_ad. The author fields are name, avatar, uid and verification.
So a detail call only for the like, comment, share and save counts costs money twice, because list page 1 already has them. Use the detail call to get the author's Douyin ID, bio and total likes without a separate profile call. This fits when you start from a video link and need to find the author.
The catalog response_fields for the video detail also list video tags, city, quality levels, permissions and the address expiry time. The catalog describes them as follows. video_tags are content class labels that the platform gives to a post. city is the city where the post was made, in pinyin. video_bitrates are playback addresses for each quality level.
permissions are the comment, download, duet and other rights that the author sets, and they contain only the items that the platform gives. video_url_expires_at is the time when the playback and download addresses expire, after which you must read them again. We only repeat the catalog text for these fields and draw no results from them. If you plan to use them for classes or download checks, first measure on your own sample how often they have a value.
Handle address fields the same way as the open-source projects. In issue #805, the maintainer found that a web direct link expires about three hours after it is signed. The catalog also says that the addresses in video_bitrates are signed and expire. In your archive, store only the video id and the post link. Before you play or download, read the detail again by id. Do not store an address as a long-term field.
For plays, the catalog says that view_count is not a real play count, and that Douyin does not publish video play counts. To judge reach, use likes, comments, shares and saves. To get plays, use the official video data capability with the owner's consent. For researchers, these four counts are the metrics that you can compare. They are in both the list and the detail. In our three reads, they rose in the same way over time (see the three test times below).
| Field group | List `user_posts` (all three reads) | Detail `video` (all three reads) | Use |
|---|---|---|---|
| Counts: likes, comments, shares, saves | Yes | Yes | Track daily with list page 1 |
| Post: id, link, text, hashtags, duration, posting time | Yes | Yes | The main part of the post table |
| Cover, animated cover, background music | Yes | Yes | Display and de-duplication |
| Author name, avatar, uid, verification | Yes | Yes | Mark co-created posts |
Author Douyin ID author_douyin_id | No | Yes | Find the account from a video |
Author bio author_bio | No | Yes | Account profile |
Author total likes author_like_count | No | Yes | Total likes without a profile call |
Plays view_count | — | — | The catalog says it is not a real play count |
The post list row in the chart has 10 fields with values in some rows. image_urls has values only on the 32 image posts. video_url and duration_seconds have values only on videos (95.2%). region has a value on 21.6% of posts, title on 20.4%, and hashtags on 79.3%.
These shares depend on post type and posting year, so they are not fixed numbers. Treat the list as the index and the detail as the file. Paging one account to the end costs less than 2 cents. A detail call costs $0.000556 per post, so use it only for the posts where you need the author data or a deeper look.
Test 4: comments, replies and the video transcript
We sent the comments call at 13:18:12 Singapore time with an empty page_token. It returned 20 top-level comments and a token for the next page. It cost one block, $0.000556. The catalog lists 18 comment fields (not counting the token). In this test, 14 had values.
ip_location (for example Henan, Zhejiang or Beijing), reply_count and liked_by_author were there. is_hot, reply_to_id, images and mentioned_users were empty in this sample. The top-level comment with the most likes had 244 likes and 15 replies. The comment authors are individual users. In our analysis, we use only counts and regions, and we do not store nicknames.
At the second time, 13:37 Singapore time, we used douyin/comment_replies to read the replies to that comment. We sent the video link, the comment id and an empty page_token. It returned 15 replies, which matches the reply_count of 15 on the comment. pagination.has_more was false. It cost one block, $0.000556. Two of the 15 replies have reply_to_reply_id and reply_to_author_name, so they are replies to replies.
Three have mentioned_users. In the same minute, we used the page 1 token to read comment page 2. It returned 13 comments and also cost one block. The 15 replies have 50 likes in total, and the top one has 30. That is one order of magnitude below the top-level comment, so count top-level comments and replies apart.
| Call | Time (Singapore) | Items returned | Charged |
|---|---|---|---|
douyin/comments, page 1 | 13:18:12 | 20 | $0.000556 |
douyin/comments, page 2 | 13:36:55 | 13 | $0.000556 |
douyin/comment_replies | 13:37:07 | 15 | $0.000556 |
douyin/transcript | 13:18:23 | 9 segments | $0.000556 |
We sent the transcript call at 13:18:23. It took 18.92 seconds (1 call) and split the 69-second video into 9 sentences with start and end times.
The transcript comes from speech recognition, so words that sound the same can be wrong. The museum's exhibition page has a four-character phrase for "gold and kingfisher blue shine together". In the transcript, two of those four characters are wrong homophones. In another place, the transcript has a wrong first character in the word for "fine dust", which we can tell from the context. When you search transcripts for keywords, also search the title and hashtags.
Three times: how the counts for one video change
The three test times were 13:07–13:18, 13:36–13:37 and 13:55, all Singapore time. From the first request to the last, 48 minutes and 39 seconds passed. At each time, we read the profile once, list page 1 once and the crown video detail once. At the second time, we also read comment page 2 and the replies. At the third time, we read comment page 1 again.
| Time (Singapore) | Video likes | Video comments | Video shares | Video saves | Followers | Account likes |
|---|---|---|---|---|---|---|
| First: list 13:07, detail 13:17, profile 13:07 | 8,691 (list) / 8,696 (detail) | 684 | 1,009 | 566 | 1,067,081 | 3,001,617 |
| Second: 13:36 | 8,700 | 685 | 1,010 | 567 | 1,067,087 | 3,001,631 |
| Third: 13:55 | 8,703 | 685 | 1,010 | 567 | 1,067,087 | 3,001,632 |
In 48 minutes, this 4-day-old exhibition video gained 12 likes, from 8,691 in the list at 13:07 to 8,703 at 13:55. Comments, shares and saves each gained 1. The account gained 6 followers and 15 total likes. At one time, the two sources agree. At the second time, the list at 13:36:13 and the detail at 13:36:35 both show 8,700 likes.
At the third time, 13:55:11 and 13:55:33 both show 8,703. At the first time, the list and the detail differ by 5 likes, because the two requests were 10 minutes apart. Of the other 19 posts on page 1, only 1 changed (+1) between the first and second times. None changed between the second and third times.
Set the tracking rate by post age. On a museum account, counts on older posts barely move in an hour. So one read of page 1 per day is enough. To follow the spread after a big exhibition opens, raise the rate only for the newest two or three posts. For example, call douyin/video once an hour: 24 calls per post per day, $0.0133. Median times at the three test times: profile 1.62 seconds (3 calls), video detail 11.71 seconds (3 calls), list page 1 13.08 seconds (3 calls).
Cost per 1,000 items: about $0.028 for lists, $0.556 for single-item calls
We grouped all real calls in this article by capability. For each one, we divided the charged amount by the items returned, then multiplied by 1,000. For capabilities that return one page per call, the page size spreads the unit price. For capabilities that return one item per call, the cost per 1,000 items is 1,000 × $0.000556.
| Capability | Calls | Items returned | Charged | Per 1,000 items | Median time (samples) |
|---|---|---|---|---|---|
douyin/profile | 3 | 3 | $0.001668 | $0.556 | 1.62 s (3) |
douyin/user_posts | 36 | 716 | $0.020016 | $0.0280 | 2.37 s (36) |
douyin/video | 3 | 3 | $0.001668 | $0.556 | 11.71 s (3) |
douyin/comments | 3 | 53 | $0.001668 | $0.0315 | 1.99 s (3) |
douyin/comment_replies | 1 | 15 | $0.000556 | $0.0371 | 2.50 s (1) |
douyin/transcript | 1 | 1 | $0.000556 | $0.556 | 18.92 s (1) |
| Total | 47 | 791 | $0.026132 | — | — |
The 716 list items are the sum from 36 calls. These are the 34 paging calls, plus page 1 at the second and third times. Page 1 at the first time is also page 1 of the paging run. So one post can count more than once. For the paging run alone, it is 34 calls, 672 items and $0.0281 per 1,000 items. The 53 comments come from three calls (20, 13 and 20 items), and each call cost one block.
Here are three cases at this unit price. First, an institution tracks its own account each day: 1 profile call and 1 list page 1 call. That is $0.001112 per day and $0.033 per month. Second, a researcher reads 50 institutional accounts for the first time.
If each account is near the museum's size (34 pages), the first run is about 50 × 35 × $0.000556 = $0.973. After that, 2 calls per account per day cost 50 × 2 × 30 × $0.000556 = $1.668 per month. Third, read the detail and comment page 1 for 500 key posts: 500 × 2 × $0.000556 = $0.556. Each formula shows its assumptions, so you can put in your own account and post counts.
| Case | Calls | Cost |
|---|---|---|
| One institution tracks its own account | 2 per day | $0.001112 per day, $0.033 per month |
| First paging run for 50 accounts | 50 × 35 | $0.973 once |
| Daily tracking for 50 accounts | 50 × 2 × 30 | $1.668 per month |
| Detail and one comment page for 500 posts | 500 × 2 | $0.556 |
Store the data: three tables and daily updates
Together, the tests above give three tables. The first is an account snapshot table with one row per account per day. It stores followers, following, total likes and post count from douyin/profile. The key is the secUid plus the date. In our three profile calls over 48 minutes, followers went from 1,067,081 to 1,067,087, and total likes from 3,001,617 to 3,001,632.
The second is a post table with one row per post. The key is the post id. It stores author_id, posted_at, media_type, is_pinned, hashtags and duration. When you build the table, page the post list to the end. After that, read page 1 again at a fixed interval and merge the whole page by id.
Insert new IDs. For IDs that you already have, update only the counts and is_pinned. The third is a post count table with one row per post id per date. It stores the like, comment, share and save counts, also from the daily page 1. To keep tracking an older post, call douyin/video for it when you need to.
Three more rules. First, do not store video or cover addresses. Read them by post id when you need them, for the reasons in issue #805 and in the catalog text. Second, add a flag "author is this account" to the post table. Filter co-created posts out when you count the institution's own output, and keep them when you count "content on this profile".
In the museum example, the 17 co-created posts change total likes from 1,392,825 to 2,051,983, almost half more. They change the top 10 share from 52.1% to 57.3%. Third, store only counts, regions and times for comments, not nicknames or avatars. If you need to link comments from the same person, store a salted hash.
With this design, one institution needs 2 fixed calls per day, and 50 institutions need 100. The monthly cost is above. For 50 institutions, the first build is about 34,000 rows (at 672 per account). After that, about 3,750 rows are added per year (at the museum's 75 posts in the last 12 months). A normal laptop can hold this.
A public culture example: what a museum's post data shows
The 34 list pages hold 655 posts with the museum as author. With them, we can measure how one museum works on Douyin. The median video length is 124 seconds (623 videos with a duration; quartiles 63 and 205 seconds). The longest video is 2,714 seconds.
Of the 655 posts, 516 have hashtags. The most frequent are "National Museum" 154 times, the museum's short name 126 times, "cultural relics" 104 times and "exhibition" 102 times. By posting year, 2021 has the most posts, 125. 2025 has 85, and 2026 up to November 10 has 71 (UTC years).
Likes are very concentrated. The 655 posts have 1,392,825 likes in total, a mean of 2,126 per post, but a median of only 281. The top 10 posts hold 52.1% of all likes. Six of these 10 are from the "Happy birthday, my motherland" series in September and October 2019.
Two are VR exhibition previews from the "Visit the museum from home" series in February 2020; the top post has 180,091 likes. The other two are from "Let relics move" in January 2019 and "Come to the museum to see China" in January 2023. A mean goes up with a few spread events. Report the median and the top 10 share together, because they are closer to the museum's normal reach.
The median likes differ a lot by year. Do not compare posts from different years of one account with a mean:
| Posting year (UTC) | Posts | Median likes |
|---|---|---|
| 2018 | 17 | 2,430 |
| 2019 | 64 | 728.5 |
| 2020 | 46 | 796.5 |
| 2021 | 125 | 181 |
| 2022 | 94 | 312.5 |
| 2023 | 68 | 437.5 |
| 2024 | 85 | 230 |
| 2025 | 85 | 157 |
| 2026 (to Nov 10) | 71 | 281 |
If you leave out 2018, which has only 17 posts, the yearly median is between 157 and 797. The highest year, 2020, is about 5 times the lowest, 2025. 2021 has the most posts (125) but a median of only 181. The 75 posts from the last 12 months (since 2025-11-14) have a median of 283. So to judge "how did the museum's content do this year", compare posts from the same year or the same time window. A full post table from a complete paging run gives you that.
Length and likes show a clear pattern. We split the 623 videos into four length groups. Under 60 seconds: 142 videos, median 587 likes. 60 to 119 seconds: 158 videos, 302. 120 to 299 seconds: 229 videos, 245. 300 seconds or more: 94 videos, 164.
Longer videos have lower medians, and the shortest group is about 3.6 times the longest. More than half of the museum's videos (323) are 2 minutes or longer. Many of them are lectures, exhibition tours and live-stream clips. Fewer likes does not mean fewer viewers, and saves and comments may be a better measure for them. The 32 image posts have a median of 269.5 likes, near the 282 for videos.
Hashtags and posting times also give numbers. The 139 posts without hashtags have a median of 314 likes. The 69 posts with "history" have 412. The 104 posts with "relics" have 375. The 154 posts with the most common hashtag, "National Museum", have only 222.
So more hashtags do not mean more likes. Posts with content hashtags (history, relics) have higher medians than posts with the museum's name as a hashtag.
By Beijing time, the museum posts most on Fridays (140 posts) and least on Saturdays (62). By hour, 16:00 and 17:00 have 89 posts each, and 10:00 has 76. Only 20 posts are after 21:00. So the museum posts mostly on workdays and in work hours.
The 655 posts have 99,934 comments in total. The median per post is 21 comments, 37 shares and 23 saves.
Why should public culture institutions look at these numbers? A China Archives News commentary was first printed on October 26, and the Fuzhou archives site reposted it on November 4. It says that Weibo, WeChat Channels and Douyin are now the main places where people get information. It asks archives to make different content for each platform's logic and audience. A museum that asks "does anyone watch our short videos, and what content do they watch" needs this base table: a full post table for its own account and a matching table for similar institutions.
State the method limits. Likes and comments depend on platform recommendations and do not equal the audience's view of the exhibition. Mark co-created posts apart. Plays are not available, so you cannot compute completion or engagement rates.
Charges: you pay for what comes back
In this test, we made 47 calls. The total charge was $0.026132, which is the sum of billing.charged_usd in each response. Profile, post list, video detail and transcript cost $0.000556 per call. Comments and replies are charged in blocks of 20 items. Our 3 comment calls and 1 reply call each returned one block or less, so each cost one block.
The catalog says that a block with no items costs nothing. A page token is valid for 24 hours, and it works only for the same account and the same parameters. If the parameters change, the API returns 422, and you start again from page 1. For scheduled jobs that retry by themselves, send an Idempotency-Key, so a replay of the same request is not charged again.
| Case | Result | Charged | Source |
|---|---|---|---|
| Profile, list page, video detail, transcript | One call | $0.000556 | Our 47 calls |
| Comments or replies, 1 to 20 items | One block | $0.000556 | Our 47 calls |
| Comment block with no items | No data in that block | $0 | Catalog rule |
| Old page token with changed parameters | 422; start again from page 1 | — | Catalog rule |
When the other two routes fit better
The official Open Platform fits institutions that manage their own accounts. Plays, profile visitors and new followers per day are available only after the owner's consent. The capability page states the allowed uses, and an institution that uses the data for its own display and review is inside them. Open-source scripts fit technical teams with small data volumes. These teams maintain their own code and want full control of each request. They fit best when you need the video file itself.
They also fit lists that only a signed-in user can see, such as likes and favorites. For these, the feature list of DouK-Downloader is longer than a data API. A pay-per-call API fits when you read many public accounts, do not want to deploy and maintain scripts, and need stable JSON fields. You can use all three. Use the official route for your own account and a pay-per-call API to compare with peers. Use an open-source tool when you need the original file.
| Your goal | Route that fits | Why |
|---|---|---|
| Plays and profile visitors for your own account | Official Open Platform | Only the owner's consent unlocks these numbers |
| The original video file, or signed-in lists | Open-source tool | A data API returns fields and addresses that expire |
| Compare many public accounts every day | Pay-per-call API | No consent needed; nothing to deploy or maintain |
| Find the author from one video | Pay-per-call douyin/video | All three reads had the author's Douyin ID, bio and likes; $0.000556 per call |
Compliance and limits
Reading public profiles also has rules. Article 18 of the Regulations on Network Data Security Management covers automated tools that access and collect network data. It says that you must assess the effect on the network service. You must not illegally enter another network or disturb the normal running of a network service. Article 24 says that if automated collection cannot avoid personal data that is not necessary, you must delete it or make it anonymous.
The Anti-Unfair Competition Law is in force since October 15, 2025. Article 13 says that a business must not use fraud or threats to get or use data that another business holds lawfully. It must also not go around or break technical controls to do this. Article 13 of the Personal Information Protection Law lists one allowed case. You can process personal data that a person made public, or that was lawfully made public, within a reasonable scope.
Our own practice is as follows. We read only public profiles and public posts. We do not store personal nicknames or avatars from comments, or we make them anonymous. We keep the call rate inside the API rate limit, and we do not go around platform login or checks.
We name institutional accounts in analysis and leave out the names of individual creators. Douyin's robots.txt blocks the listed search engine crawlers from /follow and from pages with the enter_from= parameter. This section describes a data method; it is not legal advice.
Sample limits: we tested one institutional account, and the detail and comments of one video. The three test times were within 60 minutes. "Empty in this sample" applies only to this sample. Personal accounts, shop accounts and accounts with mostly image posts can be different. The year, length, hashtag and posting-time analysis uses only the museum's 655 posts.
Industry updates
- November 2026: under its notice, the Douyin Open Platform moves to certificates without a cross-signed root. Old systems that did not upgrade by October 31 get errors when they call
open.douyin.com, and the notice says that an upgrade fixes this. What it means for you: if old Java programs call the official API, check the certificate this month. - November 9, 2026: douyin-downloader #263 reports no post details after a new login, while the desktop app works. What it means for you: in this issue, a new login did not fix it, so cookie-based scripts need other checks.
- November 4, 2026: the National Museum's crown exhibition opened to the public. At 13:07 on November 14, the museum's exhibition video from November 10 had 8,691 likes. That is 27.7 times the median (314) of the other 19 posts from the 3 months before. What it means for you: peaks on institutional accounts follow physical exhibitions, so put exhibition dates in your tracking calendar.
- October 31, 2026: the Douyin_TikTok_Download_API maintainer says in #805 that direct video links expire in about three hours. What it means for you: store only the video
id, and read the address when you need it. - October 26, 2026: the title of douyin-downloader #258 says that the security check allows only requests from inside the web page. It says that retry or a new login does not help. What it means for you: if you build your own tool, plan the cost of browser automation.
FAQ
Does Douyin have an official API?
Yes. It is the Douyin Open Platform. Account and video endpoints need the account owner to authorize your app. user_info returns the nickname, avatar, gender and region. The user interaction data product is open only to companies, government bodies and public institutions. To read other public accounts, you need open-source scripts or a pay-per-call API.
What fields does a Douyin user profile API return?
The official /oauth/userinfo/ document lists nickname, avatar, gender and region, and the sample also has open_id and union_id. It needs user consent. The pay-per-call douyin/profile catalog lists 24 fields. For the National Museum, 16 had values. They include followers, following, total likes, post count, verification text, avatar and banner image.
What is the difference between Douyin uid and sec_uid?
uid is a numeric ID; for the museum it is 92744920981. sec_uid is the part after douyin.com/user/ in the web profile address, and it starts with MS4w. The pay-per-call API uses sec_uid to find an account. The short Douyin ID, chnmuseum for the museum, is a third ID. The account sets it, and you cannot send it as a secUid. The author_douyin_id field in the video detail returns the author's Douyin ID, so you can use it to check.
Is there a free Douyin data API?
The Open Platform capabilities are free, but you need a qualified organization, a review and the owner's consent. Open-source projects on GitHub are free, but you pay for servers, proxies and upkeep. With the pay-per-call API, paging the museum's post list to the end returned 672 items and cost $0.018904.
Do the Douyin API projects on GitHub still work?
Some do, but read recent issues first. The douyin-downloader README says that security checks now block single-video downloads in the command-line version. On November 9, 2026, a user reported no post details even after a new login. Douyin_TikTok_Download_API reads authors and posts with a guest identity pool, but follower lists and search need a login.
Can a Douyin API return the play count?
The official video data query can return play_count, but it needs the owner's consent, and it reads only the authorized account's own videos. The pay-per-call catalog says that view_count is not a real play count, because Douyin does not publish video play counts. To judge reach, use likes, comments, shares and saves.
Get started
- Open the EveryInfra quick start, sign up and get an API key. Put it in the environment variable
EVERYINFRA_API_KEY. - Open the target account on Douyin web. Copy the secUid after
douyin.com/user/in the address. - Put it in
SECin the Python code above. Run the profile call and page 1 first, and check the counts. See the pricing page and the capability catalog for current prices. - To page to the end, loop until there is no
next_page_token. Then filter out co-created posts byauthor_id. For daily updates, read page 1 again at a fixed interval. Merge the whole page into your table by postid. - Call
douyin/videoanddouyin/commentsonly for the posts where you need the author data or a deeper look. - For keyword search and the full flow from search to replies, see the Douyin API Python test. To compare unit prices for two ways to buy Douyin data, read the Douyin API price comparison. For other platforms, see the TikTok Scraper API and the Xiaohongshu Scraper API.
References
- Douyin Open Platform: user interaction data capability page (in Chinese), read 2026-11-14
- Douyin Open Platform: video data capability page (in Chinese), read 2026-11-14
- Douyin Open Platform: public user info capability page (in Chinese), read 2026-11-14
- Douyin Open Platform: get public user info API document (in Chinese), read 2026-11-14
- Douyin Open Platform: authorized account video list (in Chinese), read 2026-11-14
- Douyin Open Platform: video data query (in Chinese), read 2026-11-14
- Douyin Open Platform: get access_token (in Chinese), read 2026-11-14
- Douyin Open Platform: video data query with business consent (in Chinese), read 2026-11-14
- Douyin Open Platform: user types and permissions (in Chinese), read 2026-11-14
- Douyin Open Platform: server certificate notice, updated 2026-03-23 (in Chinese), read 2026-11-14
- DigiCert: compatibility of DigiCert trusted root certificates, read 2026-11-14
- TikTok for Developers: Display API getting started, read 2026-11-14
- TikTok for Developers: video list endpoint, read 2026-11-14
- TikTok for Developers: Research API, read 2026-11-14
- GitHub: Douyin_TikTok_Download_API README, read 2026-11-14
- GitHub: Douyin_TikTok_Download_API issue #805, reply of 2026-10-31, read 2026-11-14
- GitHub: douyin-downloader README, read 2026-11-14
- GitHub: douyin-downloader Chinese README, read 2026-11-14
- GitHub: douyin-downloader issue list, read 2026-11-14
- GitHub: douyin-downloader issue #258, 2026-10-26, read 2026-11-14
- GitHub: douyin-downloader issue #263, 2026-11-09, read 2026-11-14
- GitHub: douyin-downloader issue #253, 2026-10-09, read 2026-11-14
- GitHub: DouK-Downloader (TikTokDownloader) README, read 2026-11-14
- GitHub: MediaCrawler README, read 2026-11-14
- GitHub: f2 README, read 2026-11-14
- GitHub: f2 issue #350, read 2026-11-14
- GitHub: douyin-cli README, read 2026-11-14
- PyPI: requests, read 2026-11-14
- EveryInfra capability catalog, read at 13:05 Singapore time, read 2026-11-14
- Douyin: National Museum of China web profile, read 2026-11-14
- Douyin robots.txt, read 2026-11-14
- CCTV: report on the museum's crown exhibition, 2026-11-10 (in Chinese), read 2026-11-14
- National Museum of China: crown exhibition preview, 2026-10-30 (in Chinese), read 2026-11-14
- National Museum of China: crown exhibition page (in Chinese), read 2026-11-14
- Xinhua: photo report from the exhibition hall, 2026-11-10 (in Chinese), read 2026-11-14
- Fuzhou archives site: China Archives News commentary, 2026-11-04 (in Chinese), read 2026-11-14
- Regulations on Network Data Security Management, full text (in Chinese), read 2026-11-14
- Anti-Unfair Competition Law of the PRC, full text (in Chinese), read 2026-11-14
- Personal Information Protection Law of the PRC, full text (in Chinese), read 2026-11-14
- Douyin Open Platform: documentation center (in Chinese), read 2026-11-14
Reference BL-154