# Xiaohongshu API in Python: notes, profiles and comments (2026)

> A Python client for public Xiaohongshu (RedNote) data: note search, note detail, creator profile, a creator's notes and comments, with paging, retries and the cost of a run.

Canonical page: https://okdata.online/guides/xiaohongshu-api-python/

Xiaohongshu's official open platform is built for shops, not for reading public notes, so this guide calls five okdata endpoints from plain requests: note search, note detail, account profile, account notes and note comments. The worked example is 5 calls and costs $0.10; a failed call is not charged.

Updated 2026-11-12

Is there an official Xiaohongshu API for this? Xiaohongshu runs an open platform, but it is the e-commerce open platform: tool apps that a shop authorises (ERP, order printing, listing products, inventory) and apps a shop builds for its own systems. PGY and the ad tools serve advertisers with their own campaigns. None of them offers an endpoint for searching everyone's notes or reading the comments under them; [Xiaohongshu's official API options](https://okdata.online/answers/xiaohongshu-official-api/) goes through each channel.

Then there is the token. Xiaohongshu's own web API attaches an `xsec_token` to each note it shows you and checks it when the note is opened, so a script holding only note IDs gets refused. [The xsec_token answer](https://okdata.online/answers/xiaohongshu-xsec-token/) explains the mechanism. With the endpoints below you pass IDs or links and never handle a token, a cookie or a signature.

You end with a small Python client: one helper that handles errors and retries, a pager with a page cap, five endpoints and a JSON report.

## Step by step

### Step 1: set up

Python 3.9 or newer, `requests` and your key in an environment variable. There is no SDK to install.

```bash
pip install requests
export OKDATA_API_KEY=okd_...
```

Each call is a GET to `https://api.okdata.online` plus the endpoint path, with the key as a bearer token. A success has `"code": "ok"` and the data under `data` (`data.items` and a `page` for lists, `data.item` for single objects). An error has `code`, `message`, `request_id` and a `retry` hint: `yes` means try again later, after `retry_after_seconds` when it is set.

### Step 2: search notes

[Xiaohongshu note search](https://okdata.online/apis/xiaohongshu/notes/search/) takes `query`, `sort` (`general`, `latest` or `popular`) and `type` (`all`, `video` or `image`). One call returns about 20 notes for $0.02, each with `id`, `title`, the opening of `text`, `author`, `published_at`, `hashtags` and `metrics` (likes, favorites, comments, shares).

```bash
curl -G "https://api.okdata.online/v1/xiaohongshu/notes/search" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'query=防晒霜' \
  --data-urlencode 'sort=popular'
```

### Step 3: one note in full

[Xiaohongshu note detail](https://okdata.online/apis/xiaohongshu/notes/get/) takes `id` (24 hex characters) or `url` (a note link or an xhslink share link) and returns the full text, every image (a video note gives its cover), hashtags and current counts for $0.02. With `view=full`, `ext.xsec_token` carries the token Xiaohongshu attached to the note, handy for building a link a person can open.

```bash
curl -G "https://api.okdata.online/v1/xiaohongshu/notes/get" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'url=https://www.xiaohongshu.com/explore/672a4f1d000000001b03c58e'
```

### Step 4: the author's profile

[Xiaohongshu account profile](https://okdata.online/apis/xiaohongshu/users/get/) takes the user ID as `id` (the note's `author.id`) or a profile link as `url`, for $0.02. It returns `followers`, `following`, `posts` (notes published), `likes` (likes and saves together, as the profile shows them), `bio`, `verified` and `username`, the Xiaohongshu number. With `view=full`, `ext.ip_location` is the region on the profile.

### Step 5: the author's notes

[Xiaohongshu account notes](https://okdata.online/apis/xiaohongshu/users/notes/list/) needs the user ID as `id` and returns about 20 notes per call, newest first, for $0.02. The `author` block on these items carries only the ID, since you asked for that account.

### Step 6: comments under a note

[Xiaohongshu note comments](https://okdata.online/apis/xiaohongshu/notes/comments/list/) needs the note `id` and returns about 10 top-level comments per call for $0.02, each with `text`, `author`, `likes`, `replies`, `published_at` and `ip_location`.

```bash
curl -G "https://api.okdata.online/v1/xiaohongshu/notes/comments/list" \
  -H "Authorization: Bearer $OKDATA_API_KEY" \
  --data-urlencode 'id=672a4f1d000000001b03c58e'
```

### Step 7: the whole script

The script runs the worked example and writes `xhs_report.json`. `call` reuses one `Idempotency-Key` across retries of the same request, so a retry after a dropped connection is never charged twice. `pages` caps how many pages any list may read, which caps the spend too.

```python
import json
import os
import time
import uuid
import requests

API = "https://api.okdata.online"
SESSION = requests.Session()
SESSION.headers["Authorization"] = f"Bearer {os.environ['OKDATA_API_KEY']}"
COMMENT_PAGES = 1   # each page is one call
AUTHOR_PAGES = 1


class ApiError(Exception):
    def __init__(self, body):
        super().__init__(f"{body['code']}: {body['message']} (request {body['request_id']})")
        self.code = body["code"]


def call(path, **params):
    key = str(uuid.uuid4())  # same key on every retry: a replay is not charged again
    for attempt in range(3):
        body = SESSION.get(API + path, params=params, headers={"Idempotency-Key": key}, timeout=60).json()
        if body["code"] == "ok":
            return body
        if body.get("retry") == "yes" and attempt < 2:
            time.sleep(body.get("retry_after_seconds") or 5)
            continue
        raise ApiError(body)


def pages(path, max_pages, **params):
    """Yield items page by page; stop at max_pages or when has_more is false."""
    cursor = None
    for _ in range(max_pages):
        body = call(path, **params, **({"cursor": cursor} if cursor else {}))
        yield from body["data"]["items"]
        if not body["page"]["has_more"]:
            return
        cursor = body["page"]["next_cursor"]


found = call("/v1/xiaohongshu/notes/search", query="防晒霜", sort="popular")["data"]["items"]
if not found:
    raise SystemExit("no notes for that query")
top = max(found, key=lambda n: n["metrics"]["likes"] or 0)

note = call("/v1/xiaohongshu/notes/get", id=top["id"])["data"]["item"]
author = call("/v1/xiaohongshu/users/get", id=note["author"]["id"])["data"]["item"]
recent = list(pages("/v1/xiaohongshu/users/notes/list", AUTHOR_PAGES, id=author["id"]))
comments = list(pages("/v1/xiaohongshu/notes/comments/list", COMMENT_PAGES, id=note["id"]))

report = {
    "note": {"id": note["id"], "title": note["title"], "text": note["text"], "images": note["images"],
             "likes": note["metrics"]["likes"], "saves": note["metrics"]["favorites"],
             "comments": note["metrics"]["comments"], "published_at": note["published_at"]},
    "author": {"id": author["id"], "name": author["name"], "followers": author["followers"],
               "notes": author["posts"], "likes_and_saves": author["likes"]},
    "recent_notes": [{"id": n["id"], "title": n["title"], "published_at": n["published_at"],
                      "likes": n["metrics"]["likes"]} for n in recent],
    "comments": [{"text": c["text"], "likes": c["likes"], "replies": c["replies"],
                  "ip_location": c["ip_location"]} for c in comments],
}
with open("xhs_report.json", "w", encoding="utf-8") as f:
    json.dump(report, f, ensure_ascii=False, indent=2)
```

Scale it by raising the caps and looping over more notes. Twenty notes in full with three comment pages each is $1.60.

## Good to know

- **No view counts.** Xiaohongshu hides views on public notes, so `metrics.views` is null; `meta.unavailable` says `platform`. Saves (`favorites`) and comments are the signals to rank by.
- **Two IDs per person.** The user ID (24 hex characters) is what the account endpoints take; the Xiaohongshu number in `username` is what people share. Profile links and share links work as `url`.
- **Deleted or private is free.** A note or account that is gone returns `not_found` and is not charged. The script raises `ApiError` with that code; catch it in batch jobs and move on.
- **Counts differ.** A note's comment count includes replies; the comments endpoint lists top-level comments with each one's reply count.
- **Times are UTC.** Every `published_at` is ISO 8601 in UTC.
- **Trim what you do not read.** `fields=id,title,metrics.likes` keeps only those fields and `view=compact` returns fewer fields per object; neither changes the price, both make responses shorter for a model.

For a keyword-wide comment export, the step-by-step [Xiaohongshu note comments guide](https://okdata.online/guides/xiaohongshu-note-comments/) goes from one search to a CSV. For the price of search at volume, see [the note search price](https://okdata.online/answers/xiaohongshu-note-search-api-price/).

## What the example costs

One search for 防晒霜 (sunscreen), the most-liked note in full, its author's profile and latest notes, and the first page of comments under the note

| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| [Xiaohongshu note search](https://okdata.online/apis/xiaohongshu/notes/search/) | 1 | $0.02 | $0.02 |
| [Xiaohongshu note detail](https://okdata.online/apis/xiaohongshu/notes/get/) | 1 | $0.02 | $0.02 |
| [Xiaohongshu account profile](https://okdata.online/apis/xiaohongshu/users/get/) | 1 | $0.02 | $0.02 |
| [Xiaohongshu account notes](https://okdata.online/apis/xiaohongshu/users/notes/list/) | 1 | $0.02 | $0.02 |
| [Xiaohongshu note comments](https://okdata.online/apis/xiaohongshu/notes/comments/list/) | 1 | $0.02 | $0.02 |
| Total | 5 |  | $0.10 |

Prices in force when this page was built. A failed call costs nothing.

## In your AI (MCP)

Connect the MCP server once, then say what you want. The agent finds these endpoints, reads their prices and calls them on your balance.

Say: Search Xiaohongshu for 防晒霜 (sunscreen), most popular first, open the most-liked note in full, look up its author's profile and latest notes, and read the first page of comments under the note. Tell me what the comments ask about.

```json
{
  "endpoint": "xiaohongshu.notes.search",
  "params": {
    "query": "防晒霜 推荐"
  },
  "idempotency_key": "<a new UUID>"
}
```

MCP: `https://api.okdata.online/mcp`

## Endpoints in this guide

- [Xiaohongshu note search](https://okdata.online/apis/xiaohongshu/notes/search/) `xiaohongshu.notes.search`: $0.02 per call · about 20 notes per page
- [Xiaohongshu note detail](https://okdata.online/apis/xiaohongshu/notes/get/) `xiaohongshu.notes.get`: $0.02 per call
- [Xiaohongshu account profile](https://okdata.online/apis/xiaohongshu/users/get/) `xiaohongshu.users.get`: $0.02 per call
- [Xiaohongshu account notes](https://okdata.online/apis/xiaohongshu/users/notes/list/) `xiaohongshu.users.notes.list`: $0.02 per call · about 20 notes per page
- [Xiaohongshu note comments](https://okdata.online/apis/xiaohongshu/notes/comments/list/) `xiaohongshu.notes.comments.list`: $0.02 per call · about 10 comments per page

## More about Xiaohongshu (RedNote)

- [Xiaohongshu (RedNote) API](https://okdata.online/apis/xiaohongshu/)
- [How to export Xiaohongshu comments for a keyword](https://okdata.online/guides/xiaohongshu-note-comments/)
- [How to shortlist Xiaohongshu PGY creators by rate and reads](https://okdata.online/guides/xiaohongshu-pgy-creator-rates/)
- [How to search Xiaohongshu notes and export them to CSV](https://okdata.online/guides/xiaohongshu-search-export-notes/)
- [Is there a Xiaohongshu MCP server that doesn't need a QR code login?](https://okdata.online/answers/xiaohongshu-mcp-qr-login-expires/)
- [How do I add Xiaohongshu data to Cursor or Cline through MCP?](https://okdata.online/answers/cursor-cline-xiaohongshu-mcp/)
- [Xiaohongshu returns error 300011 (account abnormal). How do I keep collecting notes?](https://okdata.online/answers/xiaohongshu-300011-account-abnormal/)
- [How do I find complaints about a brand on Xiaohongshu?](https://okdata.online/answers/xiaohongshu-brand-complaints/)
- [How do I export every note from a Xiaohongshu creator's profile?](https://okdata.online/answers/xiaohongshu-export-creator-notes/)
- [How do I find Xiaohongshu KOLs in a niche and get their follower counts?](https://okdata.online/answers/xiaohongshu-find-kol-creators/)
- [Scraping it yourself vs a per-call data API: cost, upkeep and risk](https://okdata.online/compare/scraping-vs-data-api/)
- [How to choose a social media data API (2026)](https://okdata.online/compare/social-media-data-apis/)
- [MCP servers for social media data: self-hosted vs hosted](https://okdata.online/compare/social-media-data-mcp-servers/)
- [Xiaohongshu data APIs: official, third-party or open-source (2026)](https://okdata.online/compare/xiaohongshu-data-apis/)

## Sources

- [小红书电商开放平台](https://open.xiaohongshu.com/) (read 2026-11-12)
