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.

Illustration of three paths that lead to one data desk. At the top left, an arch with a permit and a card reader stands for the official platform that needs approval and user consent. In the middle, a winding path with loose gears and a small robot that pushes on a closed glass door stands for open-source scripts that need a login and request signatures. In front, a teal conveyor belt carries video cards, comment bubbles and sound waves to a laptop on the desk, which stands for a pay-per-call API.

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.

Illustration of five translucent trays in a vertical stack, joined by thin arrows. The top tray is teal and the largest, with a magnifying glass over a grid of blank video thumbnails, for search. The second tray holds a large video card with a play button, for video detail. The third holds a column of comment bubbles. The fourth shows one comment that splits into three small bubbles, for replies. The bottom tray shows a sound wave that turns into lined paper strips, for the transcript.
The chain in this article has five steps. Search is the most expensive step, so it is the largest tray.

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.

QuestionTikTok Research APIDouyin Open PlatformOpen-source scriptsPay-per-call API (EveryInfra, tested here)
Covers DouyinNoYesYesYes
Who can applyAcademic and not-for-profit researchers in listed regionsRegistered developers; some data only for companies and public bodiesAnyoneAnyone with an API key
Keyword searchYes, with archive delayLast 1 day only, or a beta programOne major project does not offer itdouyin/search, from 1 day to no time limit
Approval timeAbout 4 weeks2 to 7 working days per capabilityNoneNone
PythonPlain HTTPSNo Python server SDKMost projects are PythonPlain HTTPS
Main riskEligibilityCapabilities can be withdrawnLogins, signatures and blocks change oftenPay 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.

TokenUsed forValid for
access_tokenAPIs that need user consent15 days
client_tokenAPIs without user consent2 hours
refresh_tokenRenewing an access_token, up to 5 times30 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.

Screenshot of the Douyin Open Platform page for the user interaction data capability, in Chinese. A teal box marks the usage rule. In translation, the rule says that the capability is only for showing Douyin user information, must not be used to build data-service products for sale or for platform statistics, and can be banned after misuse.
The official data capability states its usage limits. Captured on November 10, 2026. Douyin Open Platform, user interaction data capability page

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 capabilityScopeUser consentEntry rule or limit (from the page)Review time
User interaction datadata.external.userYesCompanies, government and public bodies only; no data products for sale2 to 3 working days
Video datavideo.data.bind and othersYesTwo capabilities needed together2 to 3 working days
Video comment managementvideo.commentYesInteraction management permissionNot stated
Keyword video searchvideo.searchYesSpecial permission; last day onlyNot stated
Douyin video searchaweme.dy.video_search_v2No (client_token)Beta application formNot stated
Any capability requestVariesVariesState the expected use case5 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.

ProjectStarsLast pushLicenseRequirements stated in the README
MediaCrawler70,7352026-11-09Custom; README forbids commercial usePlaywright login that saves the session; QR-code login
Douyin_TikTok_Download_API21,3132026-11-09Apache-2.0Version 5 makes guest identities with a headless browser; signatures in pure Python
douyin-downloader12,5762026-11-09MITPython 3.9 or later; save cookies after a browser login
TikTokDownload8,8922024-06-28MITNo push for more than a year
f22,7292026-10-19Apache-2.0Cookie setup; some content needs a login
Crawler1,4782026-10-19Non-commercial licenseAdd 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.

Animated flow of five boxes from left to right: douyin/search ($0.008333, median 5.52 s), douyin/video ($0.000556, median 5.56 s), douyin/comments ($0.000556, median 1.59 s), douyin/comment_replies ($0.000556, median 1.27 s) and douyin/transcript ($0.000556, median 22.35 s). A teal dot moves from the search box through each step. The search box has a teal outline because it is 79% of the chain cost. The text under the boxes says that one chain is 5 requests and $0.010557 in total.

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.

