Parameters
| Param | Required | Value |
|---|---|---|
platform | yes | xiaohongshu |
keyword | yes | for search_posts; Chinese works best, add a city or category qualifier |
post_id | yes | for get_comments; the string after explore/ |
limit | no | rows to return, default 20 |
Search response
items[]: id, url, author (with handle), text (note body plus hashtags), stats (likes / comments / shares / collects / views), cover, created_at.
On Xiaohongshu collects is reliably populated and is a better intent signal than likes — people save what they plan to use.
Known limits (stated plainly)
- Occasional malformed notes: an item can come back as
{"error": "normalize_failed"}. Handle per item and keep the rest of the batch. - Timestamps can be null: some notes do not expose publish time; treat
nullas unknown, not 1970. - Covers are signed, expiring URLs: mirror them immediately if you need them long term.
Copy and run
cURL
curl -s https://lucydomi.com/mcp/v1/search_posts \
-H "Authorization: Bearer $BUSYBEE_API_KEY" \
-H "Content-Type: application/json" \
-X POST \
-d '{"platform": "xiaohongshu", "keyword": "coffee", "limit": 20}'Python (stdlib, no dependencies)
import os, json, urllib.request
KEY = os.environ["BUSYBEE_API_KEY"]
req = urllib.request.Request(
"https://lucydomi.com/mcp/v1/search_posts",
data=json.dumps({"platform": "xiaohongshu", "keyword": "coffee", "limit": 20}).encode(),
headers={"Authorization": f"Bearer {KEY}", "Content-Type": "application/json"},
method="POST",
)
data = json.load(urllib.request.urlopen(req, timeout=60))
for n in data["items"]:
if n.get("error"):
continue
print(n["stats"]["likes"], n["stats"]["collects"], n["url"])
Real response sample
Taken from a real production call; truncated, image/signed URLs removed.
{
"ok": true,
"platform": "xiaohongshu",
"tool": "search_posts",
"count": 2,
"items": [
{
"id": "6ada5f59000000002a01f993",
"url": "https://www.xiaohongshu.com/explore/6ada5f59000000002a01f993",
"author": {"handle": "294505110", "name": "\u5c0f\u675c"},
"text": "\u8fd1\u671f\u559d\u5230\u768414\u676f\u7ec6\u7ce0\uff08\u65e0\u5e7f\u5408\u96c6\uff09",
"created_at": null,
"stats": {"likes": 183, "comments": 15, "shares": 95, "views": 0, "collects": 198}
},
{"platform": "xiaohongshu", "error": "normalize_failed"}
]
}FAQ
Can I sort by likes or filter by date range?
The search endpoint returns upstream relevance order. Sort locally — every stat you need is in the payload.
How many comments can I pull?
Up to
limit, subject to the upstream single-call cap. For analysis rather than raw text, sample with comment insights first.Are hashtags and emoji preserved?
Yes, raw text is preserved; clean it yourself.
Anything special about mainland platforms?
Douyin and Xiaohongshu live in the domestic key group; new accounts get 5 free domestic trial calls before a top-up unlocks the group.
Related
One key, six platforms
Same schema, same MCP endpoint, one parameter to switch platforms. Sign-up credit included, failed calls are free.
See pricing Try it first