# Xiaohongshu Data Collection: Search, Notes, Comments and Cost

> We ran Xiaohongshu search, note, comment and reply calls 12 times: $0.368 per 1,000 rows. Only 7 of 20 notes repeat after 8 minutes. Full cost model.

- Canonical page: https://everyinfra.com/en/blog/xiaohongshu-data-collection-search-notes-comments
- Published: 2026-11-14T14:56:00+08:00 · Fact-checked: 2026-11-14T13:40:00+08:00

At 13:06 Singapore time on November 14, 2026, we searched Xiaohongshu (also called RedNote) for the Chinese keyword for "flu vaccine". We sorted by relevance and got a first page of 20 notes. At 13:14 we ran the same search with the same parameters. Only 7 of the 20 notes were the same as before. At 13:26 we searched a third time, and only 4 notes appeared in all three pages.

We pulled 7 pages in total with two sort orders, which gave 140 rows. After we removed duplicates, 83 distinct notes were left. So one search is one sample, not a full picture. For trend and sentiment work, you must sample at several times and in several sort orders, and then remove duplicates.

We ran the full flow with the EveryInfra pay-per-call API: search, note detail, comments, replies and the post list of a public health account. It took 12 paid calls and cost $0.066672 for 181 rows. That is $0.368 per 1,000 rows. With the same mix of calls, 10,000 rows a month cost about $3.68, 100,000 rows about $36.84, and 1,000,000 rows about $368.

> **Key points**
>
> - On November 14, 2026, the official Xiaohongshu open platform still opens only `basic_info` (nickname, avatar, gender, region). The `read_notes` scope is still "planned". Pugongying, Juguang and the e-commerce open platform give access to your own partnership, ad and shop data only.
> - Six open-source Xiaohongshu repositories got 23 new issues in the last 30 days. Six of them report login failures, search limits or parser failures. One issue records a page data change around October 15, 2026 that crashed the parser.
> - `xiaohongshu/search` returns 20 rows per page at $0.278 per 1,000 rows. `xiaohongshu/comments` reached `end_of_list` after two pages and returned 16 top-level comments in this run, at $0.695 per 1,000 rows. `xiaohongshu/note` returns 1 row per call, at $5.556 per 1,000 rows. Cost per 1,000 rows = price per call / rows returned x 1,000.
> - Same keyword, relevance sort, 8 minutes apart: only 7 of 20 notes repeat. At the same moment, the relevance and newest sorts share only 2 to 7 notes.
> - Each extra page brings fewer new notes. In the order that we fetched the 7 pages, page 1 brought 20 new notes and page 7 brought 6. The cost per 1,000 new notes rose from $0.278 to $0.926. The 12 paid calls cost $0.066672 in total.

Xiaohongshu data collection means that you take public notes, comments and account posts from Xiaohongshu row by row and store them in a table. Then you use the table for statistics, sentiment tracking, product research or academic work. There are three ways to do it. The first is the set of official Xiaohongshu entry points. The second is a scraper script that you write yourself or take from an open-source project. The third is a data API that you pay for per call.

For the pay-per-call method, we divide `charged_usd` by the number of rows that each call returned.

![Generated illustration: a long conveyor belt runs from the back left to the front right and carries gray note cards. Three nets hang above the belt, and each net lifts a few cards. Most cards differ from net to net. Each net holds one or two teal cards that stand for notes that show up every time. At the back left, a three-level tray holds the cards in layers.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/img-explain-sampling-nets.webp)

