Douyin API in Python: official, open-source and pay-per-call routes, tested
Three ways to get Douyin data in Python: the official open platform, open-source scrapers, or a pay-per-call API. One live chain cost $0.0106.

On November 10, 2026, between 00:14 and 00:34 Singapore time, we ran a full Douyin data chain four times. We used Python and the requests library. Each chain had five requests: keyword search, video detail, comments, comment replies and a transcript of the video. All 20 requests returned HTTP 200. Each chain cost $0.010557, and the search step took 79% of that amount. Per 1,000 rows, search results cost about $0.76, comments about $0.032 and replies about $0.029.
We also checked the two other routes against their own primary documents. The Douyin Open Platform gives data mostly through user consent, limits some data products to companies and public bodies, and has no Python server SDK. The most popular open-source scrapers on GitHub state in their own README files that they need a logged-in session or request signatures. Their issue trackers show new blocks and new verification puzzles in the last 30 days.
This article is for one type of reader: a researcher or analyst who knows Python and wants Douyin data about a topic. Our running example is public-health work, because many English-speaking teams study vaccine talk on short-video apps. You may want the top videos about flu vaccines and the comments under them. You may also want the replies and the words that people say in the videos. We explain what each route needs, what it returns and what it costs.
We describe three kinds of method: the official platform, open-source scripts and a pay-per-call data API.

Why researchers ask about a douyin api alternative
Many English guides treat Douyin as "Chinese TikTok" and send readers to TikTok tools. That does not work. TikTok and Douyin are separate apps with separate content, separate accounts and separate developer platforms. The TikTok Research API returns public TikTok data about accounts, content and shops. It does not return Douyin videos or Douyin comments.
The TikTok Research API also has strict entry rules. Its product page lists eligibility for academic and not-for-profit researchers in the United States, the EEA, the UK and Switzerland. The page says that approval typically takes about 4 weeks. The Research API FAQ states that creators, advertisers and commercial users are not eligible. It sets a daily limit of 1,000 requests and up to 100,000 records, with up to 100 records per video or comment request.
The same FAQ gives two facts that matter for any short-video study. New videos can take up to 48 hours to enter the search index. Statistics such as view counts can take up to 10 days to update, because the search API uses archived data. Keep these delays in mind when you compare TikTok results with Douyin results. On Douyin, you have to pick a route of your own, and the next sections compare the three options.
| Question | TikTok Research API | Douyin Open Platform | Open-source scripts | Pay-per-call API (EveryInfra, tested here) |
|---|---|---|---|---|
| Covers Douyin | No | Yes | Yes | Yes |
| Who can apply | Academic and not-for-profit researchers in listed regions | Registered developers; some data only for companies and public bodies | Anyone | Anyone with an API key |
| Keyword search | Yes, with archive delay | Last 1 day only, or a beta program | One major project does not offer it | douyin/search, from 1 day to no time limit |
| Approval time | About 4 weeks | 2 to 7 working days per capability | None | None |
| Python | Plain HTTPS | No Python server SDK | Most projects are Python | Plain HTTPS |
| Main risk | Eligibility | Capabilities can be withdrawn | Logins, signatures and blocks change often | Pay per call; failed calls are free |
Route 1: the Douyin Open Platform
Many tutorials describe the Douyin Open Platform as a general API for any Douyin data. The official documents do not support that view. Almost every data capability depends on user consent. Your app asks a Douyin user to log in and approve access. Then your app can read that user's own videos, followers and interaction data. It cannot read data about other accounts.
The login and consent document (in Chinese) sets the token rules in the table below. The same page says that users must give consent for data-operation capabilities on a desktop computer.
| Token | Used for | Valid for |
|---|---|---|
| access_token | APIs that need user consent | 15 days |
| client_token | APIs without user consent | 2 hours |
| refresh_token | Renewing an access_token, up to 5 times | 30 days; 195 days at most in total |
Who can apply for data capabilities
We opened each data capability page. The "user interaction data" capability is open only to companies, government bodies and public institutions. Its usage section says that apps can use it only to show Douyin user information. It must not be used to build data-service products for sale or for platform-wide statistics. The page warns that the platform can ban the capability after misuse.

