# RedNote Transcript & Subtitle API – Xiaohongshu Video to Text (`lance_api/xiaohongshu-video-ai-transcript-scraper-api`) Actor

Extract native subtitles and convert public RedNote (Xiaohongshu/XHS) videos to text, with AI transcription used only when needed. Get timestamped segments, SRT/VTT, optional translation, video URLs, and note metadata. A matching xsec\_token is required.

- **URL**: https://apify.com/lance\_api/xiaohongshu-video-ai-transcript-scraper-api.md
- **Developed by:** [LanceAPI](https://apify.com/lance_api) (community)
- **Categories:** Social media, AI, Developer tools
- **Stats:** 1 total users, 0 monthly users, 0.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 1,000 successful videos

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 AI Transcript & Subtitle API – Xiaohongshu Video to Text

**Use native Xiaohongshu subtitles first, fall back to AI transcription only when needed, and return clean text, timestamped segments, SRT, or WebVTT—with optional translation.**

This version accepts complete public Xiaohongshu video-note URLs containing their matching `xsec_token`. Process up to 1,000 URLs per run and receive one structured Dataset record per input.

When a usable native subtitle exists, the Actor skips AI speech recognition automatically. Pay only for successful note resolution, AI transcription when actually used, and text translation when actually needed.

- Native subtitles first for faster, lower-cost results
- Optional AI fallback when no usable native subtitle exists
- One transcript, four output formats: plain text, timestamped segments, SRT, and WebVTT
- Optional translation preserves the original transcript
- AI-minute visibility whenever an AI transcription charge occurs, plus translation-unit visibility on completed translations
- Included note metadata and downloadable video media details when available
- Batch processing with isolated failures and duplicate-aware billing

### ✨ Key features

#### Native subtitles first

Use the video's own Xiaohongshu subtitle when available. Native success avoids AI transcription and its started-minute charge.

#### AI transcript fallback

When no native subtitle can be used, AI speech recognition runs only if `allowAiTranscript` is enabled.

#### Four transcript formats from one result

Return plain text, timestamped segments, SRT subtitles, and WebVTT subtitles from the same transcription. Selecting multiple formats does not create additional AI-minute charges.

#### Optional translation that preserves the source

Translate the completed speech transcript to a selected language while keeping the original `transcript` unchanged. Translation never overwrites the source-language result.

#### Structured note and media context

Get available note metadata and video media details alongside the transcript without separate metadata or video-URL switches.

#### Batch up to 1,000 inputs

Process large lists with bounded concurrency. One failed, deleted, inaccessible, image-only, or silent item does not stop the remaining inputs.

#### Duplicate-aware processing and billing

Every submitted input receives a Dataset record. Equivalent notes are processed and charged only once; later records are marked with `duplicate` and `duplicateOf`.

### 🚀 Quick start

Use the Actor in Apify Console:

1. Paste a complete Xiaohongshu video-note URL into `urls`.
2. Click **Start**.
3. Open the run's **Dataset**.
4. Read `transcript.text`.
5. Add subtitle formats or enable translation when needed.

The smallest valid input is:

```json
{
  "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"]
}
```

By default, the Actor returns `text` and `segments`, prefers native subtitles, allows AI fallback, includes available note and media details, and does not translate.

### Supported RedNote / Xiaohongshu inputs

The Actor accepts complete HTTP or HTTPS Xiaohongshu video-note URLs in these forms:

- `https://www.xiaohongshu.com/explore/{noteId}?xsec_token=...`
- `https://www.xiaohongshu.com/discovery/item/{noteId}?xsec_token=...`
- `https://www.xiaohongshu.com/red_video/{noteId}?xsec_token=...`

The note ID is the 24-character hexadecimal value after `/explore/`, `/discovery/item/`, or `/red_video/` in the complete URL.

Profile URLs, user pages, search pages, and unrelated Xiaohongshu pages are unsupported. Image-only notes can be submitted but cannot produce a transcript and return `unsupported_note_type`.

Supported paths are normalized to a canonical explore URL. Duplicate detection uses the canonical note ID.

#### Complete URL requirement

A complete URL must contain the matching `xsec_token` for its video note. Open the public note from Xiaohongshu search, feed, or sharing and copy the complete browser URL. There is no separate run-level token input.

Request URLs are sanitized before logging. The Dataset `input` field preserves the submitted URL, while `normalizedUrl` omits query parameters.

### Input

| Field | Type | Required | Default | Limits | Description |
|---|---|---:|---|---|---|
| `urls` | `string[]` | Yes | None | 1–1,000 items | Complete supported video-note URLs containing a valid matching `xsec_token`. Items are normalized and deduplicated by canonical note identity. |
| `formats` | `string[]` | No | `['text', 'segments']` | Unique values from `text`, `segments`, `srt`, `vtt` | Select transcript and translation representations. An empty array also falls back to `text` and `segments`. |
| `allowAiTranscript` | `boolean` | No | `true` | — | Use AI speech recognition only when no usable native subtitle is available. Native subtitles are always preferred. |
| `translate` | `boolean` | No | `false` | — | Add a translated copy while preserving the original transcript. No translation service or translation charge is used when disabled. |
| `targetLanguage` | `string` | No | `en` | One supported dropdown value | Translation target. Used only when `translate` is `true`; users select a language name in the Console. |

The target-language dropdown includes English, Simplified and Traditional Chinese, Japanese, Korean, Spanish, French, German, Portuguese, Italian, Dutch, Russian, Ukrainian, Polish, Czech, Swedish, Danish, Finnish, Norwegian, Turkish, Arabic, Hebrew, Hindi, Bengali, Indonesian, Malay, Thai, Vietnamese, Filipino, Greek, Romanian, and Hungarian.

Available note metadata and video media details are included automatically.

Need subtitles? Add `srt` or `vtt` to `formats`.

Need translation? Enable it only when needed; the original transcript remains available.

### Input examples

#### All transcript formats

```json
{
  "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"],
  "formats": ["text", "segments", "srt", "vtt"],
  "allowAiTranscript": true
}
```

#### Translate to English

```json
{
  "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"],
  "formats": ["text", "segments", "srt"],
  "allowAiTranscript": true,
  "translate": true,
  "targetLanguage": "en"
}
```

#### Plain transcript with included metadata and media

```json
{
  "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"],
  "formats": ["text"]
}
```

#### Native subtitles only, without AI fallback

```json
{
  "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"],
  "formats": ["text", "srt"],
  "allowAiTranscript": false,
  "translate": false
}
```

#### Batch input

```json
{
  "urls": [
    "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=TOKEN_FOR_FIRST_NOTE",
    "https://www.xiaohongshu.com/red_video/6a84418900000000270212b1?xsec_token=TOKEN_FOR_SECOND_NOTE",
    "https://www.xiaohongshu.com/explore/6a840ef900000000270231e6?xsec_token=TOKEN_FOR_THIRD_NOTE"
  ],
  "formats": ["text"]
}
```

### Transcript formats

All selected formats are generated from the same completed transcript, whether it comes from a native subtitle or AI speech recognition. Asking for four formats does not create additional AI transcription.

#### `text`

Plain transcript text for LLM prompts, search, indexing, summaries, and content databases.

#### `segments`

Timestamped speech segments for quote extraction, timeline analysis, editing, and synchronization. `start` and `end` are measured in seconds.

#### `srt`

SubRip subtitle text generated locally from the returned segments. Timestamps use `HH:MM:SS,mmm`.

#### `vtt`

WebVTT subtitle text generated locally from the same segments. Suitable for web players and accessibility workflows; timestamps use `HH:MM:SS.mmm`.

### Translation

Translation is optional and disabled by default.

- The source-language result always remains in `transcript`.
- The translated copy is returned in `translation` and never overwrites `transcript`.
- `translation.language` is the selected target language.
- Translation uses the same selected `formats`, including translated text, segments, SRT, and VTT when requested.
- Translated segments preserve the original segment timestamps and order.
- Only speech transcript content is translated; note title, caption, author, tags, and other metadata are not translated.
- Long transcripts are processed in ordered batches while preserving segment order.
- If Xiaohongshu already provides a native subtitle matching the target language, that track is reused without a translation-service charge.
- Translation works the same whether the transcript came from a native subtitle or AI speech recognition.
- If translation fails after transcription succeeds, the result remains successful with `status: "partial_success"`, the original transcript is kept, and `translation` is `null`.
- A failed translation does not emit a translation charge.
- When both the recognized language and target are English, the original transcript is reused with language `en`, with no translation charge.

Successful actual translation is billed from the original transcript's Unicode character count:

```text
translationUnits = max(1, ceil(originalTranscriptCharacters / 1,000))
```

Examples: 1–1,000 characters use 1 unit; 1,001–2,000 use 2 units; 2,001–3,000 use 3 units. English-to-English reuse uses 0 units.

### Short output example

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "success",
  "noteId": "6a87dbad0000000005030ca4",
  "media": {
    "durationSeconds": 61,
    "coverUrl": "https://sns-webpic.example/cover.webp",
    "nativeSubtitles": [{ "key": "source", "language": "zh-CN", "url": "https://sns-subtitle.example/source.srt", "isSource": true }]
  },
  "transcript": {
    "source": "native_subtitle",
    "language": "zh-CN",
    "text": "Example transcript text.",
    "segments": [
      { "start": 0, "end": 3.4, "text": "Example transcript text." }
    ]
  },
  "translation": null,
  "scrapedAt": "2026-08-22T03:00:00.000Z"
}
```

### Output

Results are written to the default Dataset in input order. Every submitted input receives one record, including failures and duplicates.

`success: true` includes native or AI transcript success, AI `no_speech`, and `no_transcript` when the user disabled AI fallback and no native subtitle could be used.

Available note metadata and video media details are included automatically. Transcript representations follow `formats`, while translation is returned only when enabled and successfully completed. Unavailable fields are omitted unless the documented behavior uses `null`, such as `translation`.

### Complete output field reference

#### Core processing

| Field | Type | Availability | Meaning |
|---|---|---|---|
| `input` | `string` | Always | Exact submitted input value. |
| `normalizedUrl` | `string` | Processed transcript results | Canonical explore URL without tracking parameters. |
| `success` | `boolean` | Always | `true` for completed transcript processing, including `no_speech` and `partial_success`. |
| `status` | `string` | Always | Stable overall outcome. See **Status values**. |
| `noteId` | `string` | Processed transcript results | Canonical RedNote/Xiaohongshu note ID. |
| `scrapedAt` | `string` | Processed transcript results | UTC ISO 8601 result timestamp. |

#### Content metadata

The `content` object is included in successful transcript records.

| Field | Type | Availability | Meaning |
|---|---|---|---|
| `content.title` | `string` | Successful transcript results | Native note title; can be an empty string. |
| `content.description` | `string` | Successful transcript results | Native note description/caption. |
| `content.author.userId` | `string` | Successful transcript results | Xiaohongshu user ID; can be empty if unavailable. |
| `content.author.nickname` | `string` | Successful transcript results | Author display name. |
| `content.author.avatarUrl` | `string` | When available | Direct avatar URL. |
| `content.author.profileUrl` | `string \| null` | Successful transcript results | Locally generated public profile URL, or `null` without a user ID. |
| `content.author.redId` | `string` | When available | Source-provided Red ID. |
| `content.author.verified` | `boolean` | When available | Source-provided verification flag. |
| `content.engagement.likes` | `number` | Successful transcript results | Normalized like count. |
| `content.engagement.comments` | `number` | Successful transcript results | Normalized comment count. |
| `content.engagement.collects` | `number` | Successful transcript results | Normalized collection/save count. |
| `content.engagement.shares` | `number` | Successful transcript results | Normalized share count. |
| `content.tags` | `object[]` | Successful transcript results | Native topic/tag list. |
| `content.tags[].id` | `string` | When available | Source tag ID. |
| `content.tags[].name` | `string` | Per tag | Tag name. |

#### Media

| Field | Type | Availability | Meaning |
|---|---|---|---|
| `media.durationSeconds` | `number` | Processed transcript results | Source media duration in seconds. |
| `media.coverUrl` | `string` | When available | Direct note/video cover URL. |
| `media.videoUrl` | `string` | When available | Downloadable video URL included with the transcript result. |
| `media.nativeSubtitles` | `object[]` | Processed video results | Normalized native subtitle tracks exposed by Xiaohongshu. May be empty. |
| `media.nativeSubtitles[].key` | `string` | Per native track | Subtitle group key such as `source`, `zh-CN`, or `en-US`. |
| `media.nativeSubtitles[].language` | `string` | When available | Track language reported by Xiaohongshu. |
| `media.nativeSubtitles[].url` | `string` | Per native track | Signed native subtitle URL; it can expire. |
| `media.nativeSubtitles[].format` | `string \| number` | When available | Source-provided subtitle format value. |
| `media.nativeSubtitles[].type` | `string \| number` | When available | Source-provided subtitle type value. |
| `media.nativeSubtitles[].isSource` | `boolean` | Per native track | `true` for the source-language group. |

The Actor returns URLs; it does not permanently host the source video.

#### Transcript

| Field | Type | Availability | Meaning |
|---|---|---|---|
| `transcript.source` | `string` | Transcript present | `native_subtitle` or `ai_transcription`. |
| `transcript.language` | `string` | When detected | Recognized source-language code. |
| `transcript.text` | `string` | When `text` selected | Plain source-language transcript. Can be empty for `no_speech`. |
| `transcript.segments` | `object[]` | When `segments` selected | Timestamped source-language segments. |
| `transcript.segments[].start` | `number` | Per segment | Start time in seconds. |
| `transcript.segments[].end` | `number` | Per segment | End time in seconds. |
| `transcript.segments[].text` | `string` | Per segment | Segment text. |
| `transcript.srt` | `string` | When `srt` selected | Locally generated SRT subtitle content. |
| `transcript.vtt` | `string` | When `vtt` selected | Locally generated WebVTT subtitle content. |

#### Translation

`translation` is `null` when translation is disabled, no transcript exists, `no_speech` is returned, or translation fails. When present, it follows the selected formats.

| Field | Type | Availability | Meaning |
|---|---|---|---|
| `translation.source` | `string` | Translation present | `native_subtitle` when a matching Xiaohongshu track is reused; otherwise `translation`. |
| `translation.language` | `string` | Translation present | Selected target-language code. |
| `translation.text` | `string` | `text` selected | Translated transcript text. |
| `translation.segments` | `object[]` | `segments` selected | Translated segments preserving source timestamps. |
| `translation.segments[].start` | `number` | Per segment | Original segment start in seconds. |
| `translation.segments[].end` | `number` | Per segment | Original segment end in seconds. |
| `translation.segments[].text` | `string` | Per segment | Translated segment text. |
| `translation.srt` | `string` | `srt` selected | SRT generated from translated segments. |
| `translation.vtt` | `string` | `vtt` selected | WebVTT generated from translated segments. |

#### Duplicate and error fields

| Field | Type | Availability | Meaning |
|---|---|---|---|
| `duplicate` | `boolean` | Duplicate inputs | `true` when the canonical note was already processed earlier in the run. |
| `duplicateOf` | `string` | Duplicate inputs | Original input value of the first matching record. |
| `error.code` | `string` | Failed or partial results | Stable machine-readable error code. |
| `error.message` | `string` | Failed or partial results | Safe user-facing explanation. |

### Status values

| Status | Meaning | Transcript | Translation | Billing |
|---|---|---|---|---|
| `success` | A native or AI transcript completed with content. | Present | Present or `null` | URL processing; AI minutes only when AI fallback runs; translation only when text translation runs |
| `no_speech` | Media was processed but no speech was detected. Valid processed result. | Empty selected fields | `null` | Base + AI minutes |
| `no_transcript` | No usable native subtitle was available and AI fallback was disabled. | `null` | `null` | URL processing only |
| `partial_success` | Transcript succeeded but optional translation failed. | Preserved | `null` | URL processing; AI minutes only if AI was used; no translation charge |
| `invalid_input` | Input was empty, malformed, or could not become a note URL. | None | None | No charge |
| `unsupported_url` | Domain, protocol, or Xiaohongshu path is unsupported. | None | None | No charge |
| `note_not_found` | Canonical input was valid, but the note was missing or unavailable. | None | None | No charge |
| `access_denied` | Canonical input was valid, but the public request was denied. | None | None | No charge |
| `page_fetch_failed` | Canonical input was valid, but note data retrieval failed. | None | None | No charge |
| `parse_failed` | Canonical input was valid, but returned note data could not be parsed. | None | None | No charge |
| `unsupported_note_type` | The note is image-only or otherwise not a video. | None | None | No charge |
| `media_not_found` | No native transcript succeeded and no usable AI speech media was available. | None | None | URL processing only |
| `transcription_failed` | Speech recognition could not start or complete. | None | None | Base; AI minutes only if media submission began |
| `transcription_timeout` | Speech recognition timed out after media submission. | None | None | Base + AI minutes |
| `internal_error` | Unexpected per-input processing error. | None | None | Depends on the completed processing stage |

Only statuses reachable in the current Transcript Actor are listed here.

### Error codes

| Error code | Status | Meaning |
|---|---|---|
| `EMPTY_INPUT` | `invalid_input` | The item was empty. |
| `URL_NOT_FOUND` | `invalid_input` | No supported note URL was found. |
| `XSEC_TOKEN_REQUIRED` | `invalid_input` | The full video-note URL did not include the required token. |
| `INVALID_URL` | `invalid_input` | Extracted URL syntax was invalid. |
| `INPUT_REQUIRES_RESOLVABLE_URL` | `invalid_input` | Input could not be converted into a public note URL. |
| `UNSUPPORTED_PROTOCOL` | `unsupported_url` | Protocol is not HTTP or HTTPS. |
| `UNSUPPORTED_DOMAIN` | `unsupported_url` | Domain is unsupported. |
| `UNSUPPORTED_PATH` | `unsupported_url` | URL is not a supported note page. |
| `NOTE_NOT_FOUND` | `note_not_found` | Note was missing or unavailable. |
| `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 state was missing. |
| `INITIAL_STATE_INVALID` | `parse_failed` | Public note state was incomplete or invalid. |
| `NOTE_DATA_INVALID` | `parse_failed` | Note data had an unexpected structure. |
| `NOT_A_VIDEO_NOTE` | `unsupported_note_type` | The note contains no video to transcribe. |
| `VIDEO_MEDIA_NOT_FOUND` | `media_not_found` | No usable public speech media was found. |
| `TRANSCRIPTION_FAILED` | `transcription_failed` | Speech recognition could not process the media. |
| `TRANSCRIPTION_TIMEOUT` | `transcription_timeout` | Speech recognition timed out. |
| `TRANSLATION_FAILED` | `partial_success` | Transcript succeeded, but optional translation failed. |
| `INTERNAL_ERROR` | `internal_error` | Unexpected per-input processing error. |

