DEV Community

mian po
mian po

Posted on

Engineering Reliable Cursor Workflows for Public RedNote Data

Social-data integrations often fail in boring places: a copied page token expires, a cursor is reused with the wrong resource, a timeout is mistaken for an empty page, or a missing metric is silently converted into zero.

I built the public examples for XHS Data API around those failure modes rather than around the happy path alone. The API exposes normalized public Xiaohongshu (RedNote) note details, top-level comments, author profiles, published-note pages, media inventories, and sequential batches.

The complete Python and Node.js examples are available from the developer website as a versioned download.

Start With A Complete Public URL

Detail and comment requests use the complete public note URL, including its current xsec_token. Keep the URL and RapidAPI key in server-side environment variables:

export X_RAPIDAPI_KEY="your_rapidapi_key"
export XHS_NOTE_URL="complete_current_public_note_url"
Enter fullscreen mode Exit fullscreen mode

First validate the URL locally:

parsed = client.parse_note_url(os.environ["XHS_NOTE_URL"])
detail = client.detail_from_url(os.environ["XHS_NOTE_URL"])
print(parsed["note_id"], detail["note"].get("title"))
Enter fullscreen mode Exit fullscreen mode

The parser does not fetch upstream data. This separates malformed-input errors from upstream availability errors before the expensive step begins.

Treat Cursor State As A Contract

The first comment request has no cursor. Every later request must use the exact next_cursor returned by the previous page and keep the same note URL:

cursor = None
seen = set()

while True:
    page = client.comments_page(note_url, cursor=cursor, count=10)
    for comment in page["items"]:
        if comment["comment_id"] not in seen:
            seen.add(comment["comment_id"])
            yield comment
    if not page["has_more"]:
        break
    cursor = page["next_cursor"]
Enter fullscreen mode Exit fullscreen mode

The client repository also deduplicates IDs defensively. A cursor is short-lived and resource-bound; editing it or moving it to another note is a client error.

A Timeout Is Not An Empty Page

When an upstream page cannot finish within the service budget, the API returns a structured error instead of 200 with an empty list:

{
  "code": 503,
  "msg": "Comments did not load",
  "error_code": "REQUEST_TIMEOUT",
  "data": {
    "request_id": "support-id",
    "retry_after": 3
  }
}
Enter fullscreen mode Exit fullscreen mode

Wait for Retry-After, then retry the identical URL and cursor. Do not advance the chain. Long cooldowns are intentionally not hidden behind aggressive automatic retries.

Preserve Unknown Values

Public profile cards and note summaries do not always contain full engagement or media fields. The normalized contract returns null when the source did not supply a value. That is different from numeric zero and boolean false.

This detail matters in dashboards. Converting unknown likes to zero changes averages, rankings, and trend lines. The user-note endpoints expose content coverage so an application can choose a lightweight summary page or request a small detail-enriched page.

Keep Support IDs, Not Secrets

Every response includes data.request_id. Log that ID with the endpoint and HTTP status. Do not log RapidAPI keys, cookies, browser state, or complete signed URLs.

Try The Examples

The repository includes:

  • a reusable Python client with structured errors and bounded retries;
  • Node.js 20 examples using built-in fetch;
  • duplicate-safe comment and user-note pagination;
  • asynchronous batch submission and polling;
  • troubleshooting guidance for 400, 401, 403, 429, and 503 responses.

Start with the developer guides or download the client examples. The current public API focuses on stable read workflows and does not advertise note search or child-comment replies.

XHS Data API is independent and is not affiliated with or endorsed by Xiaohongshu/RedNote. Use public data lawfully and follow applicable law, third-party rights, and source-platform rules.

Top comments (0)