python
"""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.

json
{
  "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.

TestTime (Singapore time)Keyword (English gloss)Search rowsCommentsRepliesTranscript lengthSerial timeCharge
100:14Gannan navel oranges1018201,502 characters48.18 s$0.010557
200:24Flu vaccine11202013 characters35.85 s$0.010557
300:28Chilean cherries101918526 characters38.84 s$0.010557
4 (parallel)00:34Gannan navel oranges112020not counted33.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.

Stacked horizontal bars for the time of each step in three serial chains. Test 1, navel oranges: search 4.8 s, video 18.36 s, comments 1.59 s, replies 1.08 s, transcript 22.35 s, total 48.18 s. Test 2, flu vaccine: search 5.52 s, video 5.56 s, comments 1.41 s, replies 1.56 s, transcript 21.8 s, total 35.85 s. Test 3, Chilean cherries: 7.73, 5.17, 2.32, 1.27 and 22.35 s, total 38.84 s. The transcript segment is teal and is the longest segment in each bar.

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.

Screenshot of two code cards. The top card is the douyin/search response at 00:14:16 for the keyword Gannan navel oranges, sorted by most liked, last half year, with an empty page_token. It shows count 10, the id, start of the text, likes of 17789 and 7967, comments of 1291 and 284, and post times for the first two results, a shortened next_page_token, and charged_usd 0.008333. The bottom card is the douyin/comments response at 00:14:36 with count 18, two comments with reply_count and ip_location, and billing with charged_usd 0.000556, rows_per_unit 20, requested_units 3, billed_units 1 and refunded_credits 80. User names show as hidden.
Real responses from test 1. We kept two results, hid user names and removed balance fields. EveryInfra API response, November 10, 2026, 00:14 Singapore time

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 likesLikesCommentsLengthPosted (UTC)Caption topic (English gloss)
152,9657,78622 s2026-08-24Free flu shots for rural residents aged 65 and over
243,0361,32448 s2026-09-13A pediatrician on optional paid vaccines
342,2783,005219 s2026-10-16A doctor gets a flu shot and answers questions
440,3545,251383 s2026-09-03The updated flu vaccine guidance explained
921,40612,4425 s2026-09-30A 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.

python
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 += 1

The 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.

Column chart of three comment pages. Each page could pre-charge up to 50 rows, or 3 tiers. The pages returned 18, 9 and 20 rows. Each page was billed one tier of $0.000556 and two tiers came back. Grey columns show the 50-row ceiling and teal columns show the rows returned.

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.

CapabilityFields per row (measured)Common fieldsNotes
douyin/search29 to 30id, url, text, like_count, comment_count, share_count, collect_count, posted_at, author_follower_count, hashtagsNo view_count; next_page_token at top level and on each row
douyin/video30 or 46Search fields plus duration_sec, music, video_tags, city, locationTest 1 returned 46 fields, tests 2 and 3 returned 30, depending on the video
douyin/comments16id, text, like_count, reply_count, ip_location, liked_by_author, posted_at18 of 18, 20 of 20 and 19 of 19 rows had an IP location
douyin/comment_replies14 to 16id, text, like_count, reply_to_id, reply_to_reply_id, posted_atreply_to_reply_id only on replies to replies; 0 of 58 replies had ip_location
douyin/transcript21text, segments (start, end, text), duration_sec, audio_url170, 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.

python
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 pageCommentsIP locationsMedian hours after postTop-3 share of likesMedian likes
Test 1, navel oranges18721.484.6%6.5
Test 2, flu vaccine2014402.945.9%104.5
Test 3, Chilean cherries19838.355.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.

CapabilityBilling rule (catalog)CallsRows returnedChargedCost per 1,000 rows
douyin/search$0.008333 per page444$0.033332about $0.76
douyin/comments$0.000556 per tier of 20 rows586$0.002780about $0.032
douyin/comment_replies$0.000556 per tier of 20 rows478$0.002224about $0.029
douyin/video$0.000556 per call33 videos$0.001668$0.556 per 1,000 videos
douyin/transcript$0.000556 per call33 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.

Horizontal bar chart of the cost per 1,000 rows from real counts and charges. douyin/search is about $0.76 and is the longest bar, in teal. douyin/video and douyin/transcript are $0.556 per 1,000 videos. douyin/comments is about $0.032 and douyin/comment_replies is about $0.029.

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.

python
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.

Bar chart comparing chain times. The three serial chains took 48.18, 35.85 and 38.84 s, with a median of 38.84 s. The parallel chain took 33.49 s of wall-clock time. In the parallel bar, the 27.44 s transcript step is teal and is 82% of the wall-clock time.

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.

PlanEach runRequests per runCost per runRows per runFrequencyTotal
Flu vaccine weekly report5 keywords, 2 search pages each; 5 videos per keyword with detail, transcript and 3 comment pages; replies for 2 top comments per video185$0.18062,425Weekly, 4 weeks$0.72
Navel orange daily report10 keywords, 1 search page each; 3 videos per keyword, same steps220$0.20012,888Daily, 30 days$6.00
Chilean cherry weekly report6 keywords, 2 search pages each; 4 videos per keyword, same steps180$0.19342,354Weekly, 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.

Stacked horizontal bars for the total cost of three plans, split into search and the other four steps. Navel orange daily for 30 days: $6.00 in total, of which search is $2.50 (41.6%). Flu vaccine weekly for 4 weeks: $0.72, search $0.33 (46.1%). Chilean cherry weekly for 4 weeks: $0.77, search $0.40 (51.7%). The search part is teal.

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.

CaseHTTP statusResponseCharge
No key401missing_key; next_steps says that nothing was charged0
sort set to hottest422invalid_value; lists most_liked, newest and relevance; did_you_mean is most_liked0
Comments called with a user profile link200count 0; reason empty_result_refunded; refund succeeded0
Comment page with 9 to 20 rows200requested_units 3, billed_units 1, 80 credits returned1 tier
Over the per-minute limit429Seen at least once in each serial test; the script waited 60 seconds and the retry succeeded0

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.

DateChangeWhat it means for you
November 9, 2026douyin-downloader issue #263: a new login still returns no video detailA cookie-based script can fail for reasons on the platform side
November 5, 2026China CDC week 44 report: positivity rises in northern provincesVaccine talk follows the season, so plan more pages for December
November 5, 2026Douyin_TikTok_Download_API merged #821: signature code 9.5% fasterMuch open-source maintenance time goes to signatures
October 28, 2026MediaCrawler issue #996: a nine-image drag puzzle on web searchSelf-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

  1. Create an API key in the console. Store the key in the EVERYINFRA_API_KEY environment variable, as the quickstart shows.
  2. Read the free catalog at GET /api/v1/social/catalog?platform=douyin. Check parameters, prices and available, or see the pricing page and the data market.
  3. Install requests with pip. Copy the script from the pay-per-call section and run it with your keyword.
  4. Open the five JSON files in the output folder. Check billing.charged_usd for each step, and pass next_page_token back unchanged for more pages.

References

  1. 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
  2. Douyin Open Platform, video data capability page (in Chinese), read November 10, 2026, https://developer.open-douyin.com/capacity-center-page/capacity-detail/7180522194714230845
  3. 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
  4. 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
  5. 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
  6. 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
  7. 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
  8. 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
  9. Douyin Open Platform, OpenAPI list (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/develop/openapi/list
  10. 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
  11. Douyin Open Platform, Douyin search capability product page (in Chinese), read November 10, 2026, https://developer.open-douyin.com/product/search
  12. 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
  13. Douyin Open Platform, capability overview (in Chinese), read November 10, 2026, https://developer.open-douyin.com/docs/resource/zh-CN/dop/ability/common-solution
  14. 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
  15. 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
  16. TikTok for Developers, Research Tools: access and eligibility, read November 10, 2026, https://developers.tiktok.com/products/research-api/
  17. TikTok for Developers, Research API FAQ, read November 10, 2026, https://developers.tiktok.com/docs/en/research-api-faq
  18. GitHub, NanmiCoder/MediaCrawler README, read November 10, 2026, https://github.com/NanmiCoder/MediaCrawler
  19. GitHub, Evil0ctal/Douyin_TikTok_Download_API README, read November 10, 2026, https://github.com/Evil0ctal/Douyin_TikTok_Download_API
  20. GitHub, jiji262/douyin-downloader README, read November 10, 2026, https://github.com/jiji262/douyin-downloader
  21. GitHub, Johnserf-Seed/TikTokDownload, read November 10, 2026, https://github.com/Johnserf-Seed/TikTokDownload
  22. GitHub, Johnserf-Seed/f2 README, read November 10, 2026, https://github.com/Johnserf-Seed/f2
  23. GitHub, ShilongLee/Crawler README, read November 10, 2026, https://github.com/ShilongLee/Crawler
  24. GitHub, Douyin_TikTok_Download_API pull request #821, November 5, 2026, https://github.com/Evil0ctal/Douyin_TikTok_Download_API/pull/821
  25. GitHub, Douyin_TikTok_Download_API issue #825, November 9, 2026, https://github.com/Evil0ctal/Douyin_TikTok_Download_API/issues/825
  26. GitHub, douyin-downloader issue #257, October 25, 2026, https://github.com/jiji262/douyin-downloader/issues/257
  27. GitHub, douyin-downloader issue #258, October 26, 2026, https://github.com/jiji262/douyin-downloader/issues/258
  28. GitHub, douyin-downloader issue #263, November 9, 2026, https://github.com/jiji262/douyin-downloader/issues/263
  29. GitHub, MediaCrawler issue #996, October 28, 2026, https://github.com/NanmiCoder/MediaCrawler/issues/996
  30. GitHub, MediaCrawler pull request #998, November 2, 2026, https://github.com/NanmiCoder/MediaCrawler/pull/998
  31. Douyin, robots.txt, read November 10, 2026, https://www.douyin.com/robots.txt
  32. EveryInfra, data API catalog, read November 10, 2026, 00:13 Singapore time, https://api.everyinfra.com/api/v1/social/catalog
  33. requests documentation, Advanced Usage: Session Objects, read November 10, 2026, https://requests.readthedocs.io/en/latest/user/advanced/#session-objects
  34. PyPI, requests 2.34.2, May 14, 2026, https://pypi.org/project/requests/
  35. Python Software Foundation, Python 3.15.2, October 25, 2026, https://www.python.org/downloads/release/python-3152/
  36. Python documentation, concurrent.futures, read November 10, 2026, https://docs.python.org/3/library/concurrent.futures.html
  37. pandas documentation, pandas.to_datetime, read November 10, 2026, https://pandas.pydata.org/docs/reference/api/pandas.to_datetime.html
  38. 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
  39. 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
  40. 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
  41. Cyberspace Administration of China, Personal Information Protection Law (in Chinese), August 20, 2021, https://www.cac.gov.cn/2021-08/20/c_1631050028355286.htm
  42. 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
  43. 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

Our own visit stats are always on. Google Analytics loads only if you choose “Allow analytics”. Privacy policy