### Output examples

#### AI fallback transcript with all formats

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "success",
  "noteId": "6a87dbad0000000005030ca4",
  "media": {
    "durationSeconds": 61,
    "coverUrl": "https://sns-webpic.example/cover.webp"
  },
  "transcript": {
    "source": "ai_transcription",
    "language": "zh",
    "text": "大家好，今天我们来聊这个话题。",
    "segments": [
      { "start": 0, "end": 3.45, "text": "大家好，今天我们来聊这个话题。" }
    ],
    "srt": "1\n00:00:00,000 --> 00:00:03,450\n大家好，今天我们来聊这个话题。",
    "vtt": "WEBVTT\n\n00:00:00.000 --> 00:00:03.450\n大家好，今天我们来聊这个话题。"
  },
  "translation": null,
  "scrapedAt": "2026-08-22T03:00:00.000Z"
}
```

#### No speech

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "no_speech",
  "noteId": "6a87dbad0000000005030ca4",
  "media": { "durationSeconds": 61 },
  "transcript": {
    "source": "ai_transcription",
    "text": "",
    "segments": []
  },
  "translation": null,
  "scrapedAt": "2026-08-22T03:00:00.000Z"
}
```

`no_speech` is a valid processed result, not a system failure. AI minutes are charged because the media was processed for speech recognition.

