Does Xiaohongshu (RedNote) have an API? Get notes and comments with Python
Xiaohongshu (RedNote) has no self-serve API for notes or comments. Search notes, read one and page through its comments with Python, then save a CSV.
Xiaohongshu (小红书), known outside China as RedNote, is where Chinese consumers review products, restaurants and travel spots. If you want that data in a spreadsheet, a dashboard or an AI agent, the first question is whether there is an API.
Is there an official Xiaohongshu API?
Not for notes or comments. Xiaohongshu's open platform mainly serves merchants and partners. It does not give developers public notes, comments or search results. That leaves two options:
- Scrape it yourself: accounts, cookies, request signing and proxies to maintain, and they break whenever the app changes.
- Use a data API: send an HTTPS request with an API key and get JSON back.
This guide takes the second route with Qovia's Xiaohongshu endpoints. You pay only for calls that return data.
What you need
- Python 3.8 or later and the
requestspackage:pip install requests. - A Qovia API key: create one in the console and put it in an environment variable, so it never ends up in your code.
export QOVIA_KEY="sk-qovia-..."
Step 1: a small helper
Every endpoint is a GET request under https://api.qovia.ai/v1/raw/xiaohongshu/. The key goes in the Authorization header. A successful call answers 200 with the result in data. An empty result (a deleted note, a search with no hits) is also a 200, with data empty or null, and is not charged.
import os import requests API = "https://api.qovia.ai/v1/raw/xiaohongshu" HEADERS = {"Authorization": f"Bearer {os.environ['QOVIA_KEY']}"} def call(endpoint, **params): resp = requests.get(f"{API}/{endpoint}", headers=HEADERS, params=params, timeout=60) if not resp.ok: # The body says why, e.g. {"error": {"code": "invalid_params", "message": "..."}} raise RuntimeError(f"{endpoint}: HTTP {resp.status_code} {resp.text[:300]}") return resp.json()["data"] or {}
Step 2: search notes by keyword
Note search returns 20 notes a page. You can sort by latest, most_liked, most_commented or most_saved, and filter by note type and publish time. Search in Chinese, the way users write.
page = call("search", keyword="咖啡", sort="most_liked") # 咖啡 = coffee for note in page.get("items", []): extra = note["extra"] print(extra["source_id"], note["metrics"]["likes"], extra["title"])
Each result has the note's ID in extra.source_id, its link in extra.url, and like, comment, save and share counts in metrics. Ask for the next page with page=2, page=3 and so on, and stop when has_more is false.
Step 3: read one note
The note ID is the 24-character string in a note link: xiaohongshu.com/explore/<note ID>. Note detail returns the full text, exact counts, topics, publish time, IP location, images and, for video notes, the video link.
note = call("note", note_id="6a14846d000000000702d0d4") print(note["extra"]["title"]) print(note["text"][:200]) print(note["metrics"]) # likes, comments, saves, shares
Step 4: page through the comments
Note comments come a page at a time. Pass each page's cursor back to get the next one, and stop when has_more is false. sort="latest" gives newest first. Leave it out for Xiaohongshu's own order, with pinned and popular comments first. max_pages caps how much one run can fetch.
def all_comments(note_id, max_pages=20): comments, cursor = [], None for _ in range(max_pages): params = {"note_id": note_id, "sort": "latest"} if cursor: params["cursor"] = cursor page = call("comments", **params) comments += page.get("items", []) if not page.get("has_more"): break cursor = page["cursor"] return comments
Each comment has cid, text, likes, reply_count, ip_location, created_at and the author's nickname. The replies under a comment come from comment replies, paged the same way.
Step 5: save a CSV
Write the file as utf-8-sig, so Excel shows the Chinese text correctly when you double-click it.
import csv rows = all_comments("6a14846d000000000702d0d4") with open("comments.csv", "w", newline="", encoding="utf-8-sig") as f: writer = csv.writer(f) writer.writerow(["cid", "created_at", "likes", "replies", "ip_location", "nickname", "text"]) for c in rows: writer.writerow([c["cid"], c["created_at"], c["likes"], c["reply_count"], c["ip_location"], c["author"]["nickname"], c["text"]]) print(len(rows), "comments saved")
Costs and limits
- Each call that returns data is charged once at the endpoint's price (see pricing). Empty results, errors and timeouts are not charged.
- Every response tells you what the call cost (
meta.charged_usd) and your balance after it (meta.balance_usd). - If you send too many requests in a minute, the API answers 429 with a
Retry-Afterheader. Wait that many seconds and try again. - Need help with an error? Branch on
error.code; the codes are listed in the API reference.
Next
- Rather ask in plain language? Connect the same data to Claude Code or Cursor with MCP.
- Doing the same for Douyin? See Export Douyin comments to Excel with Python.
- Brand-deal data on Xiaohongshu creators (follower profiles, note performance) is on the Pugongying page.
Endpoints in this guide
More guides
- DouyinExport Douyin comments to Excel with PythonPull every comment on a Douyin video and the replies under them through an API, deduplicate them and save a CSV that opens cleanly in Excel. Full Python code.
- DouyinXiaohongshu (RedNote)WeiboUse Douyin, RedNote and Weibo data in Claude Code and Cursor with MCPConnect Qovia's MCP server to Claude Code, Cursor or VS Code and ask about Chinese social media in plain language. The AI finds the data and sums it up.