The "video data" capability also needs user consent. With consent, an app can read the title, cover, pin status and creation time of that user's videos. It can also read the official like, play, share and comment counts. Mobile and web apps must apply for two capabilities at the same time. The platform review takes 2 to 3 working days. The "authorized account video list" endpoint needs a user access token and, per the page, does not support a time filter yet.
For comments, the video comment management guide lists four endpoints: comment list, reply list, reply to a comment and pin a comment. The scope is video.comment. The guide describes a back-office tool that shows real-time comments for a connected Douyin account. That means your account or an account that gave you consent. It does not give you the comments under any public video.
Keyword search: one day of results, or a beta program
Search is the key feature for topic research. The Open Platform has two search products, and we read both sets of documents. The first is "keyword video search", with the scope video.search. It needs a permission request and user consent. You must create the keywords first in a management console. The page states that the endpoint returns only videos from the last day.
The partner platform describes the same product in its video search management page. A developer registers keywords that relate to the developer, then searches public videos whose titles contain those keywords and replies to comments. Results include only public videos from the last day. The user types and permissions table marks this permission as special and off by default.
The second product is "Douyin video search" in the search capability group. The OpenAPI list describes it as search results for a user's query. The OpenAPI SDK overview gives its scope as aweme.dy.video_search_v2. Its product page says that access starts with a beta application form. It targets apps that show Douyin content to their own users, not bulk research.
Beta access has its own risk. Section 10.4.2 of the mini-app operation rules says that the platform team can take back beta API access. A research project that depends on a beta endpoint can lose its data source in the middle of a study. Plan for that before you design a long panel or a multi-month time series.
| Official capability | Scope | User consent | Entry rule or limit (from the page) | Review time |
|---|---|---|---|---|
| User interaction data | data.external.user | Yes | Companies, government and public bodies only; no data products for sale | 2 to 3 working days |
| Video data | video.data.bind and others | Yes | Two capabilities needed together | 2 to 3 working days |
| Video comment management | video.comment | Yes | Interaction management permission | Not stated |
| Keyword video search | video.search | Yes | Special permission; last day only | Not stated |
| Douyin video search | aweme.dy.video_search_v2 | No (client_token) | Beta application form | Not stated |
| Any capability request | Varies | Varies | State the expected use case | 5 to 7 working days |
The last row comes from the capability overview, which gives 5 to 7 working days for a capability request or a quota increase. The create an app page adds that a new app starts as a test app, and its actions have no effect in production. Only a live app can be used commercially. The publishing capability rules set an even higher bar. A company needs registered capital of at least 500,000 yuan and at least 1 year since registration.
The official route and Python
People who search for "douyin api python" often miss one fact. The Open Platform server SDK supports Java, NodeJS and Go only. There is no Python SDK.
You can still call the official endpoints from Python, because they are normal HTTPS endpoints. You must write the token exchange, refresh and renewal code yourself. The real barrier is not the language. Without a company account and without users who give you consent, most data endpoints will not work for you.
For a university team outside China, this route is usually closed. A foreign university is not a Chinese company or public institution. Also, the people who post about flu vaccines will not give your app consent to read their accounts. The official route fits a different job: a brand or clinic that manages its own Douyin account and wants its own comments and statistics.
Route 2: open-source douyin scraper projects on GitHub
Search for "douyin scraper" or "douyin scraper github" and you get the same group of open-source projects near the top. On November 10, 2026, at 00:22 Singapore time, we read the public GitHub API for six common projects. We recorded stars, last push date and license. Then we read each README and the issues from the last 30 days. This section reports only what those public pages say. We do not rate the projects.
| Project | Stars | Last push | License | Requirements stated in the README |
|---|---|---|---|---|
| MediaCrawler | 70,735 | 2026-11-09 | Custom; README forbids commercial use | Playwright login that saves the session; QR-code login |
| Douyin_TikTok_Download_API | 21,313 | 2026-11-09 | Apache-2.0 | Version 5 makes guest identities with a headless browser; signatures in pure Python |
| douyin-downloader | 12,576 | 2026-11-09 | MIT | Python 3.9 or later; save cookies after a browser login |
| TikTokDownload | 8,892 | 2024-06-28 | MIT | No push for more than a year |
| f2 | 2,729 | 2026-10-19 | Apache-2.0 | Cookie setup; some content needs a login |
| Crawler | 1,478 | 2026-10-19 | Non-commercial license | Add your own cookie to a test file; a proxy pool is advised |
Logins and signatures are a cost that does not go away
The MediaCrawler README describes its method openly. It uses Playwright to log in and keep a session, then reads signature values from the browser context with JavaScript. By default it connects to the user's own Chrome through CDP mode to reuse cookies and lower the risk of detection. Its disclaimer says that the code is for learning and reference only and must not be used commercially. A research lab should read that license before it builds a funded project on the code.
The Douyin_TikTok_Download_API README explains the main problem of its version 4. Endpoints failed without warning when cookies expired, signature rules changed or rate limits applied. Users found out only when someone opened an issue. Version 5 creates guest identities with a headless browser, refills an identity pool and computes several signature values in pure Python. Deployment needs PostgreSQL with TimescaleDB, Redis 8 and Python 3.12.
One line in that README matters most for topic research. Under the feature table, the author says that Douyin does not give search results or hashtag feeds to guests. The author has not tested whether a logged-in identity can get them. So the project does not offer Douyin keyword search at all.
Recent activity also shows the maintenance load. Pull request #821, merged on November 5, 2026, made one step of the signature code 9.5% faster. Issue #825, opened on November 9, 2026, reports a long backlog of content requests.
The douyin-downloader README states its limits directly. Douyin request checks currently block command-line downloads of single videos, collections, music, likes and favorites. A Playwright browser fallback can try author pages, with no promise of success. The README says that new cookies or retries do not fix these blocks. Three recent issues relate to this article. Issue #257, from October 25, 2026, says that comment downloads sometimes produce empty files, often after more than 50 downloads in a row.
Issue #258, from October 26, 2026, shows Douyin refusing the first page of an author's video list. The error says that the security check accepts only requests made inside the web page, and retries or a new login do not help. Issue #263, from November 9, 2026, says that a fresh login and new cookies still return no video detail. The tool worked a few weeks earlier.
Verification puzzles change too. MediaCrawler issue #996, from October 28, 2026, records a new check on the Douyin web search page. A pop-up covers the results. It asks the user to pick the matching images from a nine-image grid and drag them to a target area. The reporter wrote that they did not try to solve it automatically. Pull request #998, from November 2, 2026, fixes how the tool reads video IDs from Douyin photo-post links.
We do not explain how to get past these checks, and we do not recommend it. We list them for one reason. The main cost of a self-built scraper is not the first version of the code. It is the weekly work to follow platform changes, and the risk that a study loses data in the middle of a collection window.
Two facts people miss: robots rules and licenses
We read the robots.txt file of the Douyin website on November 10, 2026, at 00:35 Singapore time. It names 26 search-engine and AI crawler user agents. For that group, it disallows paths such as /follow and search pages with the general_search parameter. A second group disallows paths such as /video/ and /search/. The file has no wildcard group for all user agents. A robots file is a statement to crawlers, not a legal text, but it shows the platform's position on its search pages.
For licenses, two of the six projects in the table say that commercial use is not allowed. Grant-funded work is not always commercial, but a lab that sells reports or works for a client should check. Ask your research office or legal team. This article does not give legal advice.
Route 3: a pay-per-call douyin api python chain
The third route moves logins, signatures, verification and page changes to the API provider. You send HTTP requests and pay per call. We tested the EveryInfra data API with five capabilities. They are douyin/search for keyword search, douyin/video for video detail, douyin/comments for comments, douyin/comment_replies for replies, and douyin/transcript for the spoken text. The overview is on the Douyin API page.
Every capability name, parameter, price and response field comes from the free catalog endpoint, which we read at 00:13 Singapore time. In the catalog, douyin/search costs $0.008333 per page. The other four cost $0.000556 per call. Comments and replies use tiers of 20 rows, and a tier with no rows is not charged.
Below is the script that we ran. It needs only requests. It reads the key from an environment variable. It picks the search result with the most comments, then the comment with the most replies. It saves each request and the full response as a JSON file, so you can check every number later. On HTTP 429 it waits 60 seconds and tries again, because our test key allows 10 requests per minute.
"""Douyin chain: search -> video -> comments -> comment_replies -> transcript."""
import json, os, sys, time
from pathlib import Path
import requests
API = "https://api.everyinfra.com/api/v1/social"
KEY = os.environ["EVERYINFRA_API_KEY"] # never hard-code the key
SESSION = requests.Session()
SESSION.headers.update({"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"})
def call(action, params, tag, name):
body = {"platform": "douyin", "action": action, "params": params}
for attempt in range(3):
t0 = time.time()
r = SESSION.post(API, json=body, timeout=120)
dt = round(time.time() - t0, 2)
if r.status_code == 429: # rate limited: wait, then retry
time.sleep(60)
continue
break
data = r.json()
Path(tag).mkdir(exist_ok=True)
Path(tag, f"{name}.json").write_text(json.dumps(
{"elapsed_s": dt, "http_status": r.status_code, "request": body, "response": data},
ensure_ascii=False, indent=1))
print(name, r.status_code, dt, (data.get("billing") or {}).get("charged_usd"))
return data
def rows_of(data):
rows = data.get("results") or []
return rows if isinstance(rows, list) else [rows]
def main(keyword, tag):
s = call("search", {"keyword": keyword, "sort": "most_liked",
"publish_time": "half_year", "page_token": ""}, tag, "1_search")
url = max(rows_of(s), key=lambda v: v.get("comment_count") or 0)["url"]
call("video", {"url": url}, tag, "2_video")
c = call("comments", {"url": url, "page_token": ""}, tag, "3_comments")
top = max([x for x in rows_of(c) if not x.get("is_reply")], key=lambda x: x.get("reply_count") or 0)
call("comment_replies", {"url": url, "comment_id": str(top["id"]), "page_token": ""}, tag, "4_replies")
call("transcript", {"url": url}, tag, "5_transcript")
if __name__ == "__main__":
main(sys.argv[1], sys.argv[2])Set the key with export EVERYINFRA_API_KEY=..., then run the script with a keyword and a folder name. Three parts of the code need a short note. First, requests.Session reuses connections. The requests documentation says that several requests to the same host can reuse the TCP connection, which can make them much faster. All five requests in a chain go to the same address.
Second, keep timeout=120. The synchronous request budget on the server side is 85 seconds, so the client timeout must be longer. Third, send page_token as an empty string. The catalog says that an empty string starts at page one and the response then includes next_page_token. If you leave the parameter out, you get one call with no next page.
We used requests 2.34.2, which needs Python 3.10 or later. Python 3.15.2, released on October 25, 2026, is an expedited security release with fixes in ssl and tarfile, so update long-running data machines.
If your team prefers an AI assistant to code, you can connect the same capabilities through remote MCP. MCP is a standard way for AI tools to call outside services. The configuration below is an example. Field names change a little between clients, and the key again comes from an environment variable. After you connect, the assistant uses the everyinfra_call_api tool with the same platform, action and params. The Douyin MCP page lists the Douyin tools.
{
"mcpServers": {
"everyinfra": {
"type": "http",
"url": "https://api.everyinfra.com/mcp",
"headers": { "Authorization": "Bearer ${EVERYINFRA_API_KEY}" }
}
}
}Live test: three keywords, four chains
We chose three keywords from different fields, so one script had to deal with different kinds of content. "Flu vaccine" is our public-health example. On November 5, 2026, the China CDC week 44 influenza report (in Chinese) said that positivity was rising in northern provinces. Influenza A was 65.4% of positive samples. The second keyword was "Gannan navel oranges", a farm product whose 2026 harvest started on November 6. The third was "Chilean cherries", an import that arrives in China each winter.
The global context also explains the timing. In its week 43 respiratory virus update, WHO reported that influenza A(H3N2) was predominant in Eastern Asia among zones with elevated positivity. WHO/Europe wrote on October 23, 2026, that the influenza season in its region usually starts between mid-November and mid-December. Vaccine talk on social apps tends to rise in this period, so it is a good moment to test a collection script.
| Test | Time (Singapore time) | Keyword (English gloss) | Search rows | Comments | Replies | Transcript length | Serial time | Charge |
|---|---|---|---|---|---|---|---|---|
| 1 | 00:14 | Gannan navel oranges | 10 | 18 | 20 | 1,502 characters | 48.18 s | $0.010557 |
| 2 | 00:24 | Flu vaccine | 11 | 20 | 20 | 13 characters | 35.85 s | $0.010557 |
| 3 | 00:28 | Chilean cherries | 10 | 19 | 18 | 526 characters | 38.84 s | $0.010557 |
| 4 (parallel) | 00:34 | Gannan navel oranges | 11 | 20 | 20 | not counted | 33.49 s wall clock | $0.010557 |
All 20 requests returned HTTP 200 in the end. The charge was the same for every chain: $0.008333 for search plus four calls of $0.000556.
One note on the times in the table. Serial time is the sum of the five step times, without rate-limit waits. In each serial test, at least one step first got HTTP 429. Our test key allows 10 requests per minute. The script waited 60 seconds and the retry succeeded.
So from the search request to the transcript response, the wall-clock times were about 108, 97 and 99 seconds. The 429 responses were not charged. The three serial chains took 35.85, 38.84 and 48.18 seconds, with a median of 38.84 seconds. Before the test, we set a target median of 30 seconds or less. We did not meet it. The transcript step caused most of the delay, with 22.35, 21.8 and 22.35 seconds, or 46.4%, 60.8% and 57.5% of the serial time.
The transcript step first gets the audio and then converts speech to text, so its time does not follow video length. The test 2 video was only 5 seconds long, and the transcript still took 21.8 seconds. The video detail step for test 1 took 18.36 seconds. In the other three chains it took 5.17 to 10.06 seconds, so single calls can vary a lot.
The screenshot below shows real responses from test 1. The top card is the search request with its first two results. The bottom card is the comments request with the billing details. We hid user names in the image and removed account balance fields.