#### No native transcript with AI fallback disabled

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "no_transcript",
  "noteId": "6a87dbad0000000005030ca4",
  "content": { "title": "Example video", "author": {}, "engagement": {}, "tags": [] },
  "media": { "durationSeconds": 61, "nativeSubtitles": [] },
  "transcript": null,
  "translation": null,
  "scrapedAt": "2026-08-24T03:00:00.000Z"
}
```

#### Translation success

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "success",
  "noteId": "6a87dbad0000000005030ca4",
  "media": { "durationSeconds": 61 },
  "transcript": {
    "source": "ai_transcription",
    "language": "zh",
    "text": "大家好，今天我们来聊这个话题。"
  },
  "translation": {
    "source": "translation",
    "language": "en",
    "text": "Hello everyone. Today we are discussing this topic."
  },
  "scrapedAt": "2026-08-22T03:00:00.000Z"
}
```

#### Translation failure with preserved transcript

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "partial_success",
  "noteId": "6a87dbad0000000005030ca4",
  "media": { "durationSeconds": 61 },
  "transcript": {
    "source": "ai_transcription",
    "language": "zh",
    "text": "大家好，今天我们来聊这个话题。"
  },
  "translation": null,
  "error": {
    "code": "TRANSLATION_FAILED",
    "message": "The transcript was created, but its optional translation could not be completed."
  },
  "scrapedAt": "2026-08-22T03:00:00.000Z"
}
```

#### Native subtitle with native target-language reuse

```json
{
  "success": true,
  "status": "success",
  "transcript": {
    "source": "native_subtitle",
    "language": "zh-CN",
    "text": "原生中文字幕"
  },
  "translation": {
    "source": "native_subtitle",
    "language": "en-US",
    "text": "Native English subtitle"
  }
}
```

No AI-minute or translation event is charged when both tracks come from Xiaohongshu native subtitles.

#### Included video media details

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "normalizedUrl": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4",
  "success": true,
  "status": "success",
  "noteId": "6a87dbad0000000005030ca4",
  "media": {
    "videoUrl": "https://sns-video.example/video.mp4",
    "durationSeconds": 61,
    "coverUrl": "https://sns-webpic.example/cover.webp"
  },
  "transcript": {
    "source": "ai_transcription",
    "language": "en",
    "text": "Example transcript."
  },
  "translation": null,
  "scrapedAt": "2026-08-22T03:00:00.000Z"
}
```

