# How do I get an AI daily report of what competitors posted on Xiaohongshu and Douyin?

> Every morning, list competitors' new Xiaohongshu notes and Douyin videos with likes and comments, and let an LLM write what changed. Account IDs, costs and code.

Canonical page: https://okdata.online/answers/ai-competitor-daily-report/

**Short answer: **Keep a list of competitor account IDs, pull the first page of each account's posts once a day (Xiaohongshu $0.02 and Douyin $0.002 a page), keep what is new or growing since yesterday, and hand that to an LLM to summarize. Watching 10 accounts on each platform costs $0.22 a day.

A tea drinks brand watches ten rivals on Xiaohongshu and ten on Douyin. Today someone opens twenty profiles every Monday and copies numbers into a sheet, and by then a campaign that launched on Wednesday is old news. A daily job can do the opening and copying, and an LLM can write the three paragraphs the team actually reads: who posted what, which post took off, and whether a rival started a new campaign.

## One-time setup: the account IDs

The list endpoints need each account's ID. Get it once from a profile link:

- [Xiaohongshu account profile](/apis/xiaohongshu/users/get/) takes a profile URL such as `xiaohongshu.com/user/profile/5f12...` and returns the ID, followers and note count.
- [Douyin account profile](/apis/douyin/users/get/) takes a profile URL or a `v.douyin.com` share link and returns the account's sec_uid (it starts with `MS4wLjABAAAA`), which is the ID Douyin uses.

Store the IDs in a file. That is $0.22 for twenty accounts, once.

## The daily pull

- [Xiaohongshu account notes](/apis/xiaohongshu/users/notes/list/): an account's notes, newest first, about 20 per page.
- [Douyin account videos](/apis/douyin/users/videos/list/): an account's videos, newest first, about 20 per page, with likes, comments and shares.

The first page covers several days of posting for almost any brand, so one call per account per day is enough.

| Monitoring | Calls a day | Cost a day | Cost for 30 days |
|---|---|---|---|
| 10 Xiaohongshu + 10 Douyin accounts | 20 | $0.22 | $6.60 |
| Plus a weekly follower check | +20 a week | — | +$0.88 |

## Code

```python
import json, os, pathlib, requests

API = "https://api.okdata.online"
H = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
RIVALS = {"xiaohongshu": ["5f1234567890abcdef123456"], "douyin": ["MS4wLjABAAAA..."]}
PATHS = {"xiaohongshu": "/v1/xiaohongshu/users/notes/list", "douyin": "/v1/douyin/users/videos/list"}
STATE = pathlib.Path("rivals.json")

before = json.loads(STATE.read_text()) if STATE.exists() else {}
now, report = {}, []
for platform, ids in RIVALS.items():
    for account in ids:
        body = requests.get(API + PATHS[platform], headers=H, timeout=60, params={
            "id": account, "fields": "id,url,title,text,published_at,metrics.likes,metrics.comments,author.name"}).json()
        if body["code"] != "ok":
            report.append(f"{platform} {account}: {body['code']}")
            continue
        for p in sorted(body["data"]["items"], key=lambda x: x["published_at"], reverse=True):
            likes = p["metrics"]["likes"] or 0
            now[p["id"]] = likes
            if p["id"] not in before:
                report.append(f"NEW {platform} {p['author']['name']}: {p['title'] or p['text'][:60]} ({likes} likes) {p['url']}")
            elif likes - before[p["id"]] > 1000:
                report.append(f"GROWING {platform} {p['author']['name']}: +{likes - before[p['id']]} likes {p['url']}")
STATE.write_text(json.dumps(now))
print("\n".join(report))  # hand these lines to your LLM with the brief
```

Then one LLM call: "These are yesterday's competitor posts. Summarize themes, flag any post growing fast, and note anything that looks like a new campaign or product." Post the result to a group chat or email.

## Gotchas

- Douyin profiles can pin older videos to the top, and they may come first in the list. Sort by `published_at` yourself, as the code does.
- Xiaohongshu hides view counts, so `metrics.views` is null and listed in `meta.unavailable`. Compare likes, saves and comments instead.
- Only public posts appear. Deleted posts simply vanish from the list.
- The 1,000-like growth threshold is a placeholder; set it per account size.

## Other ways

Coze or Feishu workflows that scrape with a pasted cookie work until the cookie expires; they suit a quick trial. Chinese analytics dashboards such as 千瓜 for Xiaohongshu or 蝉妈妈 for Douyin give charts, rankings and history without code, and are the better buy for a team that wants a dashboard more than a daily message. With three or four rivals, opening their profiles by hand each morning is honestly fine. More on this job: [competitor monitoring](/solutions/competitor-monitoring/).

## Endpoints used

- [Xiaohongshu account notes](https://okdata.online/apis/xiaohongshu/users/notes/list/) `xiaohongshu.users.notes.list`: $0.02 per call · about 20 notes per page
- [Douyin account videos](https://okdata.online/apis/douyin/users/videos/list/) `douyin.users.videos.list`: $0.002 per call · about 20 videos per page
- [Xiaohongshu account profile](https://okdata.online/apis/xiaohongshu/users/get/) `xiaohongshu.users.get`: $0.02 per call
- [Douyin account profile](https://okdata.online/apis/douyin/users/get/) `douyin.users.get`: $0.002 per call

Updated 2026-11-12
