Xiaohongshu API endpoint
Returns one page of the anonymous Xiaohongshu explore feed as normalized note cards: note id, a ready-to-call note_url carrying its short-lived xsec_token, type, title, cover image, like count, and a public author card. Omit channel_id for the upstream default recommendation feed; use channel_id with an id from the channels list returned by this endpoint for a category feed. The upstream serves one server-rendered page per channel (typically 20-33 cards) and has no credential-free cursor, so there is no pagination. Search, user profiles, comments, and note detail without a feed token are not available on this anonymous surface. The xsec_token in note_url is short-lived; call /xiaohongshu/note promptly with the returned note_url, and re-run this endpoint for a fresh token when it expires.
/xiaohongshu/exploreReturns one page of Xiaohongshu's anonymous explore or channel feed, normalized from the site's own server-rendered page state. Each response carries the note cards currently rendered for one channel, the selectable channel list, and the channel id that was actually served. There is no pagination: the anonymous upstream exposes no cursor, so this endpoint always returns the single page it was served.
Query parameters:
channel_id (optional) — one id from the channels array returned in a previous response. Omit it for the upstream's default recommendation feed. The accepted values are dynamic rather than a fixed enum: the channels list returned by this endpoint plus the resolved default id homefeed_recommend (echoed as channel_id in a no-channel response). A malformed or unknown value is rejected with 400; a value that is not present in the served channel list is also rejected with 400.Notable response behavior:
items holds public note cards only: note_id, note_url, xsec_token, type, title, cover_url, liked_count, and a public author card. Description, comments, coordinates, and any account or private field are not part of the anonymous feed.note_url is the value to forward: it already carries the note id and a short-lived xsec_token. The token expires, so call /xiaohongshu/note promptly and re-run this endpoint for a fresh card when it does. xsec_token is also returned separately for diagnostics, but note_url is the ready-to-call form.count is the number of usable cards in this one response (typically 20 to 33). Cards missing a note id, token, or card body are dropped; if no usable card remains, the endpoint reports an upstream error instead of returning an empty success, so count: 0 is not a normal result.channel_id is the channel the upstream actually served; it may differ from the request when channel_id was omitted./login, HTTP 461, or HTTP 403/406/429) is reported as an upstream 503, not as an empty feed. A redirect to /404/sec_* (error code 300031) means the note token was stale or the note was removed and is reported as 404.| Field | Filled in, of 30 checked | Values in the sample |
|---|---|---|
| note_id | 30 | |
| note_url | 30 | xiaohongshu.com |
| xsec_token | 30 | |
| type | 30 | normal (17), video (13) |
| title | 29 | “Vlog👧🏻97年妈妈姐和3岁女儿的一天~” and 28 other values |
| cover_url | 30 | sns-webpic-qc.xhscdn.com |
| liked_count | 30 | 478 to 100,000, median 8,152 |
| author | 30 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| channel_id | string | No | Optional explore channel id from the channels list in a previous response. Unknown values are rejected; omit for the default feed. | homefeed.food_v3 | |
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/xiaohongshu/explore" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"channel_id": "homefeed_recommend",
"channels": [
{
"id": "homefeed.food_v3",
"name": "美食"
},
{
"id": "homefeed.travel_v3",
"name": "旅行"
}
],
"count": 1,
"items": [
{
"note_id": "0123456789abcdef01234567",
"note_url": "https://www.xiaohongshu.com/explore/0123456789abcdef01234567?xsec_token=SYNTHETIC-EXAMPLE-TOKEN-0001&xsec_source=pc_feed",
"xsec_token": "SYNTHETIC-EXAMPLE-TOKEN-0001",
"type": "normal",
"title": "Synthetic example note",
"cover_url": "https://sns-img.example.test/synthetic-cover.jpg",
"liked_count": 42,
"author": {
"user_id": "000000000000000000000002",
"nickname": "synthetic_user",
"avatar_url": "https://sns-avatar.example.test/synthetic-avatar.jpg"
}
}
]
}
}Request schema
No body schema
Response schema
#/definitions/xiaohongshu.exploreResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| code | integer | No | 200 | |||
| data | xiaohongshu.ExploreResponse | No | ||||
| data.channel_id | string | No | homefeed_recommend | |||
| data.channels | array | No | ||||
| data.channels[].id | string | No | homefeed.food_v3 | |||
| data.channels[].name | string | No | 美食 | |||
| data.count | integer | No | 30 | |||
| data.items | array | No | ||||
| data.items[].author | xiaohongshu.NoteAuthor | No | ||||
| data.items[].author.avatar_url | string | No | ||||
| data.items[].author.nickname | string | No | synthetic_user | |||
| data.items[].author.user_id | string | No | 000000000000000000000002 | |||
| data.items[].cover_url | string | No | ||||
| data.items[].liked_count | integer | No | 14000 | |||
| data.items[].note_id | string | No | 0123456789abcdef01234567 | |||
| data.items[].note_url | string | No | ||||
| data.items[].title | string | No | ||||
| data.items[].type | string | No | video | |||
| data.items[].xsec_token | string | No | ||||
| msg | string | No | OK |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 404 | Not Found | #/definitions/app.Response |
| 429 | Too Many Requests | #/definitions/app.Response |
| 500 | Internal Server Error | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/xiaohongshu/explore" \
-H "x-api-key: $CRAWLORA_API_KEY"