#### Image-only note

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a840ef900000000270231e6?xsec_token=...",
  "success": false,
  "status": "unsupported_note_type",
  "error": {
    "code": "NOT_A_VIDEO_NOTE",
    "message": "This RedNote post does not contain a video to transcribe."
  }
}
```

#### Invalid input

```json
{
  "input": "https://www.xiaohongshu.com/user/profile/example",
  "success": false,
  "status": "unsupported_url",
  "error": {
    "code": "UNSUPPORTED_PATH",
    "message": "This Xiaohongshu URL is not a supported note page."
  }
}
```

#### Missing or inaccessible note

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a67603c000000000503be3f?xsec_token=...",
  "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."
  }
}
```

#### Transcription timeout after media submission

```json
{
  "input": "https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=...",
  "success": false,
  "status": "transcription_timeout",
  "error": {
    "code": "TRANSCRIPTION_TIMEOUT",
    "message": "Speech recognition timed out."
  }
}
```

### API usage

The Actor slug is `lance_api/xiaohongshu-video-ai-transcript-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/xiaohongshu-video-ai-transcript-scraper-api').call({
  urls: ['https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN'],
  formats: ['text', 'segments'],
  translate: false,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
console.log(items[0]?.transcript?.text);
```

#### Python

```python
import os
from apify_client import ApifyClient

client = ApifyClient(os.environ["APIFY_TOKEN"])

run = client.actor("lance_api/xiaohongshu-video-ai-transcript-scraper-api").call(run_input={
    "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"],
    "formats": ["text", "segments"],
    "translate": False,
})

items = client.dataset(run["defaultDatasetId"]).list_items().items
print(items[0].get("transcript", {}).get("text"))
```