One search lifts a small handful of notes at one moment. Lift again a few minutes later, or with another sort order, and most of the notes change. Only a few notes show up every time. [Generated illustration, not data, 2026-11-14](https://api.everyinfra.com/api/v1/social/catalog)

## Method one: what the official open platform, Pugongying and Juguang let you read

Xiaohongshu has several official entry points for developers and companies. Each one does one job. On November 14, 2026, we read the official pages again, one by one. The table below shows what each entry point needs and what it lets you read.

| Xiaohongshu entry point | What you need | What the official text says you can read | Can it read other people's public notes and comments? |
| --- | --- | --- | --- |
| Open platform account scopes (openaccount.xiaohongshu.com) | Create an app and wait for review, about 1 to 3 working days | Only `basic_info`: the signed-in user's nickname, avatar, gender and region | No. `read_notes`, `user_profile` and `read_followers` are all "planned" |
| Pugongying (pgy.xiaohongshu.com) | The brand verifies its company on the professional account platform; company verification costs CNY 600 per application and lasts 1 year | A platform where brands and creators agree on content and livestream deals | Not stated on the public page; no export of notes or comments by row |
| Juguang Marketing API (ad.xiaohongshu.com) | A Juguang ad account and ad experience; key accounts only; a sales rep starts the approval | Reports, campaigns and creatives of your own ad account | No. Your own ad data only |
| E-commerce open platform (open.xiaohongshu.com) | Only the main shop account can authorize | Products, orders and other data of the authorized shop | No. Your own shop only |

Start with the first row. The scope page of the open platform says that only one scope, `basic_info`, is open at this time. Of the five scopes, only `basic_info` has the status "open". The `read_notes` scope, which reads notes, is still "planned" ([Scope list](https://openaccount.xiaohongshu.com/docs/scope), last updated 2026-03-29, unchanged when we read it again on November 14).

The quick start guide says that after you create an app, you wait for a review of about 1 to 3 working days. After that, the user clicks, authorizes on Xiaohongshu and returns to your app. Your app then gets the user's profile ([Quick start](https://openaccount.xiaohongshu.com/docs/quick-start)). So the open platform lets users sign in to your app with a Xiaohongshu account. Today it gives no endpoint to search other people's notes or to read their comments.

![Screenshot of the Xiaohongshu open platform scope list table, with a teal frame around the full table. There are five rows. basic_info, the basic user profile with the fields nickname, avatar, gender and region, has the status open. user_profile, the detailed profile with the fields description, fans, follows and notes, has the status planned. read_notes, write_notes and read_followers all have the status planned.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/img-shot-xhs-scope.webp)

Read again on November 14, 2026: the official scope list still opens only basic_info. Reading notes and follower lists is still planned. [Xiaohongshu open platform, scope list](https://openaccount.xiaohongshu.com/docs/scope)

Pugongying is the platform where brands and creators agree on paid partnerships. Its sign-up page tells brands to go to the Xiaohongshu professional account platform first and verify the company. Then the brand uses that professional account to sign in to Pugongying. Agencies use the partner platform, and shops use the e-commerce sign-up ([Pugongying sign-up guide](https://pgy.xiaohongshu.com/role-introduce?needLogout=needLogout)). The official company account verification guide gives the fee: CNY 600 per application. The verification lasts 1 year, and you must pass a review every year.

The review fee is not refunded if verification fails ([Verification guide, PDF](https://fe-video-qc.xhscdn.com/d32a91d3f2fdc2130a7ba5015cc92ca446034613.pdf)). In Pugongying you can see creator rates and the results of partnership notes on the web pages. The public pages that we read do not describe a developer endpoint that exports notes and comments row by row. On November 13, 2026, the central parity rate was 6.7152 CNY per USD ([China News Service, citing the China Foreign Exchange Trade System](https://www.chinanews.com.cn/cj/2026/11-13/10731286.shtml)). At that rate, CNY 600 a year is about $89.35, or about $7.45 a month. That money buys the right to join and to run partnerships.

The Juguang Marketing API starter guide states the bar clearly. It is for key accounts that have a Juguang ad account and some ad experience. A Xiaohongshu sales rep starts the approval inside the company. The API covers reports and campaign management ([Juguang Marketing API starter guide](https://ad.xiaohongshu.com/openApiDoc?categoryId=761&articleId=3047), updated 2024-01-03). The e-commerce open platform says that only the main shop account can complete the authorization ([Authorization flow for software vendors](https://open.xiaohongshu.com/document/developer/file/38)). There is also a share open platform.

It lets apps share and publish content to Xiaohongshu, so it writes data and does not read it ([Share open platform](https://agora.xiaohongshu.com/index)). All four entry points handle your own assets: your signed-in users, your ad account and your shop. You may want to study what other people post about a public topic and what the comments say. For that, the public documents of these entry points list sign-in, partnership, ad and shop functions. They do not describe a read endpoint for it (read on 2026-11-14). Our earlier article, [Xiaohongshu API options: official platform, open-source scripts, pay per call](/blog/xiaohongshu-api-official-vs-third-party), compares these entry points in more detail.

The EveryInfra catalog also lists `xiaohongshu/pgy_content_square`. It reads the top-content charts of the Pugongying content square. It returns 20 rows per page, up to 5 pages per chart, at $0.016 per call ([Catalog](https://api.everyinfra.com/api/v1/social/catalog)). The catalog lists it as supported, but we did not test it in this run, so the costs below do not include it.

## Method two: write your own scraper, and what the open-source projects say

GitHub has many Xiaohongshu projects. We picked 6 repositories that have many stars or that people often cite. We used the public GitHub API to read each repository. We also read every issue opened from October 15 to November 14, 2026, without pull requests ([List repository issues](https://docs.github.com/en/rest/issues/issues#list-repository-issues)). We read the title and body of each issue. Below we quote the README files and issues of these projects.

| Repository | Stars | License | Last push | New issues in 30 days | Of those, no data |
| --- | --- | --- | --- | --- | --- |
| [NanmiCoder/MediaCrawler](https://github.com/NanmiCoder/MediaCrawler) | 71,098 | Custom; the README forbids commercial use | 2026-11-09 | 3 | 0 (2 are about other platforms, 1 is an ad post) |
| [xpzouying/xiaohongshu-mcp](https://github.com/xpzouying/xiaohongshu-mcp) | 17,115 | Apache-2.0 | 2026-11-10 | 13 | 4 |
| [JoeanAmier/XHS-Downloader](https://github.com/JoeanAmier/XHS-Downloader) | 13,292 | GPL-3.0 | 2026-11-13 | 7 | 2 |
| [cv-cat/Spider_XHS](https://github.com/cv-cat/Spider_XHS) | 8,467 | Not declared | 2026-10-22 | 0 | 0 |
| [jackwener/xiaohongshu-cli](https://github.com/jackwener/xiaohongshu-cli) | 2,731 | Not declared | 2026-03-21 | 0 | 0 |
| [ReaJason/xhs](https://github.com/ReaJason/xhs) | 2,236 | MIT | 2025-07-01 | 0 | 0 |

In those 30 days, the 6 repositories got 23 new issues. Six of them, or 26%, report a failed login, a search limit, or a failure to get or parse data. All six are in the two most active repositories. Three other repositories got no new issues in 30 days, and the last push to `ReaJason/xhs` was on July 1, 2025.

Few issues can mean two things. The tool may be stable, or fewer people may use it and the maintainer may have stopped. The issue count alone cannot tell you which. When you choose a repository, look at the issue count and the last push date together.

![Horizontal stacked bar chart of new issues opened from October 15 to November 14, 2026 in 6 open-source Xiaohongshu repositories. xiaohongshu-mcp has 13 issues: 4 about getting no data and 9 other. XHS-Downloader has 7: 2 about getting no data and 5 other. MediaCrawler has 3, all other. Spider_XHS, xiaohongshu-cli and xhs have 0.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/fig-04-github-issues.en.light.svg)

Here is what the no-data issues say, in our translation. Issue #877 in `xiaohongshu-mcp` (2026-10-21) has the title "Search is limited (but the app works normally)". The body says the account got a warning that it was suspected of using third-party tools and scripts ([#877](https://github.com/xpzouying/xiaohongshu-mcp/issues/877)). Issue #880 (2026-10-23) reports a verification code after the QR scan and no successful login ([#880](https://github.com/xpzouying/xiaohongshu-mcp/issues/880)). Issue #874 (2026-10-18) reports that the search tool times out after about 60 seconds, while the home feed still works ([#874](https://github.com/xpzouying/xiaohongshu-mcp/issues/874)). Issue #907 (2026-11-05) reports that the tool cannot get the login QR code ([#907](https://github.com/xpzouying/xiaohongshu-mcp/issues/907)).

Issue #497 in `XHS-Downloader` (2026-10-17) states the cause. It says that around October 15, 2026, Xiaohongshu added a new JavaScript construct to the server-rendered data of some note pages. That change crashed the note parser ([#497](https://github.com/JoeanAmier/XHS-Downloader/issues/497)).

Five days later, issue #499 reports that the tool fails to get notes ([#499](https://github.com/JoeanAmier/XHS-Downloader/issues/499)). Both #497 and #499 are about parsing the note detail page. Both issues are closed. Before the fix, that version of the tool could not parse those notes.

The README files also list what you must handle yourself. The MediaCrawler README says that it uses the Playwright browser automation framework to sign in and keep the session. Its disclaimer forbids commercial use ([MediaCrawler README](https://github.com/NanmiCoder/MediaCrawler), [LICENSE](https://github.com/NanmiCoder/MediaCrawler/blob/main/LICENSE)).

The `xiaohongshu-mcp` README says that Xiaohongshu requires a login. It warns that one account cannot stay signed in on several web clients at the same time. If it does, the platform signs out the session of the tool. New accounts also get a prompt for real-name verification ([xiaohongshu-mcp README](https://github.com/xpzouying/xiaohongshu-mcp)).

Issue #878 in the same repository (2026-10-22) asks whether Xiaohongshu allows this use, and whether notes get less reach after you use the tool. On November 14 the issue had no reply ([#878](https://github.com/xpzouying/xiaohongshu-mcp/issues/878)).

From these texts, a self-built scraper has four costs. You need a signed-in account, and the README says that the account cannot sign in at several places at once. Someone must fix the code when the page changes (#497, #499). The license may not allow commercial use (MediaCrawler). The account can get a warning (#877).

A 2026 study also had to copy posts from two platforms by hand. That study in BMC Public Health looked at discussions of dengue and chikungunya. The team collected Bilibili, Weibo and Zhihu data through APIs. For Douyin and Xiaohongshu, it says it had to copy posts by hand "because of platform anti-automation controls". Those two platforms gave only 97 posts in total, so the team reported them descriptively only ([BMC Public Health, 2026](https://doi.org/10.1186/s12889-026-29595-0)).

## Method three: a pay-per-call Xiaohongshu search API, tested end to end

A pay-per-call API turns each step into one HTTP request. You send a keyword and get one page of results. You send a note link and get the note detail or one page of comments. The EveryInfra catalog lists the required and optional parameters, the rows per page and the price of each capability ([Catalog](https://api.everyinfra.com/api/v1/social/catalog)). We read it at 13:05 on 2026-11-14. The six capabilities in this run all cost $0.005556 per call:

| Capability | Required parameters | Rows per page | Paging | Returned in this run |
| --- | --- | --- | --- | --- |
| [`xiaohongshu/search`](/xiaohongshu-api/search) | `keyword` | 20 | `page_token` | 7 pages, 20 rows each |
| [`xiaohongshu/note`](/xiaohongshu-api/note) | `url` | 1 | None | 1 row |
| [`xiaohongshu/comments`](/xiaohongshu-api/comments) | `url` | Up to 15 | `page_token` | Page 1: 15 rows; page 2: 1 row |
| [`xiaohongshu/sub_comments`](/xiaohongshu-api/sub_comments) | `url`, `comment_id` | Up to 10 | `page_token` | 1 page, 4 rows |
| [`xiaohongshu/user_posts`](/xiaohongshu-api/user_posts) | `user_id` | 20 | `page_token` | 1 page, 20 rows |
| [`xiaohongshu/hashtag`](/xiaohongshu-api/hashtag) | `topic_id` | 20 | `page_token` | Not tested in this run |

Two search parameters change the sample directly. `sort` accepts `relevance`, `newest`, `most_liked`, `most_commented` and `most_collected`. `date_range` accepts the last 24 hours, 7 days, 30 days, half a year or one year. The catalog adds a note about `date_range`.

With `last_30_days` and `last_1_year`, a page can have fewer than 20 rows. A page with no rows at all is not charged. For fuller pages, the catalog suggests `sort=newest`. The [Xiaohongshu data API](/xiaohongshu-api) page has the full reference.

### One round trip: the request and the real response

Here is the search request from 13:06:28. The key comes from the environment variable `EVERYINFRA_API_KEY`:

```bash
curl -s https://api.everyinfra.com/api/v1/social \
  -H "Authorization: Bearer $EVERYINFRA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"platform":"xiaohongshu","action":"search","params":{"keyword":"流感疫苗","sort":"relevance"}}'
# Next page: copy next_page_token from the response into params.page_token and keep the other parameters
```

We look at four things in the response. `count` is the number of rows on this page. `pagination.has_more` and `stop_reason` tell you if there is a next page. `next_page_token` is the cursor for the next page. `billing.charged_usd` is the amount that this call cost.

| Field | Meaning | Search page 1 at 13:06 | Comments page 2 at 13:14 | Replies at 13:09 |
| --- | --- | --- | --- | --- |
| `count` | Rows on this page | 20 | 1 | 4 |
| `pagination.has_more` | Is there a next page | true | false | false |
| `pagination.stop_reason` | Why paging stopped | none | `end_of_list` | `end_of_list` |
| `billing.charged_usd` | Cost of this call | 0.005556 | 0.005556 | 0.005556 |

The image below shows three real responses.

On the left is the first search page, where `has_more` is true. In the middle is page 2 of the comments. It returned 1 row in this run, and `stop_reason` is `end_of_list`, so the platform gives no next page. On the right are the replies to one top-level comment. That call returned 4 rows and also stopped at `end_of_list`.

![Screenshot of three real EveryInfra responses in monospace text on white. Left: xiaohongshu/search at 13:06:28, with teal frames around has_more true, count 20 and charged_usd 0.005556. Middle: page 2 of xiaohongshu/comments with page_token at 13:14:54, with frames around stop_reason end_of_list and count 1. Right: xiaohongshu/sub_comments at 13:09:00, with frames around stop_reason end_of_list and count 4.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/img-shot-ei-response.webp)

Three real responses: the search page has a next page; comments page 2 and the replies of one thread both stop at end_of_list. [Screenshot of EveryInfra API responses, 2026-11-14, Singapore time](https://api.everyinfra.com/api/v1/social/catalog)

Each search row has fields that match the `response_fields` list in the catalog. We counted how many of the 20 rows on the 13:06 page had a value in each field. This tells you which fields you can use directly for statistics:

| Field | Meaning (from the catalog) | Rows with a value, of 20 |
| --- | --- | --- |
| `id`, `url`, `posted_at`, `author_id` | Note ID, link with an access token, post time in UTC, author ID | 20 |
| `like_count`, `collect_count`, `comment_count`, `share_count` | Likes, saves, comments, shares; `null` means not available, not zero | 20 |
| `title` | Title | 19 |
| `text` | Short excerpt of the body, up to about 60 characters in search; call `note` for the full text | 20 |
| `is_cooperation_note`, `is_goods_note` | Brand partnership note or not; product note or not | 20 |
| `video_url`, `duration_sec` | Video link and length; empty for image notes | 3 |
| `poi_id` | ID of the place tag on the card; the field is absent when there is no tag | 1 |

In search and post lists, `text` is a cut excerpt of the body. `note` returns the full text. For sentiment or topic analysis, use only the title and excerpt, or call `note` again for the notes that you selected. A `note` call costs $0.005556 for one row, which is 20 times the cost of one search row. So call it only for notes that pass your filter.

### The full flow: search, note, comments, replies

The three test times were 13:06, 13:14 and 13:26 Singapore time (SGT), 20 minutes from first to last. We ran the flow below across those three times. At the first time we ran the whole flow. At the second and third times we repeated the searches and fetched the rest of the comments. We also read the post list of a public health agency account:

| Time (SGT) | Capability | Main parameters | Returned in this run | charged_usd |
| --- | --- | --- | --- | --- |
| 13:06:28 | `xiaohongshu/search` | Flu vaccine keyword, relevance | 20 rows | 0.005556 |
| 13:06:50 | `xiaohongshu/search` | Same, page 2 | 20 rows | 0.005556 |
| 13:07:01 | `xiaohongshu/search` | Flu vaccine keyword, newest | 20 rows | 0.005556 |
| 13:07:22 | `xiaohongshu/note` | A question note about a school-issued trivalent flu vaccine | 1 row | 0.005556 |
| 13:08:41 | `xiaohongshu/comments` | Same note, page 1 | 15 rows | 0.005556 |
| 13:09:00 | `xiaohongshu/sub_comments` | The top-level comment with the most likes | 4 rows | 0.005556 |
| 13:14:28 | `xiaohongshu/search` | Flu vaccine keyword, relevance | 20 rows | 0.005556 |
| 13:14:41 | `xiaohongshu/search` | Flu vaccine keyword, newest | 20 rows | 0.005556 |
| 13:14:54 | `xiaohongshu/comments` | Page 2 | 1 row, end of list | 0.005556 |
| 13:26:12 | `xiaohongshu/search` | Flu vaccine keyword, relevance | 20 rows | 0.005556 |
| 13:26:33 | `xiaohongshu/search` | Flu vaccine keyword, newest | 20 rows | 0.005556 |
| 13:26:47 | `xiaohongshu/user_posts` | A city disease control center account | 20 rows | 0.005556 |
| Total |  | 12 paid requests | 181 rows | 0.066672 |

As a script, the flow is about 60 lines. The version below runs as is. It needs only `requests`, and it reads the key from the environment.

Each logical request sends an `Idempotency-Key`, and a retry inside the same call reuses the same key. So when a network error sends a request twice inside one call, it runs and bills once. Our article [AI agent retries and the Idempotency-Key header](/blog/api-idempotency-key-ai-agent-retry) explains this pattern. On a 429 or 503 the script waits for the `retry_after` value in the response.

When you run the whole job again, the script makes new keys, and each request bills as a new request. Each run then gets the results of that moment, which is what sampling at several times needs.

```text
"""Xiaohongshu search -> note -> comments (to the end) -> replies.
Usage: EVERYINFRA_API_KEY=... python3 xhs_chain.py "flu vaccine"
Needs only requests. Writes JSON Lines, one row per line."""
import json, os, sys, time, uuid
import requests

API = "https://api.everyinfra.com/api/v1/social"
KEY = os.environ["EVERYINFRA_API_KEY"]

def call(action, params, tries=4):
    idem = str(uuid.uuid4())                      # one key per logical request; retries reuse it
    for _ in range(tries):
        r = requests.post(API, timeout=120, json={"platform": "xiaohongshu", "action": action, "params": params},
                          headers={"Authorization": f"Bearer {KEY}", "Idempotency-Key": idem})
        body = r.json()
        if r.status_code in (429, 503):           # rate limit or temporary error: not charged, wait and retry
            time.sleep((body.get("error") or {}).get("retry_after", 30) + 1)
            continue
        r.raise_for_status()
        return body
    raise RuntimeError(f"{action} failed after {tries} tries")

def pages(action, params, max_pages=10):
    token = None
    for _ in range(max_pages):
        body = call(action, {**params, **({"page_token": token} if token else {})})
        yield from body.get("results") or []
        token = body.get("next_page_token")
        if not token or not (body.get("pagination") or {}).get("has_more"):
            break
        time.sleep(8)                              # pause between pages; tune for your job size

def main(keyword, out="xhs.jsonl"):
    with open(out, "a", encoding="utf-8") as f:
        notes = list(pages("search", {"keyword": keyword, "sort": "newest"}, max_pages=1))
        for n in notes:
            f.write(json.dumps({"type": "search", **n}, ensure_ascii=False) + "\n")
        target = max(notes, key=lambda n: n.get("comment_count") or 0)       # go deeper only on the most-commented note
        detail = call("note", {"url": target["url"]})["results"]
        f.write(json.dumps({"type": "note", **detail}, ensure_ascii=False) + "\n")
        for c in pages("comments", {"url": target["url"]}):
            f.write(json.dumps({"type": "comment", **c}, ensure_ascii=False) + "\n")
            if (c.get("sub_comment_count") or 0) > len(c.get("sub_comments") or []):
                for s in pages("sub_comments", {"url": target["url"], "comment_id": c["id"]}):
                    f.write(json.dumps({"type": "sub_comment", **s}, ensure_ascii=False) + "\n")

if __name__ == "__main__":
    main(sys.argv[1])
```

Two checks in the script control the number of calls. First, it goes deeper only on the note with the most comments. A search page has 20 notes. If you fetch the detail and comments of every note, the number of calls grows 20 times.

Second, it fetches replies only when `sub_comment_count` is larger than the number of replies that the comment row already carries in `sub_comments`. In this run, 3 of the 16 top-level comments had replies, and their `sub_comment_count` values added up to 9. Each comment row already carried 0 or 1 reply. So only the comments with more replies need an extra `sub_comments` call.

### How to know that paging reached the end

Comments have two levels: top-level comments and threaded replies. For top-level comments, page through `comments`, up to 15 rows per page. Stop when the response has no `next_page_token` and `stop_reason` is `end_of_list`. For this note, page 1 had 15 rows (13:08:41) and page 2 had 1 row (13:14:54). The two pages gave 16 comments with no repeated IDs.

All 16 had an IP location, and they came from 10 provincial regions. For replies, use `sub_comments`. The comment that we picked had a `sub_comment_count` of 4. One `sub_comments` call returned 4 rows with `stop_reason` set to `end_of_list`. One reply answered the top-level comment directly.

The other 3 answered earlier replies, and their `reply_to_id` points to the reply above them. To rebuild the conversation, build a tree from `reply_to_id`. Do not sort by time only.

| Request | Time (SGT) | Rows returned | `has_more` / `stop_reason` | What it tells you |
| --- | --- | --- | --- | --- |
| `comments`, page 1 | 13:08:41 | 15 | true / none | A full page; there is a next page |
| `comments`, page 2 | 13:14:54 | 1 | false / `end_of_list` | The platform gives no next page; 16 in total over two pages |
| `sub_comments`, one thread | 13:09:00 | 4 | false / `end_of_list` | 1 answers the comment, 3 answer replies |

`end_of_list` means that the platform gives no next page. The catalog describes the `sort` parameter of `comments` as follows. The default sort is the platform's recommended order, and each request sorts again, so paging can miss or repeat some comments. The `newest` sort orders by time and pages in a stable way, but for some notes the platform gives only the newest part ([Catalog](https://api.everyinfra.com/api/v1/social/catalog)).

This run used the default sort, and the two pages were 6 minutes 13 seconds apart. For more stable paging, use `sort=newest`. With the default sort, page through one more round and merge by comment `id`. In your report, write down the fetch time and the sort order of each page.

Comment pricing follows a simple rule. Each call has a fixed price, so fuller pages give a lower cost per 1,000 rows. In this run, page 2 had only 1 row, so the 16 comments cost $0.695 per 1,000 rows. A note with several hundred comments has mostly full pages of 15 rows, and the cost comes close to $0.370 per 1,000 rows ($0.005556 / 15 x 1,000).

To fetch the first comment page of many notes, `xiaohongshu/comments_batch` takes several links in one call. Our [batch comments guide](/build/xiaohongshu-comments-batch) shows how to use it. We did not test it in this run.

![Horizontal bar chart of the USD cost per 1,000 returned rows, by capability. xiaohongshu/search: 7 calls, 140 rows, $0.278. xiaohongshu/comments: 2 calls, 16 rows, $0.695. xiaohongshu/sub_comments: 1 call, 4 rows, $1.389. xiaohongshu/note: 1 call, 1 row, $5.556. The whole flow in this run: 12 calls, 181 rows, $0.368, in teal.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/fig-01-per1k-by-capability.en.light.svg)

When you put the five capabilities side by side, every call costs $0.005556, so rows per page set the cost per 1,000 rows. Search and post lists return 20 rows per call, and note detail returns 1. So note detail costs 20 times more per 1,000 rows. To plan a budget, first decide which data needs only list fields (title, excerpt, engagement counts, post time) and which data needs the detail call (full text, hashtags, map coordinates).

Then estimate by that ratio. This run gave 181 rows for $0.066672, or $0.368 per 1,000 rows. That is a mix with mostly search, plus some detail and comments. If your flow is mostly note detail, the cost per 1,000 rows moves toward $5.556.

## Sampling design: how much the same keyword overlaps across sort orders and times

One search is a sample of one moment. We searched the flu vaccine keyword at three times, in two sort orders each time, and compared the note `id` values between pages. Every page had 20 rows, so the overlap is simply the number of notes that two pages share.

![7 by 7 heatmap. Rows and columns are the 7 search pages: 13:06 relevance, 13:06 relevance page 2, 13:07 newest, 13:14 relevance, 13:14 newest, 13:26 relevance, 13:26 newest. Each cell shows how many notes two pages share. 13:06 and 13:14 relevance share 7, 13:14 and 13:26 relevance share 6, 13:06 and 13:26 relevance share 5. 13:07 and 13:14 newest share 11, 13:14 and 13:26 newest share 12, 13:07 and 13:26 newest share 7. Relevance and newest at the same time share 4, 2 and 7. Relevance page 1 and page 2 at 13:06 share 0.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/fig-02-overlap-heatmap.en.light.svg)

| Comparison | 13:06 to 13:14 | 13:14 to 13:26 | 13:06 to 13:26 | Distinct notes over three runs | In all three runs |
| --- | --- | --- | --- | --- | --- |
| Relevance sort, page 1 | 7 / 20 | 6 / 20 | 5 / 20 | 46 | 4 |
| Newest sort, page 1 | 11 / 20 | 12 / 20 | 7 / 20 | 37 | 7 |
| Same time: relevance vs newest | 4 / 20 at 13:06 | 2 / 20 at 13:14 | 7 / 20 at 13:26 | n/a | n/a |

First, the relevance sort changed fastest within 20 minutes. Its three first pages held 46 distinct notes, and only 4 notes were in all three. The three newest first pages held 37 distinct notes, and 7 were in all three.

Second, the two sort orders at the same moment are almost two separate samples. They share only 2 to 7 notes. Together, the two pages at one moment held 36, 38 and 33 distinct notes. Third, page 1 and page 2 of one search did not overlap at all, so paging brings new notes. The 7 pages held 140 rows and 83 distinct notes, so 41% of the rows were repeats.

![Horizontal bar chart of the median age in hours of the 20 notes on each page, measured from the fetch time. 13:06 relevance 30.9. 13:06 relevance page 2 96.8. 13:07 newest 16.1. 13:14 relevance 58.0. 13:14 newest 6.2. 13:26 relevance 22.0. 13:26 newest 4.3. The three newest bars are teal.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/fig-05-note-age.en.light.svg)

The two sort orders also return notes of different ages. In the three newest pages, the median note was 16.1, 6.2 and 4.3 hours old. On each page, 19 or 20 of the 20 notes were less than 48 hours old. In the three relevance pages, the medians were 30.9, 58.0 and 22.0 hours. The oldest note on the 13:26 relevance page was 281 days old.

Engagement changes too. On relevance page 2, the median comment count was 4.5. On the newest pages it was 0 to 0.5, because new notes have not had time to collect engagement.

Repeats also cost money. The 7 search pages cost $0.038892 for 140 rows, or $0.278 per 1,000 rows. After deduplication there were only 83 distinct notes, so the cost per 1,000 distinct notes is about $0.469. When you sample at several times and in several sort orders, part of the money pays for repeated notes.

That money buys one piece of information: the note appeared at several moments. You can use it to give each note a stability score.

Maybe you need only a list of distinct notes. In this test, the relevance sort gave more for the money. Its three first pages held 60 rows and 46 distinct notes, about $0.362 per 1,000 distinct notes. The three newest pages held 60 rows and 37 distinct notes, about $0.450 per 1,000. The newest sort is useful because it catches notes soon after people post them, so use it for trend monitoring.

| Count basis | Rows | Cost | Per 1,000 rows or notes |
| --- | --- | --- | --- |
| 7 search pages, all rows | 140 | $0.038892 | $0.278 |
| 7 search pages, distinct notes | 83 | $0.038892 | $0.469 |
| Three relevance first pages, distinct notes | 46 | $0.016668 | $0.362 |
| Three newest first pages, distinct notes | 37 | $0.016668 | $0.450 |

Next, look at how many new notes each extra page brings. We put the 7 pages in the order that we fetched them. For each page, we count only notes that no earlier page had:

| Fetch order | Page | New notes on this page | Distinct notes so far | This page per 1,000 new notes |
| --- | --- | --- | --- | --- |
| 1 | 13:06 relevance page 1 | 20 | 20 | $0.278 |
| 2 | 13:06 relevance page 2 | 20 | 40 | $0.278 |
| 3 | 13:07 newest page 1 | 14 | 54 | $0.397 |
| 4 | 13:14 relevance page 1 | 10 | 64 | $0.556 |
| 5 | 13:14 newest page 1 | 7 | 71 | $0.794 |
| 6 | 13:26 relevance page 1 | 6 | 77 | $0.926 |
| 7 | 13:26 newest page 1 | 6 | 83 | $0.926 |

Every page costs $0.005556. The last column is $0.005556 / new notes on this page x 1,000. The first two pages come from one search, so all 20 notes on each page are new. Page 3 uses the other sort order and still brings 14 new notes. After that, each new search a few minutes later brings 10, 7, 6 and 6 new notes. The marginal cost rises to 3.3 times the cost of page 1.

Each sort order alone shows the same pattern. The three relevance first pages brought 20, 13 and 13 new notes, and the three newest first pages brought 20, 9 and 8. On a small budget, page deeper in one search first, and then add the other sort order. In this test, that gave more new notes than the same search again a few minutes later. A repeated search tells you which notes stay; it does not grow the list much.

The overlap measure is simple. Put the note `id` values of two pages into two sets. Divide the size of the intersection by the size of the union. The result is the Jaccard index. The 13:06 and 13:14 relevance pages share 7 notes, and their union has 33 notes, so the Jaccard index is about 0.21.

The newest pages at the same two times share 11 notes out of a union of 29, so the index is about 0.38. Record this number after each sampling run. Plot it as a line over a few days. Then you can see how fast the results for a keyword change, and decide how often to sample.

Here is a sampling plan that you can adapt to your budget:

| Research goal | Sort | Frequency and depth | Deduplication and records |
| --- | --- | --- | --- |
| Topic trend | `newest` | Page 1 every 1 to 2 hours; 1 or 2 more pages when many new notes arrive | Deduplicate by `id`; record the first time each note appears |
| Content study of a topic | `relevance` + `most_commented` | 2 or 3 pages at 3 times in one day | Merge and deduplicate; fetch detail and comments only for notes with many comments |
| Look back at an event | `newest` + `date_range` | Twice a day for 7 days after the event | Record the fetch time and sort parameters of every page |
| Opinion analysis of comments | Select notes with one of the plans above | Page each note's comments to `end_of_list`; fetch replies as needed | Build a tree from `reply_to_id`; normalize author IDs before deduplication |

The last row says to normalize author IDs. The catalog says that `author_id` in comment results is often a different 29-character form, not the 24-character ID in note results. Before you deduplicate across batches, convert them to one form with `profile` ([Catalog](https://api.everyinfra.com/api/v1/social/catalog)). If you skip this step, one person counts as two.

This design has limits. We tested one keyword, three times and 20 minutes, with a sample of 7 pages and 140 rows. All overlap rates and deduplication costs above hold only for this sample. Hot and quiet keywords change at different speeds, and so do day and night hours. Before you sample a new keyword, run the same three searches, compute your own overlap, and then set the frequency.

Researchers have discussed sampling bias in social media data for years. In 2013, Morstatter and colleagues compared the Twitter sampled stream with the full data. They found that the sample depended on the parameters and the time window ([ICWSM 2013](https://doi.org/10.1609/icwsm.v7i1.14401)). A Xiaohongshu search sample also depends on the sort order and the time.

## 10,000, 100,000 or 1,000,000 rows a month: what each method costs

We put the three methods into one table and priced them by rows per month. The pay-per-call side uses measured numbers. The flow in this run cost $0.368 per 1,000 rows. We also show a floor (search pages only, $0.278 per 1,000 rows) and a ceiling (note detail only, $5.556 per 1,000 rows).

The self-built scraper side is not measured. The hours, the hourly cost and the proxy traffic are our assumptions. The second table lists each assumption with its source and read date. We keep the original text of each external page in the raw data folder of this article.

You can put in your own numbers and compute again.

| Rows per month | Pay per call (this run's mix) | Search pages only | Note detail only | Self-built scraper (our assumptions) | Xiaohongshu entry points |
| --- | --- | --- | --- | --- | --- |
| 10,000 | $3.68 | $2.78 | $55.56 | $79.25 | Cannot read other people's notes and comments |
| 100,000 | $36.84 | $27.80 | $555.60 | $181.77 | Same |
| 1,000,000 | $368.35 | $278.00 | $5,556.00 | $672.57 | Same |

| Self-built scraper assumption (ours, not measured) | Value | Source and read date |
| --- | --- | --- |
| Engineer hourly cost | About $9.54 (CNY 64.08) | We assume the average 2025 annual wage in urban private units, information transmission, software and IT services: CNY 128,166 ([National Bureau of Statistics, published 2026-05-15](https://www.stats.gov.cn/sj/zxfb/202605/t20260515_1963707.html), read 2026-11-14), divided by 2,000 hours (250 working days x 8 hours, our assumption) |
| Maintenance hours per month | 8 hours for 10,000 rows, 16 for 100,000, 40 for 1,000,000 | Our assumption: expired logins, page changes and debugging; see the 6 no-data issues in 30 days above |
| Proxy traffic | 200 KB per row, about $1.49 per GB (CNY 10) | Traffic per row is our assumption; the unit price is the CNY 10 per GB tier inside a public residential proxy price range of CNY 8 to 20 per GB (one vendor's public price page, read 2026-11-14) |
| Exchange rate | 1 USD = 6.7152 CNY | Central parity rate on 2026-11-13 ([China News Service, citing the China Foreign Exchange Trade System](https://www.chinanews.com.cn/cj/2026/11-13/10731286.shtml), read 2026-11-14) |
| Not included | First build, servers, accounts | The first build is a one-time cost that varies a lot between teams; the user agreement does not allow bulk account sign-ups (see the compliance section) |

![Grouped horizontal bar chart on a log scale, in three groups. 10,000 rows a month: pay per call with this run's mix $3.68, search pages only $2.78, self-built scraper with our assumptions $79.25. 100,000 rows a month: $36.84, $27.80 and $182. 1,000,000 rows a month: $368, $278 and $673. The pay-per-call bars for this run's mix are teal.](https://everyinfra.com/articles/xiaohongshu-data-collection-search-notes-comments/fig-03-monthly-cost.en.light.svg)

At low volume, with our assumptions, almost all of the self-built cost is people. At 10,000 rows a month, pay per call costs $3.68. The maintenance hours of a self-built scraper alone cost about $76.34, which is 20.7 times more. With the proxy cost of $2.91, the total is $79.25, or 21.5 times more.

At high volume, the pay-per-call cost grows in a straight line with rows. The labor of a self-built scraper grows more slowly. At 1,000,000 rows a month, the gap is only about 1.8 times.

If your flow is mostly note detail ($5.556 per 1,000 rows), 1,000,000 rows cost $5,556. In that case a self-built scraper may cost less in cash. The price is maintenance, account risk and the agreement terms below. This table counts money only. It does not count the loss when an account gets limited or when your data has a gap of several days.

Two assumptions move the result the most, and you can change each one and compute again. The first is proxy traffic per row. We used 200 KB. At 1,000,000 rows a month the proxy cost is about $290.85, which is 43% of the self-built total. If your script uses only 50 KB per row, the proxy cost drops to about $72.71. The self-built total becomes about $454.43, which is still higher than the $368.35 of this run's mix.

The second is maintenance hours. We gave 40 hours a month to 1,000,000 rows. Suppose that the page structure changes twice a month and each change needs one more working day (8 hours) of fixes. Then the hours are 56, labor alone is about $534.41, and the self-built total is about $825.26.

| Scenario (1,000,000 rows a month, our assumptions) | Proxy | Labor | Self-built total | Times the pay-per-call cost of this run's mix ($368.35) |
| --- | --- | --- | --- | --- |
| 200 KB per row, 40 hours | $290.85 | $381.72 | $672.57 | 1.8 |
| 50 KB per row, 40 hours | $72.71 | $381.72 | $454.43 | 1.2 |
| 200 KB per row, 56 hours | $290.85 | $534.41 | $825.26 | 2.2 |

We convert from CNY at 1 USD = 6.7152 CNY. Proxy = rows x 0.2 MB / 1,024 x CNY 10 / 6.7152. Labor = hours x 128,166 / 2,000 / 6.7152.

The column for official entry points has no amount. Pugongying needs company account verification (the guide says CNY 600 per application, valid for 1 year, about $7.45 a month). The public pages of the open platform, Juguang and the e-commerce open platform do not state a fee. The public documents of all four entry points do not describe an endpoint to read other people's notes and comments. So you cannot compare them on price with the other two methods, only on use case.

## Another field: how to collect notes and comments on a public health topic

We chose the flu vaccine keyword because it has an official data source to compare with. On November 12, 2026, the Chinese Center for Disease Control and Prevention (China CDC) published data for week 45 (November 2 to 8). Influenza-like illness made up 4.1% of outpatient and emergency visits. The flu virus positive rate in influenza-like illness samples was 18.8%, up 3.1 percentage points from the week before. The 5 to 14 age group had a higher positive rate than other groups ([China CDC, week 45](https://www.chinacdc.cn/jksj/jksj04_14275/202611/t20261112_1842956.html)).

The flu surveillance report for the same week counts 125 reported outbreaks of influenza-like illness ([Weekly report no. 934](https://www.chinacdc.cn/jksj/jksj04_14249/202611/t20261111_1842933.html)). Government data tells you how many people got sick. Xiaohongshu notes and comments tell you what people ask and worry about. When you put the two side by side, you can compare public concern with the flu season.

You can collect data for this kind of study in four steps. Each step uses only the capabilities that we tested above.

| Step | Capability | What to record |
| --- | --- | --- |
| 1. Keyword groups | `xiaohongshu/search` with `newest` and `relevance` | Fetch time, sort order, page number, note `id` and `posted_at` |
| 2. Comments of selected notes | `xiaohongshu/comments`, `xiaohongshu/sub_comments` | `reply_to_id`, `ip_location`, post time; anonymous IDs in place of nicknames |
| 3. Agency accounts | `xiaohongshu/user_posts` | Post date, title and engagement of each agency note |
| 4. Claim checks | No API call; official notices and guidelines | Category of each comment and the official source it matches or contradicts |

Step one: set the keyword groups. For vaccines, split them by setting: school, children, insurance payment, trivalent versus quadrivalent. For each group, run the `newest` sort on page 1 every 2 hours for 7 days. Each day, also run `relevance` for 2 or 3 pages to add older notes with high engagement. In this run, the first relevance page held a note that was 281 days old. If you study "this season", filter out older seasons by `posted_at`.

Step two: pick notes and go down to the comments. The author of the note in this run asked if a school-issued trivalent flu vaccine was worth taking. Its 16 top-level comments came from 10 provincial regions. Some replies describe the writer's own vaccination, and some talk about price.

The value of this kind of discussion is in the comments. So for the notes with the most comments, page the comments to the end and build reply trees from `reply_to_id`. Keep the `ip_location` and post time of every comment, so that you can group by region and week.

Step three: collect agency accounts on their own. We read the post list of a city disease control center account. Its 20 notes ran from September 1 to November 13 and had 0 to 33 likes. One title announced free flu vaccination for older people and young children in rural Sanming.

`has_more` was true, so older posts exist. Compare what agency accounts post, and how often, with what users ask in their notes. This shows if health education covers the questions that people actually ask.

Step four: check claims, and do not draw medical conclusions. You can compare price and payment claims in comments with local government notices. An example is an October 8 notice from Ganquan Road Subdistrict in Putuo District, Shanghai.

It lists the trivalent split vaccine at CNY 86.4 or 96.4 and the trivalent subunit vaccine at CNY 306.4. A CNY 6 service fee is added. It says that people can pay from their personal medical insurance account balance or a family shared account ([Ganquan Road Subdistrict notice](https://www.shpt.gov.cn/gqjd-jiedaozhen/gsgg-sqzc-gqjd/20261008/973469.html)). For vaccination advice, use the national technical guideline for flu vaccination for 2026 to 2027.

It recommends vaccination in September and October. One priority group is people in nurseries, primary and secondary schools and detention facilities ([Technical guideline](https://www.chinacdc.cn/jkts/202609/t20260903_1839780.html)). Your report counts how many comments ask about price, how many describe side effects and how many repeat a policy. It does not judge anyone's health. Hide all commenter nicknames and keep only anonymous IDs.

Set the comment categories before you collect data, and do not add categories while you read. For vaccines you can start with five: price and payment, place and booking, reactions after the shot, repeating a policy or notice, and other. Two people label the same 100 comments on their own with the same written guide. Then you compute their agreement rate. If agreement is too low, revise the guide and label again.

Content analysis calls this step an intercoder reliability check. After labeling, sum the share of each category by week and by provincial region. Put it on the same timeline as the weekly positive rate from China CDC. Then you can compare which of the two curves rises first.

Researchers have done this before. A 2025 study in Frontiers in Digital Health searched Douyin, Bilibili and Xiaohongshu for videos about children's flu vaccines. It took 100 videos from each platform, 300 in total. The Spearman correlation between content quality score and comment count was 0.90 ([Frontiers in Digital Health, 2025](https://doi.org/10.3389/fdgth.2025.1591347)). Another study of HPV vaccine discussions collected 15,391 posts from Zhihu, Weibo, Tieba and Xiaohongshu ([PMC full text](https://pmc.ncbi.nlm.nih.gov/articles/PMC13377298/)).

The Frontiers study states that it took its sample in February 2025. With the sampling design above, you repeat the search at several times and deduplicate by ID. Then the sample is closer to "all the discussion that appeared during this period". The same method works for education topics. Change the keywords to after-school services or school admission policy, and change the agency accounts to local education bureaus.

The platform also acts on health content. On November 4, Xiaohongshu started a two-month campaign against health and science rumors. By November 9 it had acted on 574 notes, 205 comments and 18 accounts ([The Paper, 2026-11-09](https://www.thepaper.cn/newsDetail_forward_34439159)). This affects sampling directly. Notes that the platform removes disappear from search results, so a sample that you collect today may not exist next week. When you study health rumors, store the raw responses on the day you collect them, and record the fetch time of every note.

## Errors, rate limits and retries: what is not charged

When the API returns a status other than 200, read `error.code` and `next_steps` in the response body first. When a request hits the rate limit, the API returns 429 and charges nothing, and a retry after `retry_after` seconds works. When the API is unavailable for a short time, it returns 503, which is also not charged. The catalog also says that a `date_range` page with no rows is not charged.

On a retry, one request can go out twice. The REST API accepts an `Idempotency-Key` header. Repeated requests with the same key run only once, and the second request gets the result of the first. The script above creates one UUID per logical request and reuses it on retries.

Our article [AI agent retries and the Idempotency-Key header](/blog/api-idempotency-key-ai-agent-retry) explains the idea and compares implementations. Two more habits help. When you page, keep every parameter except `page_token` the same, and start again from page 1 after a job stops. Store the request `id` from each response with the raw response, so that you can match charges later.

Teams with high volume can create one key per job. Each job then has its own limit and its own billing records, and a problem in one job does not slow down the others.

## Compliance: what the agreement and the laws say

Read three texts before you collect data. The first is the platform agreement. The Xiaohongshu User Service Agreement was updated on March 23, 2026. Clause 3.4 says that you need written permission from Xiaohongshu to copy, read, use or compile statistics on platform content and data. Without it, you may not sell the data or use it commercially in any form. Clause 4.1 forbids taking content through hotlinking, redundant copying, illegal scraping, simulated downloads, deep links, fake registrations and similar means.

It also forbids signing in or using the service through unauthorized third-party software. Clause 2.1 forbids frequent or bulk account registration ([User Service Agreement](https://agree.xiaohongshu.com/h5/terms/ZXXY20220331001/-1), our translation). A self-built scraper needs a signed-in account, so these clauses apply to it directly.

The second is China's Personal Information Protection Law. Article 6 says that collection of personal information must be limited to the minimum scope needed for the purpose. Article 13, item 6, allows you to process personal information that a person or a lawful source made public.

The processing must stay within a reasonable scope ([Full text](https://www.cac.gov.cn/2021-08/20/c_1631050028355286.htm)). For data collection, this means three things. Take only the fields that your study needs. Do not store personal data such as nicknames and avatars if you can avoid it, and hide them in reports.

The third is the Regulations on Network Data Security Management, in force since January 1, 2025. Article 8 forbids stealing network data or getting it by other illegal means ([Regulations](https://www.mee.gov.cn/zcwj/gwywj/202410/t20241003_1087417.shtml)). The Anti-Unfair Competition Law, revised in 2025, also has clauses on data acquisition ([Copy at the China National Intellectual Property Administration](https://www.cnipa.gov.cn/art/2026/5/20/art_104_206437.html)).

| Text | Clause | What it means for data collection |
| --- | --- | --- |
| Xiaohongshu User Service Agreement | 3.4, 4.1, 2.1 | Written permission to read and compile statistics; no illegal scraping; no unauthorized third-party sign-in; no bulk accounts |
| Personal Information Protection Law | Article 6; Article 13, item 6 | Minimum scope for the purpose; public personal data within a reasonable scope |
| Regulations on Network Data Security Management | Article 8 | No stealing of network data and no other illegal means |

We do not give legal advice. Ask a lawyer about your project.

All three texts set rules on purpose and scope. For sampling, this means the following. Collect only the keywords that you study. Go down only to the notes whose comments you need. Store only the fields that you count. Then both data volume and risk go down.

## When to use an official entry point, and when to build your own

Each of the three methods fits a different case. Match your need against this table:

| Your need | Better method | Why |
| --- | --- | --- |
| Users sign in to your app with a Xiaohongshu account | Xiaohongshu open platform | `basic_info` is open; review takes about 1 to 3 working days |
| See your own brand's partnership notes and creator rates | Pugongying | Partnership data stays inside the platform; access needs a verified company account |
| Pull your own ad reports | Juguang Marketing API | Reads only your own ad account; needs sales approval |
| A one-time study of a few thousand rows, with an engineer on the team | Open-source script | Lowest cash cost if you do not count engineer hours (proxy about $2.91 for 10,000 rows a month, with our assumptions), but you need a signed-in account, must follow the agreement and must fix it yourself |
| Monitor a topic on a schedule, 10,000 to 1,000,000 rows a month | Pay-per-call API | Nothing to deploy or maintain yourself; errors are not charged; fits a scheduled job |

If your team already uses an open-source script, you can replace one step with the pay-per-call API and keep the rest. The issues above show both search limits (#877, #874) and note detail parser failures (#497, #499). Use the error log of your own script to pick the first step to replace. Outside Xiaohongshu, Douyin comment collection has the same flow and the same sampling questions. The capability list is on the [Douyin data API](/douyin-api) page.

For a weekly brand share-of-voice report, see [Xiaohongshu share-of-voice weekly report for Singapore and Malaysia brands with Claude](/blog/xiaohongshu-weekly-share-of-voice-report-sea-brands). To store one export as a snapshot and compare it two weeks later, see [Xiaohongshu data export and snapshot analysis](/blog/xiaohongshu-data-export-snapshot-analysis). To let Claude Code run the comment analysis, see [Claude Code dynamic workflows for Xiaohongshu comments](/blog/claude-code-dynamic-workflows-xiaohongshu-comments).

## Recent events that affect Xiaohongshu data

Several recent events change what you collect:

| Date | Event | Effect on collection |
| --- | --- | --- |
| Around 2026-10-15 | The data structure of some note pages changed, and an open-source parser crashed (XHS-Downloader #497, filed on October 17) | Self-built scripts need someone on call; no data until the fix |
| 2026-10-27 | Xiaohongshu reported on its work to protect minors: from July to September it acted on more than 120,000 AI-altered and harmful animation posts, and it learns more than 2,000 new slang codes each day ([Beijing News](https://m.bjnews.com.cn/detail/1793097565129919.html)) | Removed content disappears from results; archive samples on the same day |
| 2026-11-04 | The campaign against health and science rumors started; by November 9 it had acted on 574 notes | Samples on health topics change; use archives to look back |
| 2026-11-06 | Xiaohongshu announced a crackdown on false and low-quality marketing; notes and comments can be limited, folded or removed ([Jiemian](https://m.jiemian.com/article/15301935.html)) | Comment counts may not match visible comments; count from paging results |
| 2026-11-12 | China CDC published week 45 flu surveillance data | Public health topics now have official data to compare with |

## Get started: from the first call to a daily job

For your first call, follow the [quick start](/docs#quickstart). Sign up, get a key, put your keyword into the curl command above and run it once. Then check `count` and `billing.charged_usd`. Prices are on the [pricing page](/pricing), and you can browse every capability by platform in the [data market](/market). To let AI assistants such as Claude or Cursor call the API directly, connect the remote MCP server. The [Xiaohongshu MCP page](/mcp-server/xiaohongshu) lists the tools and the setup:

```text
{
  "mcpServers": {
    "everyinfra": {
      "type": "http",
      "url": "https://api.everyinfra.com/mcp",
      "headers": { "Authorization": "Bearer ${env:EVERYINFRA_API_KEY}" }
    }
  }
}
```

MCP suits ask-and-check work. For sampling jobs that run at fixed times each day, the REST script above with `Idempotency-Key` is more reliable, because retries do not bill twice. The MCP configuration fields follow the Model Context Protocol specification ([MCP specification](https://modelcontextprotocol.io/specification/2025-06-18/basic/transports)). For scheduling, the system cron is enough. Set it to the frequencies in the sampling table above. After each run, archive the JSON Lines file by date, and then run deduplication and the overlap statistics.

## FAQ

### How do I apply for a Xiaohongshu search API?

On November 14, 2026, the official Xiaohongshu open platform opens only one scope, `basic_info`. The `read_notes` scope is still "planned", so there is no official search API to apply for today ([Scope list](https://openaccount.xiaohongshu.com/docs/scope)). A pay-per-call API needs no application. Sign up, get a key and call `xiaohongshu/search` at $0.005556 per call for 20 rows per page.

### Is Xiaohongshu data collection legal?

It depends on what you collect, how you collect it and what you do with it. Clause 3.4 of the platform agreement requires written permission to read or compile statistics on platform content. Clause 4.1 forbids illegal scraping and sign-in through unauthorized third-party software ([User Service Agreement](https://agree.xiaohongshu.com/h5/terms/ZXXY20220331001/-1)). The Personal Information Protection Law limits collection to the minimum scope needed for the purpose ([Full text](https://www.cac.gov.cn/2021-08/20/c_1631050028355286.htm)). Ask a lawyer about your project.

### How do I page Xiaohongshu comments to the end?

Page through `comments`, up to 15 rows per page, until the response has no `next_page_token` and `stop_reason` is `end_of_list`. That means the platform gives no next page.

The catalog says that the default sort can miss or repeat some comments across pages. For more stable paging, use `sort=newest`; with the default sort, page one more round and merge by comment `id`. Some top-level comments have a `sub_comment_count` larger than the replies in their row. For those, call `sub_comments` and page to the end. In this run, one note returned 16 top-level comments in two pages ([Catalog](https://api.everyinfra.com/api/v1/social/catalog)).

### Do the xiaohongshu scraper projects on GitHub still work?

They work, but you must maintain them. The 6 repositories that we checked got 23 new issues from October 15 to November 14. Six of them report login failures, search limits or parser failures. XHS-Downloader #497 records a page structure change around October 15 that crashed the parser ([#497](https://github.com/JoeanAmier/XHS-Downloader/issues/497)). When you pick a repository, check the last push date and the license too.

### How do I analyze the data that a Xiaohongshu scraper collects?

First deduplicate notes by `id`, build comment trees from `reply_to_id`, and convert author IDs to one form. Then group by post time, region and engagement. For the full weekly report and snapshot flow, see [Xiaohongshu data export and snapshot analysis](/blog/xiaohongshu-data-export-snapshot-analysis).

### Does Pugongying have an API?

The public Pugongying pages describe sign-up and partnership flows. A brand must first verify its company account (CNY 600 per application, valid for 1 year). The public pages that we read show no developer endpoint for row-by-row export of notes and comments ([Pugongying sign-up guide](https://pgy.xiaohongshu.com/role-introduce?needLogout=needLogout), [Verification guide](https://fe-video-qc.xhscdn.com/d32a91d3f2fdc2130a7ba5015cc92ca446034613.pdf)).

## References

1. Xiaohongshu open platform: scope list, read 2026-11-14. https://openaccount.xiaohongshu.com/docs/scope
1. Xiaohongshu open platform: quick start, read 2026-11-14. https://openaccount.xiaohongshu.com/docs/quick-start
1. Xiaohongshu Pugongying: sign-up guide, read 2026-11-14. https://pgy.xiaohongshu.com/role-introduce?needLogout=needLogout
1. Xiaohongshu Pugongying home page, read 2026-11-14. https://pgy.xiaohongshu.com/
1. Xiaohongshu company account verification guide (PDF), read 2026-11-14. https://fe-video-qc.xhscdn.com/d32a91d3f2fdc2130a7ba5015cc92ca446034613.pdf
1. Xiaohongshu Juguang Marketing API starter guide, read 2026-11-14. https://ad.xiaohongshu.com/openApiDoc?categoryId=761&articleId=3047
1. Xiaohongshu e-commerce open platform: authorization flow for software vendors, read 2026-11-14. https://open.xiaohongshu.com/document/developer/file/38
1. Xiaohongshu share open platform, read 2026-11-14. https://agora.xiaohongshu.com/index
1. Xiaohongshu User Service Agreement (updated 2026-03-23), read 2026-11-14. https://agree.xiaohongshu.com/h5/terms/ZXXY20220331001/-1
1. NanmiCoder/MediaCrawler README. https://github.com/NanmiCoder/MediaCrawler
1. NanmiCoder/MediaCrawler LICENSE. https://github.com/NanmiCoder/MediaCrawler/blob/main/LICENSE
1. xpzouying/xiaohongshu-mcp README. https://github.com/xpzouying/xiaohongshu-mcp
1. xiaohongshu-mcp issue #874 (2026-10-18). https://github.com/xpzouying/xiaohongshu-mcp/issues/874
1. xiaohongshu-mcp issue #877 (2026-10-21). https://github.com/xpzouying/xiaohongshu-mcp/issues/877
1. xiaohongshu-mcp issue #878 (2026-10-22). https://github.com/xpzouying/xiaohongshu-mcp/issues/878
1. xiaohongshu-mcp issue #880 (2026-10-23). https://github.com/xpzouying/xiaohongshu-mcp/issues/880
1. xiaohongshu-mcp issue #907 (2026-11-05). https://github.com/xpzouying/xiaohongshu-mcp/issues/907
1. JoeanAmier/XHS-Downloader. https://github.com/JoeanAmier/XHS-Downloader
1. XHS-Downloader issue #497 (2026-10-17). https://github.com/JoeanAmier/XHS-Downloader/issues/497
1. XHS-Downloader issue #499 (2026-10-22). https://github.com/JoeanAmier/XHS-Downloader/issues/499
1. cv-cat/Spider_XHS. https://github.com/cv-cat/Spider_XHS
1. jackwener/xiaohongshu-cli. https://github.com/jackwener/xiaohongshu-cli
1. ReaJason/xhs. https://github.com/ReaJason/xhs
1. GitHub REST API: List repository issues. https://docs.github.com/en/rest/issues/issues#list-repository-issues
1. EveryInfra catalog, read 2026-11-14 at 13:05. https://api.everyinfra.com/api/v1/social/catalog
1. China CDC: influenza-like illness surveillance, week 45 of 2026, 2026-11-12. https://www.chinacdc.cn/jksj/jksj04_14275/202611/t20261112_1842956.html
1. China CDC: flu surveillance weekly report no. 934, 2026-11-11. https://www.chinacdc.cn/jksj/jksj04_14249/202611/t20261111_1842933.html
1. China CDC: technical guideline for flu vaccination in China (2026 to 2027). https://www.chinacdc.cn/jkts/202609/t20260903_1839780.html
1. Ganquan Road Subdistrict, Putuo District, Shanghai: flu vaccination notice, 2026-10-08. https://www.shpt.gov.cn/gqjd-jiedaozhen/gsgg-sqzc-gqjd/20261008/973469.html
1. Frontiers in Digital Health: quality of short videos about children's flu vaccines, 2025. https://doi.org/10.3389/fdgth.2025.1591347
1. PMC: study of social media discussion of HPV vaccines. https://pmc.ncbi.nlm.nih.gov/articles/PMC13377298/
1. BMC Public Health: social media discussion of dengue and chikungunya, 2026. https://doi.org/10.1186/s12889-026-29595-0
1. Morstatter and others: Is the Sample Good Enough?, ICWSM 2013. https://doi.org/10.1609/icwsm.v7i1.14401
1. National Bureau of Statistics of China: average annual wages in urban units for 2025, 2026-05-15. https://www.stats.gov.cn/sj/zxfb/202605/t20260515_1963707.html
1. China News Service: RMB central parity rate on November 13, 2026-11-13. https://www.chinanews.com.cn/cj/2026/11-13/10731286.shtml
1. Personal Information Protection Law of the People's Republic of China. https://www.cac.gov.cn/2021-08/20/c_1631050028355286.htm
1. Regulations on Network Data Security Management (State Council Decree No. 790). https://www.mee.gov.cn/zcwj/gwywj/202410/t20241003_1087417.shtml
1. Anti-Unfair Competition Law of the People's Republic of China (2025 revision). https://www.cnipa.gov.cn/art/2026/5/20/art_104_206437.html
1. The Paper: Xiaohongshu starts a campaign against health and science rumors, 2026-11-09. https://www.thepaper.cn/newsDetail_forward_34439159
1. Jiemian: Xiaohongshu cracks down on false and low-quality marketing, 2026-11-06. https://m.jiemian.com/article/15301935.html
1. Beijing News: Xiaohongshu progress on protecting minors, 2026-10-27. https://m.bjnews.com.cn/detail/1793097565129919.html
1. Model Context Protocol specification: Transports. https://modelcontextprotocol.io/specification/2025-06-18/basic/transports
