# Why do I get fewer Douyin comments than the video's comment count shows?

> A Douyin video says 2,416 comments but your scraper returns 619. Where the rest go, how to check coverage, and what collecting the public ones costs.

Canonical page: https://okdata.online/answers/douyin-comments-incomplete/

**Short answer: **The counter on a Douyin video includes replies, and some comments are folded, hidden or deleted, so the number of public top-level comments is always lower. okdata returns every top-level comment Douyin serves, about 20 per page at $0.002, each with its reply count, so you can check coverage: 2,000 comments cost $0.20.

The video shows 2,416 comments. Your export has 619 rows. The first instinct is that the scraper is broken, and sometimes it is: a failed signature or a block can end paging early with no error. But even a perfect collector will not reach 2,416, and it helps to know why before you chase a bug.

## Where the comments go

- **Replies count too.** Douyin's counter includes replies under comments. A video with 600 top-level comments and 1,800 replies shows 2,400.
- **Folded and hidden comments.** Douyin folds low-quality or reported comments, and creators can hide or delete them. Those are not served publicly.
- **Very large threads.** On videos with tens of thousands of comments, Douyin may stop serving top-level comments before the end.

## Check your coverage

[Douyin video comments](/apis/douyin/videos/comments/list/) returns top-level comments with a `replies` count on each. Sum `1 + replies` over everything you collected and compare it with `metrics.comments` from [video detail](/apis/douyin/videos/get/). If the two are close, you have everything public. If your sum is far lower and the last page still said `has_more: true`, your collection stopped early.

## Cost

| Comments collected | Calls | Cost |
|---|---|---|
| 620 (the example above) | 31 | $0.062 |
| 2,000 | 100 | $0.20 |
| plus the video's counter | 1 | $0.002 |

## Code for the check

```python
import os, requests

API, HEAD = "https://api.okdata.online", {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
vid = "7301234567890123456"
total = requests.get(API + "/v1/douyin/videos/get", headers=HEAD, params={"id": vid}, timeout=60).json()["data"]["item"]["metrics"]["comments"]

seen, params = 0, {"id": vid}
while True:
    body = requests.get(API + "/v1/douyin/videos/comments/list", headers=HEAD, params=params, timeout=60).json()
    seen += sum(1 + (c["replies"] or 0) for c in body["data"]["items"])
    if not body["page"]["has_more"]:
        break
    params["cursor"] = body["page"]["next_cursor"]
print(f"covered {seen} of {total}")
```

Every page is a separate charge; if a page fails, it is not charged and you can resend it with the same cursor.

## If you need the replies themselves

This catalog lists top-level comments only. Reply text needs another tool: MediaCrawler and TikTokDownloader can collect replies with a logged-in account, and their issue trackers show that reply endpoints break more often than top-level ones. For most sentiment work, top-level comments weighted by likes and reply counts carry the signal. See [word-of-mouth analysis](/solutions/word-of-mouth/).

## Endpoints used

- [Douyin video comments](https://okdata.online/apis/douyin/videos/comments/list/) `douyin.videos.comments.list`: $0.002 per call · about 20 comments per page
- [Douyin video detail](https://okdata.online/apis/douyin/videos/get/) `douyin.videos.get`: $0.002 per call

Updated 2026-11-12