#### cURL

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

```bash
curl -X POST \
  "https://api.apify.com/v2/acts/lance_api~xiaohongshu-video-ai-transcript-scraper-api/run-sync-get-dataset-items?format=json" \
  -H "Authorization: Bearer $APIFY_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "urls": ["https://www.xiaohongshu.com/explore/6a87dbad0000000005030ca4?xsec_token=YOUR_TOKEN"],
    "formats": ["text", "segments"],
    "translate": false
  }'
```

In the returned JSON array, read `[0].transcript.text`.

### 💰 Simple, transparent pricing

Pay only for the processing you use: successful note resolution, AI transcription by started media minute when native subtitles cannot be used, and optional text translation by character volume.

RedNote note processing starts from **$0.003 per successful canonical note ($3 per 1,000)**, while AI transcription starts from **$0.002 per started media minute — $2 per 1,000 started media minutes** with eligible Apify Store discounts.

Optional translation starts from **$0.07 per started 1,000 Unicode characters**. The available video URL and note metadata are included with the successful note result.

A 1,600-character transcript uses 2 translation units: **$0.14** at the lowest eligible rate or **$0.20** at the standard Free rate.

Standard Free pricing is:

- Note processing: **$0.006 per successful canonical note — $6 per 1,000**
- AI transcription: **$0.005 per started media minute — $5 per 1,000 started media minutes**
- Translation: **$0.10 per started 1,000-character unit**