What the flu vaccine chain shows a health researcher
Test 2 is the most useful one for public-health readers, and it also shows a trap. The search for "flu vaccine", sorted by most liked in the last half year, returned 11 videos. Likes ran from 52,965 down to 16,070. Post dates ran from June 1 to October 17, 2026. Most top videos were explainers, many of them by doctors. The most-liked video was a 22-second clip that says rural residents aged 65 and over can get free flu shots.
| Rank by likes | Likes | Comments | Length | Posted (UTC) | Caption topic (English gloss) |
|---|---|---|---|---|---|
| 1 | 52,965 | 7,786 | 22 s | 2026-08-24 | Free flu shots for rural residents aged 65 and over |
| 2 | 43,036 | 1,324 | 48 s | 2026-09-13 | A pediatrician on optional paid vaccines |
| 3 | 42,278 | 3,005 | 219 s | 2026-10-16 | A doctor gets a flu shot and answers questions |
| 4 | 40,354 | 5,251 | 383 s | 2026-09-03 | The updated flu vaccine guidance explained |
| 9 | 21,406 | 12,442 | 5 s | 2026-09-30 | A morning queue for free flu shots |
Our script picks the result with the most comments. In test 2, that rule chose a 5-second clip with 12,442 comments. Its caption says that many people were already in line for free flu shots early in the morning.
Its transcript returned a single line of 13 characters that reads like a song lyric from the background music, not speech about vaccines. For a health study, this is a selection error, not an API error. A better rule for your own work is to filter on duration_sec, for example 60 seconds or more, before you rank by comments. Eight of the 11 search results met that rule.
The comments under the short clip also need careful reading. The first page returned 20 top-level comments from 14 different IP locations, including one outside mainland China. The median comment came 402.9 hours after the video was posted, which is about 17 days. The top three comments had 45.9% of all likes on the page.
Several of the most-liked comments are jokes. The comment with the most replies lists scary-sounding chemicals that are in fact names for water. Its 26 replies argue about whether the writer is joking.
This matters for automatic labeling. A keyword filter for words such as "do not get the shot" would mark many of these comments as anti-vaccine. A human reader would see jokes that mock the claim. If you use a language model or a classifier, check a sample by hand first. Report the share of ironic comments as a separate number. We do not judge any medical claim in these comments. For vaccine guidance, use your health authority or WHO/Europe's season advice.
The reply data adds one more detail. In the three tests, 15 of 20, 11 of 20 and 16 of 18 replies carried reply_to_reply_id. That means they answered another reply in the thread, not the top comment. If you study only top-level comments, you miss the part of the discussion with the most back-and-forth. In test 2, the replies came a median 554.1 hours after the video, so the thread kept going for weeks.
Pagination with next_page_token
Douyin comment threads and search results are long, and pagination is where Python scripts most often go wrong. On November 10, 2026, from 00:16 to 00:17 Singapore time, we used the tokens from test 1 to fetch more pages. We fetched search page 2, comment pages 2 and 3, and reply page 2.
tok = first_page["next_page_token"] # from the response of page 1
while tok:
d = call("comments", {"url": url, "page_token": tok}, "pages", f"comments_{n}")
tok = d.get("next_page_token") # missing key = last page
n += 1The results matched the catalog, with one surprise. Search page 2 returned 13 rows, more than the default 10, with no overlap with page 1. The catalog says that search takes whole Douyin pages without cutting them, and it drops videos already given on the page before. The three comment pages returned 18, 9 and 20 rows, 47 in total, with no duplicates. The video had 1,291 comments, a number that includes replies.
The catalog allows up to 50 top-level comments per page. Each page returned only 9 to 20, so each page was billed one tier. The response showed requested_units 3, billed_units 1 and refunded_credits 80. In plain terms, the call pre-charged three tiers and returned two of them because fewer rows came back. The two reply pages had 20 rows each, 40 in total, with no duplicates. The parent comment had a reply_count of 66, so two pages covered 61% of the thread.
This has two direct effects on your script. First, do not plan with 50 rows per page. Our three pages averaged 15.7 rows, so use about 16. Second, you do not pay for 50 rows when only 9 come back, because billing follows the real row count. The page token is valid for 24 hours and breaks if any parameter changes. If a script stops halfway, start again from page one.
Fields: what each step returns
The table lists the main fields that each step returned in our tests. We checked each field against the catalog response_fields. We show only the fields that analysts use most, so see the catalog for the full list.
| Capability | Fields per row (measured) | Common fields | Notes |
|---|---|---|---|
douyin/search | 29 to 30 | id, url, text, like_count, comment_count, share_count, collect_count, posted_at, author_follower_count, hashtags | No view_count; next_page_token at top level and on each row |
douyin/video | 30 or 46 | Search fields plus duration_sec, music, video_tags, city, location | Test 1 returned 46 fields, tests 2 and 3 returned 30, depending on the video |
douyin/comments | 16 | id, text, like_count, reply_count, ip_location, liked_by_author, posted_at | 18 of 18, 20 of 20 and 19 of 19 rows had an IP location |
douyin/comment_replies | 14 to 16 | id, text, like_count, reply_to_id, reply_to_reply_id, posted_at | reply_to_reply_id only on replies to replies; 0 of 58 replies had ip_location |
douyin/transcript | 21 | text, segments (start, end, text), duration_sec, audio_url | 170, 2 and 57 segments in tests 1 to 3 |
No search row in any test had view_count. The catalog explains that Douyin does not publish play counts. Most results have no such field, and a value of 0 does not mean zero views. Use likes, comments and shares to judge reach. In test 1, the video detail showed view_count 0 next to 17,789 likes and 10,584 shares. If your study design needs view counts, Douyin public data cannot give them to you, whatever route you choose.
The posted_at field is ISO 8601 with a time zone, for example 2026-09-30T23:51:39+00:00 for the test 2 video. pandas and most databases can read it directly. The video_url and audio_url fields carry signatures and expire, so download media soon if you need to keep it. Commenter names and avatars are personal data. We hid them in this article, and we suggest that research teams do the same.
Join the five steps into one table with pandas
Data collection is only the first step. We used pandas to join the five JSON files of each chain into one table with one row per comment. We added the video likes and post time to each comment, then computed hours since the video, the IP location spread and like concentration. The code to read the files is short.
import json, pandas as pd
v = json.load(open("run2/2_video.json"))["response"]["results"]
c = pd.DataFrame(json.load(open("run2/3_comments.json"))["response"]["results"])
c["posted_at"] = pd.to_datetime(c["posted_at"])
c["hours_after_video"] = (c["posted_at"] - pd.to_datetime(v["posted_at"])).dt.total_seconds() / 3600
summary = {"ip_top": c["ip_location"].value_counts().head(4).to_dict(),
"lag_median_h": c["hours_after_video"].median(),
"top3_like_share": c["like_count"].nlargest(3).sum() / c["like_count"].sum()}The first comment pages of the three videos were very different, as the table shows. In the navel orange explainer, 8 of 18 comments came from the growing province itself. The flu clip drew comments from far more places and kept getting them for weeks. The cherry sales video drew almost no likes.
| First comment page | Comments | IP locations | Median hours after post | Top-3 share of likes | Median likes |
|---|---|---|---|---|---|
| Test 1, navel oranges | 18 | 7 | 21.4 | 84.6% | 6.5 |
| Test 2, flu vaccine | 20 | 14 | 402.9 | 45.9% | 104.5 |
| Test 3, Chilean cherries | 19 | 8 | 38.3 | 55.6% | 0 |
These numbers teach two lessons. First, the first comment page is not in time order. It is the set of top comments after Douyin's own ranking. It shows where the discussion is focused, but you cannot use it for time trends or regional shares. For shares, page through all comments.
Second, IP location appears only on top-level comments. All 57 top-level comments in our tests had ip_location, and none of the 58 replies had it, although the catalog lists the field for replies.
For regional analysis, use top-level comments only and assign each reply to the region of its parent comment, or leave replies out. Like concentration also varies widely, from 45.9% to 84.6%. A sentiment study that weights by likes can reach a very different result from one that does not. Report both numbers.
Cost per 1,000 rows: search is expensive, comments are cheap
Many people who search for a "douyin api alternative" want one number: the cost of 1,000 rows. We did not divide the catalog price by the page limit. We used the real row counts and the real charges from our calls.
The sample is the three serial chains, tests 1 to 3. It also includes four extra pages that we fetched with the test 1 tokens. These are search page 2, comment pages 2 and 3, and reply page 2. That is 19 requests. Test 4 repeated the test 1 keyword in parallel, so we left it out to avoid counting one topic twice. That is why the table shows 4 search calls, 5 comment calls and 4 reply calls.
| Capability | Billing rule (catalog) | Calls | Rows returned | Charged | Cost per 1,000 rows |
|---|---|---|---|---|---|
douyin/search | $0.008333 per page | 4 | 44 | $0.033332 | about $0.76 |
douyin/comments | $0.000556 per tier of 20 rows | 5 | 86 | $0.002780 | about $0.032 |
douyin/comment_replies | $0.000556 per tier of 20 rows | 4 | 78 | $0.002224 | about $0.029 |
douyin/video | $0.000556 per call | 3 | 3 videos | $0.001668 | $0.556 per 1,000 videos |
douyin/transcript | $0.000556 per call | 3 | 3 videos | $0.001668 | $0.556 per 1,000 videos |
Search costs about $0.76 per 1,000 rows. That is 23 times the comment cost and 27 times the reply cost. The reason is simple.
A search page returns 10 to 13 rows for $0.008333, but a comment tier returns up to 20 rows for $0.000556. So a cheap design uses many keywords, one search page per keyword, and deep comment collection under the matching videos. A design with few keywords and many search pages costs much more. Our Douyin API price comparison compares 37 capabilities side by side, so we do not repeat it here.
A different sample does not change the result. If we add test 4 and count all 24 requests, search is 5 calls, 55 rows and $0.041665, or about $0.76 per 1,000 rows. Comments are 6 calls, 106 rows and $0.003336, or about $0.031. Replies are 5 calls, 98 rows and $0.00278, or about $0.028. Search still costs 24 times as much as comments and 27 times as much as replies.
How much time does parallel work save
The transcript is the slowest step, and video detail, transcript and comments do not depend on each other. So the next idea is to run those three at the same time after search. We changed the script with concurrent.futures from the Python standard library. We ran it once on November 10, 2026, at 00:34 Singapore time.
from concurrent.futures import ThreadPoolExecutor
def comments_then_replies():
c = call("comments", {"url": url, "page_token": ""}, tag, "3_comments")
top = max(rows_of(c), key=lambda x: x.get("reply_count") or 0)
call("comment_replies", {"url": url, "comment_id": str(top["id"]), "page_token": ""}, tag, "4_replies")
with ThreadPoolExecutor(max_workers=3) as pool:
jobs = [pool.submit(call, "video", {"url": url}, tag, "2_video"),
pool.submit(call, "transcript", {"url": url}, tag, "5_transcript"),
pool.submit(comments_then_replies)]
for j in jobs:
j.result()The parallel chain took 33.49 seconds of wall-clock time. The five step times added up to 47.52 seconds. Compared with the serial median of 38.84 seconds, it was only about 14% faster. In this run the transcript took 27.44 seconds, so the chain time was almost exactly search at 6.05 seconds plus the transcript. Parallel work hides the comment, reply and detail time inside the transcript wait. It cannot make one chain shorter than the transcript.
To raise throughput, run several videos in parallel and respect the per-minute limit of your key. Our test key allows 10 requests per minute, and one chain is 5 requests, so it can run at most 2 chains per minute. For very slow transcripts, add "mode": "async" to the request body. You get a job ID and poll for the result, so the connection does not stay open.
A flu-season monitoring budget
Unit prices alone are hard to read, so we priced three realistic plans. Prices come from the catalog. Rows per page are the averages from the same sample as the cost table: 11.0 for search, 17.2 for comments and 19.5 for replies. The flu plan is the one a health team would run during a season. The other two plans show how the bill changes with frequency.
| Plan | Each run | Requests per run | Cost per run | Rows per run | Frequency | Total |
|---|---|---|---|---|---|---|
| Flu vaccine weekly report | 5 keywords, 2 search pages each; 5 videos per keyword with detail, transcript and 3 comment pages; replies for 2 top comments per video | 185 | $0.1806 | 2,425 | Weekly, 4 weeks | $0.72 |
| Navel orange daily report | 10 keywords, 1 search page each; 3 videos per keyword, same steps | 220 | $0.2001 | 2,888 | Daily, 30 days | $6.00 |
| Chilean cherry weekly report | 6 keywords, 2 search pages each; 4 videos per keyword, same steps | 180 | $0.1934 | 2,354 | Weekly, 4 weeks | $0.77 |
The flu plan collects about 2,425 rows each week for $0.1806. Search is 46.1% of that cost. Over a 16-week season, from mid-November to early March, the same plan would cost about $2.89 in API fees. That figure is our own projection from the measured prices, not a test result. The daily orange plan works out to about $0.069 per 1,000 rows. That is ten times lower than search alone, because most rows come from cheap comments and replies.
Search is 41.6% to 51.7% of the cost in the three plans. If the budget is tight, cut search pages first, not comment depth. These numbers include API fees only. They do not include your own servers, storage or staff time.
Errors and charges: when you pay nothing
When a script fails, the hard question is whether the failure cost money and whether to retry. On November 10, 2026, at 00:30 Singapore time, we made three bad calls on purpose. The table combines them with what we saw in the live tests.
| Case | HTTP status | Response | Charge |
|---|---|---|---|
| No key | 401 | missing_key; next_steps says that nothing was charged | 0 |
| sort set to hottest | 422 | invalid_value; lists most_liked, newest and relevance; did_you_mean is most_liked | 0 |
| Comments called with a user profile link | 200 | count 0; reason empty_result_refunded; refund succeeded | 0 |
| Comment page with 9 to 20 rows | 200 | requested_units 3, billed_units 1, 80 credits returned | 1 tier |
| Over the per-minute limit | 429 | Seen at least once in each serial test; the script waited 60 seconds and the retry succeeded | 0 |
The 422 row is useful for teams that let an AI assistant write and fix scripts. The error lists the allowed values and the closest match, so a model can read it and correct the call. The third row shows that a valid but wrong input returns an empty result with a refund, not an error. So your script must check count, not only the status code. For safe retries without double charges, read idempotency keys and retries and failure refund reconciliation.
When the other two routes are a better fit
A pay-per-call API is not the right answer for every project. The official route is better in three cases. The first case is write access: replying to comments, pinning comments or publishing videos. Only the Open Platform can do that, and a data API is read-only. The second case is private account data such as follower profiles, profile visits and daily new plays. That data belongs to the account owner, and only a consent flow should give it to you.
The third case is a company that wants to show Douyin content in its own product for a long time and can wait for review. The official search beta has a high bar, but it gives platform-approved stability. A Chinese hospital group that runs its own Douyin account is a good example. It can read its own comment threads and reply to patients through official endpoints.
Open-source scripts also have a place. Maybe you only need a few videos that you can already see, for a class project or a personal archive. Then a downloader is faster than any sign-up.
You can read and change the code, and the data stays on your computer. Some teams have an engineer who maintains scrapers and accepts the ongoing work on logins, signatures, proxies and checks. For them, a self-built tool gives full control. Count that time as a cost. The issues in this article all date from the last 30 days.
A pay-per-call API fits the large middle group. That group needs public videos and comments from other accounts on a schedule, needs no write access and has no scraper engineer. It wants free failures and output that goes straight into a table or a database.
The limits are real. It cannot read private account data. A transcript takes more than 20 seconds. Search is billed per page, so a plan with many search pages becomes expensive fast.
Do you want to query Douyin from an AI tool without code? Read ModelScope MCP for Xiaohongshu and Douyin, Feishu Base field shortcuts or WorkBuddy connectors. For Xiaohongshu, read Xiaohongshu API: official vs third party. The same Python code works for the TikTok API and the Xiaohongshu API if you change the platform and action. For TikTok prices, see TikTok API pricing.
Compliance and limits
This section covers data methods and limits only. It is not legal advice. All three routes face the same Chinese laws.
Articles 13 and 27 of the Personal Information Protection Law allow processing of personal information that a person has made public, within a reasonable scope. The exception is when the person clearly refuses. Where processing has a major effect on personal rights, consent is needed. Commenter names, avatars and IP locations are personal data. For research and monitoring, keep text and statistics, and do not store names or avatars.
The revised Anti-Unfair Competition Law, in force since October 15, 2025, added a clause to Article 13. Businesses must not obtain or use data held lawfully by another business through fraud, coercion, or by avoiding or breaking technical controls. The signatures, puzzles and request checks in the open-source section are such controls, which is why we only describe them. The Network Data Security Regulations, in force since January 1, 2025, set general rules for network data processing. Large or long-term projects should check them too.
Research teams outside China also follow their own ethics rules. A university ethics board may ask how you store public posts, how long you keep them and how you remove names. The field-level facts in this article help with that answer. Comments carry an IP location, replies do not, and media links expire. Plan your data management before the first call, not after the first export.
The data has limits that our tests confirm. Douyin does not publish play counts, so do not trust any play-count field. Video and audio links expire. Comment pages return only 9 to 20 rows, so a video with thousands of comments needs many pages. Search results follow Douyin's own ranking and deduplication. They are not a full census, so you cannot use them to estimate the total number of videos on a topic.
Recent changes to watch
The table lists dated changes from the last 30 days that affect a Douyin data project. Each row ends with what the change means for your work.
| Date | Change | What it means for you |
|---|---|---|
| November 9, 2026 | douyin-downloader issue #263: a new login still returns no video detail | A cookie-based script can fail for reasons on the platform side |
| November 5, 2026 | China CDC week 44 report: positivity rises in northern provinces | Vaccine talk follows the season, so plan more pages for December |
| November 5, 2026 | Douyin_TikTok_Download_API merged #821: signature code 9.5% faster | Much open-source maintenance time goes to signatures |
| October 28, 2026 | MediaCrawler issue #996: a nine-image drag puzzle on web search | Self-built tools need time for manual work |
Frequently asked questions
Is there an official douyin api python SDK?
No. The server SDK supports Java, NodeJS and Go only, so from Python you write the token code yourself, as the section "The official route and Python" explains. (Question from Google suggestions for "douyin api python" and "douyin python".)
Does the TikTok Research API include Douyin data?
No. The TikTok Research API returns public TikTok data about accounts, content and shops. Douyin is a separate app with its own developer platform. The Research API is also limited to approved academic and not-for-profit researchers in listed regions. (Question from Google suggestions for "douyin api" and "tiktok research api".)
Do douyin scraper github projects still work?
Single-video downloads still work in many projects. Keyword search and bulk comments need logins and signatures, and issues from the last 30 days report refused requests and new puzzles (see Route 2). (Question from Google suggestions for "douyin scraper github".)
Is there a free douyin api alternative?
Open-source code is free, but you supply the login and deal with signatures and checks. Some licenses also forbid commercial use. The official Open Platform does not charge per call, but it needs approval and user consent, and it forbids data products for sale. A pay-per-call API costs money. One full five-step chain cost $0.010557 in our test. (Question from Google suggestions for "douyin api alternative free" and "douyin api alternatives".)
How do I get replies to Douyin comments in Python?
Call the comments capability first. Each top-level comment has a reply_count. For comments with a count above zero, call douyin/comment_replies with the video URL and the comment ID. You get up to 20 replies per page and use next_page_token for more. In our tests, three calls returned 20, 20 and 18 replies, and 15, 11 and 16 of them answered other replies. (Question from Google suggestions for "douyin comment scraper".)
Can I turn the speech in a Douyin video into text?
Yes. douyin/transcript returns the full text and timed segments. In test 1, a 338-second video gave 1,502 characters in 170 segments. One call took about 22 seconds and cost $0.000556. Check the result on very short clips. In test 2, a 5-second clip returned one line that looks like a song lyric from the background music. (Question from Google suggestions for "douyin transcripts scraper".)
Get started
- Create an API key in the console. Store the key in the
EVERYINFRA_API_KEYenvironment variable, as the quickstart shows. - Read the free catalog at
GET /api/v1/social/catalog?platform=douyin. Check parameters, prices andavailable, or see the pricing page and the data market. - Install requests with pip. Copy the script from the pay-per-call section and run it with your keyword.
- Open the five JSON files in the output folder. Check
billing.charged_usdfor each step, and passnext_page_tokenback unchanged for more pages.
References
- Douyin Open Platform, user interaction data capability page (in Chinese), read November 10, 2026, https://developer.open-douyin.com/capacity-center-page/capacity-detail/7180284622729658424
- Douyin Open Platform, video data capability page (in Chinese), read November 10, 2026, https://developer.open-douyin.com/capacity-center-page/capacity-detail/7180522194714230845
- Douyin Open Platform, login and consent (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/sdk/mobile-app/permission/overall-permission
- Douyin Open Platform, authorized account video list (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/video-management/douyin/search-video/account-video-list
- Douyin Open Platform, video comment management guide (in Chinese), read November 10, 2026, https://open.douyin.com/platform/resource/docs/ability/interaction-management/video-comment-management-solution
- Douyin Open Platform, keyword video search (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/search-management/keywords-video-list/keywords-video
- Douyin partner platform, video search management (in Chinese), read November 10, 2026, https://partner.open-douyin.com/docs/resource/zh-CN/dop/ability/search-management/video
- Douyin Open Platform, user types and permissions (in Chinese), read November 10, 2026, https://open.douyin.com/platform/resource/docs/accession-guide/type-and-permission
- Douyin Open Platform, OpenAPI list (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/list
- Douyin Open Platform, OpenAPI SDK overview (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/sdk-overview
- Douyin Open Platform, Douyin search capability product page (in Chinese), read November 10, 2026, https://developer.open-douyin.com/product/search
- Douyin Open Platform, mini-app operation rules (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/mini-app/operation/management/specification/standard
- Douyin Open Platform, capability overview (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/ability/common-solution
- Douyin Open Platform, create mobile and web apps (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/app-mgmt/create-mobile-and-web-app
- Douyin Open Platform, publishing capability rules (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/operation-standard/platform-capabilities/useclue
- TikTok for Developers, Research Tools: access and eligibility, read November 10, 2026, https://developers.tiktok.com/products/research-api/
- TikTok for Developers, Research API FAQ, read November 10, 2026, https://developers.tiktok.com/docs/en/research-api-faq
- GitHub, NanmiCoder/MediaCrawler README, read November 10, 2026, https://github.com/NanmiCoder/MediaCrawler
- GitHub, Evil0ctal/Douyin_TikTok_Download_API README, read November 10, 2026, https://github.com/Evil0ctal/Douyin_TikTok_Download_API
- GitHub, jiji262/douyin-downloader README, read November 10, 2026, https://github.com/jiji262/douyin-downloader
- GitHub, Johnserf-Seed/TikTokDownload, read November 10, 2026, https://github.com/Johnserf-Seed/TikTokDownload
- GitHub, Johnserf-Seed/f2 README, read November 10, 2026, https://github.com/Johnserf-Seed/f2
- GitHub, ShilongLee/Crawler README, read November 10, 2026, https://github.com/ShilongLee/Crawler
- GitHub, Douyin_TikTok_Download_API pull request #821, November 5, 2026, https://github.com/Evil0ctal/Douyin_TikTok_Download_API/pull/821
- GitHub, Douyin_TikTok_Download_API issue #825, November 9, 2026, https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues/825
- GitHub, douyin-downloader issue #257, October 25, 2026, https://github.com/jiji262/douyin-downloader/issues/257
- GitHub, douyin-downloader issue #258, October 26, 2026, https://github.com/jiji262/douyin-downloader/issues/258
- GitHub, douyin-downloader issue #263, November 9, 2026, https://github.com/jiji262/douyin-downloader/issues/263
- GitHub, MediaCrawler issue #996, October 28, 2026, https://github.com/NanmiCoder/MediaCrawler/issues/996
- GitHub, MediaCrawler pull request #998, November 2, 2026, https://github.com/NanmiCoder/MediaCrawler/pull/998
- Douyin, robots.txt, read November 10, 2026, https://www.douyin.com/robots.txt
- EveryInfra, data API catalog, read November 10, 2026, 00:13 Singapore time, https://api.everyinfra.com/api/v1/social/catalog
- requests documentation, Advanced Usage: Session Objects, read November 10, 2026, https://requests.readthedocs.io/en/latest/user/advanced/#session-objects
- PyPI, requests 2.34.2, May 14, 2026, https://pypi.org/project/requests/
- Python Software Foundation, Python 3.15.2, October 25, 2026, https://www.python.org/downloads/release/python-3152/
- Python documentation, concurrent.futures, read November 10, 2026, https://docs.python.org/3/library/concurrent.futures.html
- pandas documentation, pandas.to_datetime, read November 10, 2026, https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html
- China CDC, influenza surveillance weekly report, week 44 of 2026 (in Chinese), November 5, 2026, https://www.chinacdc.cn/jksj/jksj04_14249/202611/t20261105_1842732.html
- WHO, Global Respiratory Virus Activity: Weekly Update No. 602, read November 10, 2026, https://www.who.int/publications/m/item/global-respiratory-virus-activity--weekly-update-n--602
- WHO/Europe, Get ready for this year's influenza season: vaccination is key, October 23, 2026, https://www.who.int/europe/news/item/23-10-2026-get-ready-for-this-year-s-influenza-season--vaccination-is-key
- Cyberspace Administration of China, Personal Information Protection Law (in Chinese), August 20, 2021, https://www.cac.gov.cn/2021-08/20/c_1631050028355286.htm
- China National Intellectual Property Administration, Anti-Unfair Competition Law, 2025 revision (in Chinese), May 20, 2026, https://www.cnipa.gov.cn/art/2026/5/20/art_104_206437.html
- Ministry of Ecology and Environment, reprint of State Council Order No. 790, Network Data Security Regulations (in Chinese), October 3, 2024, https://www.mee.gov.cn/zcwj/gwywj/202410/t20241003_1087417.shtml
Reference BL-127