# Xiaohongshu (RedNote) Note Scraper API – No xsec\_token (`lance_api/rednote-note-detail-scraper-api`) Actor

Scrape public Xiaohongshu (RedNote) note details without requiring xsec\_token. Extract note metadata, author, engagement, tags, media, and structured JSON from note IDs or URLs.

- **URL**: https://apify.com/lance\_api/rednote-note-detail-scraper-api.md
- **Developed by:** [LanceAPI](https://apify.com/lance_api) (community)
- **Categories:** Social media, Developer tools, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $17.00 / 1,000 url processings

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## RedNote (Xiaohongshu) Note Detail Scraper API – No xsec\_token Required

**Extract structured details from public RedNote/Xiaohongshu notes—including video notes, image galleries, author data, engagement, tags, timestamps, covers, and optional downloadable video URLs.**

**No `xsec_token` is required for normal use. If you already have a valid token in the URL or provide one separately, the Actor can use it when resolving that public note.**

Submit a 24-character note ID, a supported Xiaohongshu URL, an `xhslink.com` or `xhslink.cn` short link, or complete app share text. Process 1–1,000 inputs per run and receive one Dataset record for every submitted input, including clear failure and duplicate records.

Equivalent inputs are normalized to the same note identity, so canonical duplicates are resolved and billed only once. Keep the downloadable-video option off when metadata and media details are enough, and pay for the video URL add-on only when a URL is requested and successfully returned.

Note details cost **$20 per 1,000 successful notes** at the standard rate, or as little as **$17 per 1,000** with the lowest eligible Store rate. The optional downloadable video URL follows the same per-result pricing.

### ✨ Key features

- **Complete note details for research and automation** — Return the note type, native title and description, author, engagement, tags, source timestamps, and scrape timestamp in predictable JSON.
- **Video and image notes in one API** — Use the same input and output workflow for Xiaohongshu video posts and multi-image galleries.
- **Flexible RedNote inputs** — Submit note IDs, supported full URLs, short links, or app share text without building separate parsers.
- **Batch processing up to 1,000 inputs** — Feed data pipelines, catalogs, dashboards, n8n, Make, Zapier, or API workflows with isolated per-input results.
- **Duplicate-aware processing** — Every submitted input receives a record, while canonical duplicate notes are resolved and billed only once.
- **Optional downloadable video URL add-on** — Request a playable video URL only when needed, keeping metadata-only runs lighter and avoiding unnecessary add-on charges.

### 🚀 Quick start

In Apify Console:

1. Add one or more note IDs, URLs, short links, or supported share texts to `urls`.
2. Keep the default options for normal note-detail extraction.
3. Click **Start**.
4. Open the run's **Dataset**.
5. Read one structured result record for each submitted input.

Minimal input:

```json
{
  "urls": ["6428b7be000000001300d335"]
}
```

### Supported RedNote / Xiaohongshu inputs

The Actor accepts:

- A 24-character hexadecimal note ID, such as `6428b7be000000001300d335`
- `https://www.xiaohongshu.com/explore/{noteId}`
- `https://www.xiaohongshu.com/discovery/item/{noteId}`
- `https://www.xiaohongshu.com/red_video/{noteId}`
- HTTP or HTTPS `xhslink.com` short links
- HTTP or HTTPS `xhslink.cn` short links
- Complete app share text containing one supported URL
- Markdown-wrapped supported links

The Actor follows supported short-link redirects, extracts the note ID, and returns a canonical `normalizedUrl` in the form `https://www.xiaohongshu.com/explore/{noteId}`. Tracking and query parameters are not included in `normalizedUrl`.

Profile pages, search pages, unrelated domains, unsupported Xiaohongshu paths, and text without a supported URL or note ID are rejected with a structured failure result.

#### Note IDs and `xsec_token`

A note ID is the preferred input. Find it in a supported note URL after `/explore/`, `/discovery/item/`, or `/red_video/`, or in the `noteId`/`id` field returned by a search or user-notes workflow.

A valid `xsec_token` can improve resolution reliability for public notes that require it, but it is not required for normal use. Submit a note ID or URL without a token, use a URL that already contains `xsec_token`, or provide it through the separate `xsecToken` input.

If both are present, the separate `xsecToken` input takes precedence over the token in the URL. The separate field applies to the run, so keep different note-specific tokens in their matching URLs when processing a batch. A missing token is allowed. An expired or invalid token can cause resolution to fail. Tokens and other query parameters are not included in `normalizedUrl`.

### Input

| Field | Type | Required | Default | Limits | Description |
|---|---|---:|---|---|---|
| `urls` | `string[]` | Yes | None | 1–1,000 items | Note IDs, supported full URLs, short links, Markdown links, or app share text. Values are trimmed, normalized, and deduplicated by canonical note identity. |
| `xsecToken` | `string` | No | Empty | One run-level value | Optional token for a public note. It overrides a token found in the URL and is best suited to a single-note run. For note-specific batch tokens, keep each token in its corresponding URL. |
| `includeMedia` | `boolean` | No | `true` | — | When `true`, include `images` and the `video` object. When `false`, omit both and return a smaller metadata-only record. |
| `includeVideoUrl` | `boolean` | No | `false` | — | Paid add-on for video notes. When enabled together with `includeMedia`, return `video.bestVideoUrl` if available and emit one `video-url-result` unit. |
| `includeAllVideoQualities` | `boolean` | No | `true` | — | When the video URL add-on is enabled, include all detected video variants. Set to `false` to keep only `bestVideoUrl`. |

`includeVideoUrl` is effective only when `includeMedia` is also enabled. Setting `includeMedia: false` omits media output and disables the video URL add-on for that run.

#### Input examples

Metadata-only analysis:

```json
{
  "urls": ["6428b7be000000001300d335"],
  "includeMedia": false
}
```

Image galleries and video metadata, without a downloadable video URL:

```json
{
  "urls": [
    "https://www.xiaohongshu.com/explore/6428b7be000000001300d335",
    "https://xhslink.com/example"
  ],
  "includeMedia": true,
  "includeVideoUrl": false
}
```

Video note with downloadable URL and all detected qualities:

```json
{
  "urls": ["6a87dbad0000000005030ca4"],
  "includeMedia": true,
  "includeVideoUrl": true,
  "includeAllVideoQualities": true
}
```

### Short output example

```json
{
  "input": "6428b7be000000001300d335",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6428b7be000000001300d335",
  "success": true,
  "status": "success",
  "noteId": "6428b7be000000001300d335",
  "noteType": "image",
  "title": "Example note",
  "description": "Example description",
  "author": {
    "userId": "66ec990b000000001d031c8b",
    "nickname": "Example author",
    "profileUrl": "https://www.xiaohongshu.com/user/profile/66ec990b000000001d031c8b"
  },
  "engagement": { "likes": 123, "comments": 12, "collects": 45, "shares": 6 },
  "tags": [{ "id": "topic-id", "name": "Example topic" }],
  "images": [{ "index": 0, "url": "https://sns-webpic.example/image" }],
  "video": null,
  "scrapedAt": "2026-08-22T00:00:00.000Z"
}
```

### Output

Every submitted input receives one Dataset record. Successful canonical inputs contain structured note details. Invalid, unsupported, inaccessible, missing, or unparseable inputs contain a safe `error` object instead. Duplicate inputs copy the canonical result and add `duplicate` and `duplicateOf`.

**The Actor preserves source truth: missing optional fields are not invented, and an empty native title is never inferred from app share text.** An original empty title is returned as `"title": ""`.

RedNote/Xiaohongshu media URLs are normalized to HTTPS for recognized RedNote CDN hosts. They are still source CDN URLs and can expire.

### Complete output field reference

#### Core processing fields

| Field | Type | When present | Meaning |
|---|---|---|---|
| `input` | `string` | Always | Original submitted value. |
| `success` | `boolean` | Always | Whether note-detail extraction succeeded. |
| `status` | `string` | Always | Stable processing status; see **Status values**. |
| `normalizedUrl` | `string` | Success | Canonical explore URL without tracking/query parameters. |
| `noteId` | `string` | Success | 24-character RedNote/Xiaohongshu note ID. |
| `noteType` | `"video" \| "image" \| "unknown"` | Success | Normalized note type. |
| `scrapedAt` | ISO 8601 string | Success | UTC time when the result was created. |
| `duplicate` | `boolean` | Duplicate only | `true` when this input resolves to an earlier canonical input in the same run. |
| `duplicateOf` | `string` | Duplicate only | Original input value of the first canonical record. |
| `error` | `object` | Failure | Safe machine-readable `code` and user-facing `message`. |

#### Note content and timestamps

| Field | Type | When present | Meaning |
|---|---|---|---|
| `title` | `string` | Success | Native note title. May be an empty string. |
| `description` | `string` | Success | Native note description/caption. May be empty. |
| `createdAt` | `integer` | When available | Source creation time as Unix milliseconds. |
| `createdAtIso` | ISO 8601 string | When `createdAt` is valid | UTC representation of `createdAt`. |
| `updatedAt` | `integer` | When available | Source update time as Unix milliseconds. |
| `updatedAtIso` | ISO 8601 string | When `updatedAt` is valid | UTC representation of `updatedAt`. |
| `tags` | `object[]` | Success | Note topics/tags. Timestamp-style moment markers are excluded. |
| `tags[].id` | `string` | When available | Source tag identifier. |
| `tags[].name` | `string` | For each tag | Tag name. |

#### Author and engagement

| Field | Type | When present | Meaning |
|---|---|---|---|
| `author` | `object` | Success | Public author fields included with the note. |
| `author.userId` | `string` | Success | Author user ID; may be empty when absent. |
| `author.nickname` | `string` | Success | Display name; may be empty. |
| `author.avatarUrl` | `string` | When available | Author avatar CDN URL. |
| `author.profileUrl` | `string \| null` | Success | Locally generated public profile URL when `userId` exists; otherwise `null`. |
| `author.redId` | `string` | When available | Public Red ID included in the source. |
| `author.verified` | `boolean` | When available | Verification flag included in the source. |
| `engagement` | `object` | Success | Normalized engagement counters. |
| `engagement.likes` | `integer` | Success | Like count. |
| `engagement.comments` | `integer` | Success | Comment count. |
| `engagement.collects` | `integer` | Success | Collection/save count. |
| `engagement.shares` | `integer` | Success | Share count. |

#### Images

The entire `images` field is omitted when `includeMedia` is `false`.

| Field | Type | When present | Meaning |
|---|---|---|---|
| `images` | `object[]` | `includeMedia: true` | Ordered image gallery. May be empty. |
| `images[].index` | `integer` | For each image | Zero-based source order. |
| `images[].url` | `string` | For each image | Selected image URL. |
| `images[].width` / `height` | `number` | When available | Image dimensions in pixels. |
| `images[].urlDefault` | `string` | When available | Source default image URL. |
| `images[].variants` | `object[]` | When available | Alternate image representations. |
| `images[].variants[].url` | `string` | For each variant | Variant URL. |
| `images[].variants[].width` / `height` | `number` | When available | Variant dimensions in pixels. |
| `images[].variants[].format` | `string` | When available | Source format or image-scene label. |

#### Video

The entire `video` field is omitted when `includeMedia` is `false`. With media enabled, image notes return `video: null`.

| Field | Type | When present | Meaning |
|---|---|---|---|
| `video` | `object \| null` | `includeMedia: true` | Video metadata for video notes; `null` for image notes. |
| `video.durationSeconds` | `number` | Video note | Duration in seconds; `0` when unavailable. |
| `video.coverUrl` | `string` | When available | Video cover image URL. |
| `video.bestVideoUrl` | `string` | Add-on enabled and URL found | Selected downloadable/playable video URL. |
| `video.variants` | `object[]` | Add-on and all qualities enabled | Detected stream variants. May be empty. |
| `video.variants[].codec` | `"h264" \| "h265" \| "av1" \| "unknown"` | For each variant | Video codec. |
| `video.variants[].url` | `string` | For each variant | Direct stream URL. |
| `video.variants[].width` / `height` | `number` | When available | Video dimensions in pixels. |
| `video.variants[].duration` | `number` | When available | Duration in seconds. |
| `video.variants[].bitrate` | `number` | When available | Source bitrate value. |
| `video.variants[].sizeBytes` | `number` | When available | Source-reported size in bytes. |
| `video.variants[].qualityLabel` | `string` | When available | Source quality label. |

### Status values

Only statuses reachable from the Note Detail processing path are listed here.

| Status | Meaning | Output behavior | Charged? |
|---|---|---|---:|
| `success` | A valid note was parsed and normalized. | Structured note result. Duplicate success records may add `duplicate`/`duplicateOf`. | One canonical `note-detail-result`; optional video URL unit when returned. |
| `invalid_input` | Input was empty, malformed, or could not become a note identity. | `success: false` with `error`. | No |
| `unsupported_url` | Domain, protocol, or Xiaohongshu path is unsupported. | `success: false` with `error`. | No |
| `short_link_resolution_failed` | A supported short link could not resolve to a valid destination. | `success: false` with `error`. | No |
| `note_not_found` | The note was missing or no longer publicly accessible. | `success: false` with `error`. | No |
| `access_denied` | The public note request was denied. | `success: false` with `error`. | No |
| `page_fetch_failed` | Note retrieval failed after retries or returned an unusable response. | `success: false` with `error`. | No |
| `parse_failed` | A response was received but did not contain valid note data in a supported structure. | `success: false` with `error`. | No |
| `internal_error` | An unexpected processing error occurred. | `success: false` with a safe generic error. | No |

#### Error codes

| Error code | Status | Meaning |
|---|---|---|
| `EMPTY_INPUT` | `invalid_input` | Input was empty. |
| `URL_NOT_FOUND` | `invalid_input` | Text did not contain a supported URL or note ID. |
| `INVALID_URL` | `invalid_input` | The extracted URL could not be parsed. |
| `INPUT_REQUIRES_RESOLVABLE_URL` | `invalid_input` | Input could not become a public note identity. |
| `UNSUPPORTED_PROTOCOL` | `unsupported_url` | URL protocol is unsupported. |
| `UNSUPPORTED_DOMAIN` | `unsupported_url` | URL is not on a supported RedNote/Xiaohongshu domain. |
| `UNSUPPORTED_PATH` | `unsupported_url` | Xiaohongshu URL is not a supported note path. |
| `SHORT_LINK_RESOLUTION_FAILED` | `short_link_resolution_failed` | Short-link redirect failed or returned an invalid destination. |
| `NOTE_NOT_FOUND` | `note_not_found` | Note data was not found or is no longer publicly accessible. |
| `ACCESS_DENIED` | `access_denied` | Public note request was denied. |
| `PAGE_FETCH_FAILED` | `page_fetch_failed` | Public note page could not be fetched after retries. |
| `INITIAL_STATE_NOT_FOUND` | `parse_failed` | Expected public note data was absent from the page. |
| `INITIAL_STATE_INVALID` | `parse_failed` | Public page state was incomplete or invalid. |
| `NOTE_DATA_INVALID` | `parse_failed` | Note data had an unsupported structure. |
| `INTERNAL_ERROR` | `internal_error` | Unexpected error hidden behind a safe generic message. |

### Output examples

#### Image note

```json
{
  "input": "6a840ef900000000270231e6",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a840ef900000000270231e6",
  "success": true,
  "status": "success",
  "noteId": "6a840ef900000000270231e6",
  "noteType": "image",
  "title": "",
  "description": "Example image-note description",
  "author": { "userId": "", "nickname": "Example author", "profileUrl": null },
  "engagement": { "likes": 0, "comments": 0, "collects": 0, "shares": 0 },
  "tags": [],
  "images": [
    { "index": 0, "url": "https://sns-webpic.example/image-1" },
    { "index": 1, "url": "https://sns-webpic.example/image-2" }
  ],
  "video": null,
  "scrapedAt": "2026-08-22T00:00:00.000Z"
}
```

#### Video note with the optional downloadable URL

```json
{
  "input": "6a87dbad0000000005030ca4",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "success",
  "noteId": "6a87dbad0000000005030ca4",
  "noteType": "video",
  "title": "Example video note",
  "description": "Example description",
  "createdAt": 1766571252000,
  "createdAtIso": "2025-12-24T10:14:12.000Z",
  "updatedAt": 1766571253000,
  "updatedAtIso": "2025-12-24T10:14:13.000Z",
  "author": {
    "userId": "66ec990b000000001d031c8b",
    "nickname": "Example author",
    "profileUrl": "https://www.xiaohongshu.com/user/profile/66ec990b000000001d031c8b"
  },
  "engagement": { "likes": 1200, "comments": 20, "collects": 80, "shares": 10 },
  "tags": [{ "id": "topic-id", "name": "Example topic" }],
  "images": [{ "index": 0, "url": "https://sns-webpic.example/cover" }],
  "video": {
    "durationSeconds": 56,
    "coverUrl": "https://sns-webpic.example/cover",
    "bestVideoUrl": "https://sns-video.example/video.mp4",
    "variants": [
      {
        "codec": "h264",
        "url": "https://sns-video.example/video.mp4",
        "width": 1080,
        "height": 1920,
        "duration": 56
      }
    ]
  },
  "scrapedAt": "2026-08-22T00:00:00.000Z"
}
```

#### Duplicate input

```json
{
  "input": "https://www.xiaohongshu.com/discovery/item/6a840ef900000000270231e6",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a840ef900000000270231e6",
  "success": true,
  "status": "success",
  "noteId": "6a840ef900000000270231e6",
  "noteType": "image",
  "title": "Example note",
  "description": "Example description",
  "author": { "userId": "user-id", "nickname": "Example author", "profileUrl": "https://www.xiaohongshu.com/user/profile/user-id" },
  "engagement": { "likes": 10, "comments": 2, "collects": 3, "shares": 1 },
  "tags": [],
  "images": [],
  "video": null,
  "duplicate": true,
  "duplicateOf": "6a840ef900000000270231e6",
  "scrapedAt": "2026-08-22T00:00:00.000Z"
}
```

#### Missing or inaccessible note

```json
{
  "input": "https://www.xiaohongshu.com/explore/69f1df66000000003601fe34",
  "success": false,
  "status": "note_not_found",
  "error": {
    "code": "NOTE_NOT_FOUND",
    "message": "The RedNote note could not be found or is no longer publicly accessible."
  }
}
```

### API usage

The real Actor slug is `lance_api/rednote-note-detail-scraper-api`.

#### JavaScript

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: process.env.APIFY_TOKEN });
const run = await client.actor('lance_api/rednote-note-detail-scraper-api').call({
    urls: ['6428b7be000000001300d335'],
    includeMedia: true,
    includeVideoUrl: false,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items.map(({ noteType, title, images, video, status }) => ({
    noteType, title, imageCount: images?.length, video, status,
})));
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])
run = client.actor("lance_api/rednote-note-detail-scraper-api").call(run_input={
    "urls": ["6428b7be000000001300d335"],
    "includeMedia": True,
    "includeVideoUrl": False,
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
for item in items:
    print({
        "noteType": item.get("noteType"),
        "title": item.get("title"),
        "imageCount": len(item.get("images", [])),
        "video": item.get("video"),
        "status": item.get("status"),
    })
```

#### cURL

This synchronous endpoint runs the Actor and returns its default Dataset items:

```bash
curl -X POST \
  'https://api.apify.com/v2/acts/lance_api~rednote-note-detail-scraper-api/run-sync-get-dataset-items?format=json&clean=true' \
  -H "Authorization: Bearer ${APIFY_TOKEN}" \
  -H 'Content-Type: application/json' \
  -d '{
    "urls": ["6428b7be000000001300d335"],
    "includeMedia": true,
    "includeVideoUrl": false
  }'
```

### 💰 Simple, transparent pricing

Pricing uses a base result plus an optional video URL add-on:

| Billable result | Event | Standard price | Per 1,000 | Lowest eligible price | Lowest per 1,000 |
|---|---|---:|---:|---:|---:|
| Successfully parsed note | `note-detail-result` | $0.020 | $20 | $0.017 | $17 |
| Successfully returned downloadable video URL | `video-url-result` | $0.020 | $20 | $0.017 | $17 |

**Note detail extraction starts from $17 per 1,000 successful notes with the lowest eligible Apify Store rate. Downloadable video URL lookup also starts from $17 per 1,000 successful URLs.** The standard rate is $20 per 1,000 for each result type. Check the Actor's **Pricing** tab for the current plan-specific rate.

Keep `includeVideoUrl` off when note metadata, image galleries, cover, and duration are enough. Enable it only when you need a downloadable video URL, so you avoid unnecessary video URL charges.

Billing boundaries:

- A valid canonical note emits one `note-detail-result`, whether `includeMedia` is on or off.
- Invalid input, unsupported URLs, failed short links, inaccessible or missing notes, fetch failures, parse failures, and internal failures emit no result event.
- Duplicate-only records do not add another charge; the canonical note is billed once.
- `includeVideoUrl: false` emits no `video-url-result`.
- `includeMedia: false` disables the video URL add-on and emits no `video-url-result`.
- If `includeVideoUrl: true` but no downloadable URL is returned, no `video-url-result` is emitted. If the optional lookup causes the whole note resolution to fail, neither result event is emitted.
- Enabling the option for an image note emits only the base note event.
- One video note emits at most one `video-url-result`, even when multiple variants are returned.
- There is no Actor-specific start event in the current billing code.

### Use cases

- **Content research** — Collect native titles, descriptions, tags, authors, timestamps, and engagement for qualitative or quantitative review.
- **Creator and competitor monitoring** — Feed public note records into dashboards and compare observable content and engagement over time.
- **Media catalogs** — Build structured indexes of image galleries, video covers, durations, and optional downloadable video URLs.
- **Trend and product research** — Use returned topics, captions, engagement, and media references as inputs to downstream analysis.
- **Moderation and review workflows** — Send one normalized record per submitted note into human-review queues while preserving failure status and source identity.
- **Dataset enrichment** — Add canonical RedNote note IDs, author profiles, engagement counters, and media metadata to existing datasets.
- **AI and RAG context** — Supply structured public-note data to downstream LLM, retrieval, summarization, or classification workflows.
- **API automation** — Run the Actor from Apify API, n8n, Make, Zapier, MCP clients, or scheduled data pipelines.

### How it works

1. Parse each submitted note ID, full URL, short link, Markdown link, or share text.
2. Normalize supported inputs to a canonical note identity and URL.
3. Group equivalent inputs so the same note is resolved once per run.
4. Retrieve and normalize the public note detail.
5. Include or omit image/video metadata according to `includeMedia`.
6. Optionally resolve and return a downloadable video URL when requested.
7. Save one ordered Dataset record for every submitted input, including duplicates and failures.

### 🤖 Use with AI agents

Use this Actor through the Apify MCP Server from ChatGPT, Claude, Cursor, Codex, or another MCP-compatible client. MCP runs use the same Actor input, output, and pricing as normal Apify runs.

Example prompt:

> Use the Apify Actor `lance_api/rednote-note-detail-scraper-api` to retrieve structured details for these public RedNote/Xiaohongshu notes. Return the note type, native title, author, engagement, tags, images or video metadata, and processing status. Request downloadable video URLs only for video notes when needed.

### FAQ

#### Which RedNote/Xiaohongshu inputs are supported?

Use a 24-character note ID, a supported `/explore/`, `/discovery/item/`, or `/red_video/` URL, an `xhslink.com`/`xhslink.cn` short link, a Markdown-wrapped supported URL, or app share text containing one supported URL.

#### Can I submit a note ID directly?

Yes. A 24-character hexadecimal note ID is the preferred input and is converted to a canonical explore URL.

#### Can I process 1,000 notes at once?

Yes. `urls` accepts 1–1,000 items. Each submitted item receives one Dataset record.

#### Are duplicate notes charged twice?

No. Equivalent notes are resolved and billed once. Additional duplicate records contain `duplicate: true` and `duplicateOf`.

#### What is the difference between `includeMedia` and `includeVideoUrl`?

`includeMedia` controls whether `images` and the `video` metadata object are returned. `includeVideoUrl` is a paid add-on inside that media output and controls `video.bestVideoUrl`; it does not replace `includeMedia`.

#### Does enabling `includeVideoUrl` always return a video URL?

No. It is meaningful only for video notes and depends on a downloadable stream being available. No video URL event is charged when a URL is not returned.

#### Are media URLs permanent?

No. They are RedNote/Xiaohongshu CDN URLs returned at scrape time, and some contain temporary signatures. Download or copy required media to your own authorized storage after retrieval.

#### Can this Actor process private notes?

No. It is designed for publicly accessible notes and does not automate login or bypass access controls.

#### What happens when a note is deleted or inaccessible?

The Actor returns a failure record such as `note_not_found` or `access_denied`. The failed input does not emit a note-detail result charge.

#### What does `duplicateOf` mean?

It contains the original input value of the first canonical record for the same note in the current run.

#### How am I charged?

A successful canonical note emits one base result event. A requested and successfully returned downloadable video URL emits one additional event. Failed and duplicate-only records are not charged.

#### Can AI agents use this Actor?

Yes. Use the real slug `lance_api/rednote-note-detail-scraper-api` through the Apify API or Apify MCP Server.

### Limitations

- Public RedNote/Xiaohongshu notes only; private content and access-control bypass are not supported.
- Deleted, removed, unavailable, or permission-restricted notes can return failure records.
- Profile URLs, search URLs, and unsupported note paths are rejected.
- Short links depend on a successful redirect and can expire or stop resolving.
- `xsec_token` values are short-lived and can expire or become invalid.
- CDN image, cover, avatar, and video URLs may expire and are not permanent storage links.
- Optional fields are omitted when they are absent or invalid in the source response.
- Engagement and other source values reflect what was available at scrape time.
- RedNote/Xiaohongshu response structures can change and temporarily affect extraction.
- The Actor returns media URLs; it does not permanently host media files.

### Public data and responsible use

Use this Actor only for lawful processing of public data. Follow RedNote/Xiaohongshu terms, Apify terms, copyright rules, privacy obligations, and applicable law. Do not use it for harassment, spam, unlawful profiling, attempts to obtain non-public information, or attempts to bypass access controls. You are responsible for how you collect, store, share, and use the returned data and media URLs.

### Support

For help, open an issue on the Actor page or email **lanceapi2026@hotmail.com**.

Include:

- Run ID
- A non-sensitive note ID or public URL
- Returned `status` and `error.code`
- Expected result versus actual result

Do not send Apify tokens, cookies, session credentials, sensitive `xsec_token` values, API keys, passwords, or other secrets.

# Actor input Schema

## `urls` (type: `array`):

Add 1–1000 notes. A 24-character hexadecimal note ID is preferred. Find it after /explore/, /discovery/item/, or /red\_video/ in a Xiaohongshu URL, or in the noteId/id field of a search or user-notes result. Full xiaohongshu.com links, xhslink.com/xhslink.cn short links, and complete app share text are also supported.

## `xsecToken` (type: `string`):

Optional short-lived signed xsec\_token from the same public note. Providing it improves reliability for geo-restricted or sensitive notes and keeps resolution on the direct RedNote path. Leave blank if unavailable; inputs without a token use the fallback service. For batches, tokens are note-specific, so prefer placing each token in its own URL unless this run contains one note.

## `includeMedia` (type: `boolean`):

Keep this on for complete image galleries and video stream details. Turn it off for lighter metadata-only workflows.

## `includeVideoUrl` (type: `boolean`):

Optional paid add-on for video notes. When enabled, the Actor obtains and returns a downloadable video URL and charges one additional successful URL unit: $20 per 1,000 on Free, down to $17 per 1,000 on Business. When disabled, note details, images, video cover, and duration are still returned without this add-on.

## `includeAllVideoQualities` (type: `boolean`):

When downloadable video URL is enabled, return all detected stream variants in addition to the best compatible URL.

## Actor input object example

```json
{
  "urls": [
    "6428b7be000000001300d335"
  ],
  "includeMedia": true,
  "includeVideoUrl": false,
  "includeAllVideoQualities": true
}
```

# Actor output Schema

## `results` (type: `string`):

No description

## `summary` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "urls": [
        "6428b7be000000001300d335"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("lance_api/rednote-note-detail-scraper-api").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "urls": ["6428b7be000000001300d335"] }

# Run the Actor and wait for it to finish
run = client.actor("lance_api/rednote-note-detail-scraper-api").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "urls": [
    "6428b7be000000001300d335"
  ]
}' |
apify call lance_api/rednote-note-detail-scraper-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lance_api/rednote-note-detail-scraper-api"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/5ixF7fkqwmdnkjpLU/builds/o0RI9P3oAhcCVQFxF/openapi.json