Check the Actor's **Pricing** tab for the current rate available to your Apify plan.

#### What triggers each charge?

- `url-processing`: once after a canonical public video note is successfully resolved and enters normal transcript processing, including native transcript and `no_transcript` results. Invalid inputs, inaccessible notes, and image-only notes are not charged this event.
- `ai-transcription-minute`: one unit for each started media minute after usable media is ready for speech recognition. `0:01`–`1:00` = 1 minute, `1:01`–`2:00` = 2 minutes, and 61 seconds = 2 minutes. Once submitted, silence, music, no detected speech, timeout, or recognition failure can still consume the charged AI minutes.
- `translation-1k-characters`: charged only after actual text translation succeeds, using the original transcript's Unicode character count rounded up to started 1,000-character units. Same-language reuse, matching native subtitle reuse, and failed translation use 0 units.

If a usable native subtitle is available, the Actor skips AI transcription automatically, so no `ai-transcription-minute` event is emitted.

Duplicate-only records do not repeat any of the canonical item's charges. **Choose one transcript format or all four—the AI transcription charge is the same.**

### Use cases

- **RedNote video transcription:** Convert spoken public video content into reusable text.
- **Subtitle generation:** Create SRT or WebVTT content for editing, review, or accessible playback.
- **Content research:** Build timestamped datasets for reviewing public RedNote/Xiaohongshu videos.
- **Creator and competitor research:** Collect authorized public speech and metadata for downstream analysis.
- **Searchable transcript databases:** Index transcript text and segments in your own search system.
- **International content analysis:** Add optional translated transcripts while retaining the original language.
- **AI and RAG workflows:** Supply source transcripts and timestamps as context for downstream LLM systems.
- **API automation:** Connect video-to-text processing to n8n, Make, Zapier, backend jobs, or data pipelines.

