Answers

Do I need an xsec_token to get a Xiaohongshu note, and how do I get one from a note ID?

Short answer

On Xiaohongshu's own web API, yes: a note opened without the xsec_token that came with it from a search or feed is often refused, and the token cannot be derived from the note ID. Through okdata you pass just the note ID or a share link and get the note back for $0.02; tokens are handled on our side.

You have a spreadsheet of note IDs from last month's campaign and want fresh like and save counts. Opening xiaohongshu.com/explore/<id> in a script returns an empty page, a "note unavailable" message or a 461, while the same link copied from the app works. The difference is the xsec_token query parameter. Xiaohongshu attaches it to every note it shows you in search results, feeds and profiles, and checks it when the note is opened. It is issued by the server, tied to where you found the note, and expires. There is no formula to turn a note ID into a valid token, which is why "how do I get xsec_token from note_id" keeps coming up in scraper issue trackers.

Xiaohongshu note detail takes either id (the 24-character note ID) or url (a note page link or an xhslink.com share link). You do not send a token. You get the title, full text, every image or the video, likes, saves, comment and share counts, hashtags and the publish time.

If you are starting from keywords, note search returns note IDs ready for the detail call.

What it costs

Notes to refresh Calls Cost
1 1 $0.02
100 100 $2.00
1,000 1,000 $20.00

If all you need are the counts of notes that rank for a keyword, search results already carry likes, saves and comment counts for about 20 notes per call.

Example

import os, requests

ids = ["6650a1b2000000001e00abcd"]
for note_id in ids:
    r = requests.get(
        "https://api.okdata.online/v1/xiaohongshu/notes/get",
        headers={"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"},
        params={"id": note_id, "fields": "id,title,metrics.likes,metrics.favorites,metrics.comments"},
        timeout=60,
    )
    print(r.json()["data"]["item"])

With view=full, the token Xiaohongshu attached to the note, when there is one, comes back under ext.xsec_token, handy if you want to build a link a person can open.

Gotchas

  • Deleted or private notes return not_found, which is not charged.
  • metrics.views is null: Xiaohongshu does not publish view counts.
  • There is no batch call for note detail; each note is one call and one charge.

Alternatives

Open-source tools such as XHS-Downloader and Spider_XHS take a full link with its token and work well for one-off downloads from your own browser session. They break when the token is missing or stale. If you have only IDs, or you refresh the same notes every week, the ID-based call is simpler. The competitor monitoring page shows a weekly refresh.

Updated