### How it works

1. Resolve and validate the public RedNote video.
2. Use the video's native subtitle when one can be downloaded and parsed.
3. If no usable native subtitle exists, optionally fall back to AI speech recognition.
4. Generate the selected text, segments, SRT, and WebVTT representations from one unified transcript.
5. Optionally translate the completed native or AI transcript while preserving timestamps.
6. Include available video, native subtitle, and structured note metadata.
7. Save one normalized Dataset record per submitted input.

### 🤖 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 pricing as normal Apify runs.

Example prompt:

> Use the Apify Actor `lance_api/xiaohongshu-video-ai-transcript-scraper-api` to transcribe these public RedNote/Xiaohongshu video notes. Return the original language, plain transcript text, timestamped segments, and SRT subtitles. Translate to English only when requested.

### FAQ

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

Supported note paths are `/explore/{id}`, `/discovery/item/{id}`, and `/red_video/{id}`.

#### Can I submit note IDs directly?

No. Submit a complete supported video-note URL.

#### Can I process up to 1,000 notes?

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

#### What transcript formats are available?

Plain `text`, timestamped `segments`, `srt`, and `vtt`.

#### Are native subtitles used before AI transcription?

Yes. A usable Xiaohongshu native subtitle is always preferred and does not create an AI-minute charge. AI runs only as a fallback when `allowAiTranscript` is enabled.

#### Can I disable AI transcription?

Yes. Set `allowAiTranscript` to `false`. If no native subtitle can be used, the result returns `status: "no_transcript"` with note and media metadata preserved.

#### Do four transcript formats cost four times?

No. All selected formats are generated from one completed transcript. Native subtitles create no AI-minute charge, and selecting multiple formats does not add AI transcription charges when AI fallback is used.

#### What happens when a video has only music or silence?

It can return `success: true` and `status: "no_speech"` with empty transcript content. AI minutes are still charged because the media was processed.

#### How are AI minutes calculated?

Each started media minute is one unit: up to 60 seconds is 1, 61–120 seconds is 2, and so on. The implementation uses `max(1, ceil(durationSeconds / 60))`.

#### How is translation charged?

Only successful actual translation is charged. Units are the original transcript's Unicode character count rounded up per started 1,000 characters. English-to-English reuse is free.

#### Does translation replace the original transcript?

No. `transcript` always remains the source-language result; `translation` is an additional object.

#### What happens if translation fails?

The original transcript remains available, `status` becomes `partial_success`, `translation` is `null`, and no translation event is charged.

#### Do I pay for an image-only note?

It does not emit a successful-note, AI-minute, or translation charge.

#### Is the downloadable video URL included?

Yes, when RedNote provides an accessible video stream. It is included with the successful note result and has no separate video URL event.

#### Are media URLs permanent?

No. RedNote/Xiaohongshu CDN URLs can contain temporary signatures and can expire. Copy permitted media to your own storage when you need long-term access.

#### Do I need `xsec_token`?

Yes. Each submitted video-note URL must contain its valid matching token.

#### Can AI agents use this Actor?

Yes. Use `lance_api/xiaohongshu-video-ai-transcript-scraper-api` through the Apify API or Apify MCP Server.

### Limitations

- Publicly accessible content only; no login automation or access-control bypass
- Image-only notes cannot produce transcripts
- Deleted, unavailable, or restricted notes can fail
- Profile, user, and search pages are unsupported
- `xsec_token` values can expire or become invalid
- Native subtitle URLs are signed CDN URLs and can expire; the Actor can try another native track or use AI fallback when enabled
- Background music, noise, overlapping speakers, accents, and audio quality can affect recognition
- Silence or music-only media can return `no_speech`
- Returned CDN media URLs can expire or stop working
- Note metadata can be empty, null, or omitted when unavailable
- The Actor does not permanently host the source media
- Platform or speech-recognition changes can temporarily affect results

### Public data and responsible use

Use this Actor only for lawful access to public content. Respect RedNote/Xiaohongshu terms, Apify terms, copyright, privacy, and applicable law. Do not use it for harassment, spam, unlawful profiling, attempts to obtain non-public information, or access-control bypass.

### Support

For help, contact **lanceapi2026@hotmail.com** and include:

- Apify Run ID
- The submitted public video-note URL, with the query string removed if you do not want to share the token
- Returned `status`, `error.code`, and `error.message`
- Expected result and actual result

Do not send Apify tokens, cookies, sessions, API keys, or passwords.

# Actor input Schema

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

Add 1–1000 full Xiaohongshu video-note URLs. Each URL must contain a valid xsec\_token query parameter. Open a public video note from Xiaohongshu search, feed, or sharing, then copy the complete browser URL; xsec\_token appears after ? or & in that URL. A valid token makes direct media resolution more reliable. Note IDs and token-free URLs are not accepted by this Actor.

## `formats` (type: `array`):

Choose plain text for LLM workflows, segments for timestamped analysis, or SRT/VTT for subtitles.

## `allowAiTranscript` (type: `boolean`):

Use AI speech recognition only when the video does not provide a usable native subtitle. Native subtitles are always preferred because they are faster and do not require AI transcription.

## `translate` (type: `boolean`):

Keep the original transcript and optionally add a translated copy.

## `targetLanguage` (type: `string`):

Choose the target language. Start typing a language name to filter the list.

## Actor input object example

```json
{
  "urls": [
    "https://www.xiaohongshu.com/explore/6a75b0f0000000003303608a?xsec_token=ABLy6_xYG1gyFlArGAB2K1M3EZNPtj3hsXL-LCiWd1Rjs=&xsec_source=pc_search&source=web_explore_feed"
  ],
  "formats": [
    "text",
    "segments"
  ],
  "allowAiTranscript": true,
  "translate": false,
  "targetLanguage": "en"
}
```

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("lance_api/xiaohongshu-video-ai-transcript-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 = {}

# Run the Actor and wait for it to finish
run = client.actor("lance_api/xiaohongshu-video-ai-transcript-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 '{}' |
apify call lance_api/xiaohongshu-video-ai-transcript-scraper-api --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,lance_api/xiaohongshu-video-ai-transcript-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/eQaumIoNhAwZnZx9Q/builds/07CMFYDbfg3gPAU6h/openapi.json
