# RedNote (Xiaohongshu) User Profile Scraper (`dami_studio/rednote-profile-scraper`) Actor

Scrape RedNote (Xiaohongshu) user profiles. Each row has the nickname, RedNote ID, follower and following counts. Also likes, collects and the verified badge. You get the province the account posts from, plus up to 30 recent notes. No login. $2.90 per 1,000.

- **URL**: https://apify.com/dami\_studio/rednote-profile-scraper.md
- **Developed by:** [Dami's Studio](https://apify.com/dami_studio) (community)
- **Categories:** Social media, Lead generation
- **Stats:** 7 total users, 5 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per event

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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) User Profile Scraper

Give it RedNote profile links or bare user IDs. Get back one row per profile: nickname, RedNote ID, avatar, banner, bio, follower count, following count, likes + collects, verification badge, IP location, gender, city, profession, and the user's recent notes with likes, collects and comments on each.

No login and no cookies to paste. It's a plain HTTP scraper with no browser, which is why it's cheap and why 240 profiles finish in about a minute.

**$2.90 per 1,000 profiles** ($0.0029 each). Flat rate — the same $2.90 on the free plan as on Diamond, with no volume tiers and no minimum spend. You're charged per profile actually returned — blocked pages, missing users and empty runs never add a profile charge.

### What you get per profile

A real row, pulled 21 August 2026:

| Field | Value |
|---|---|
| `userId` | `5b723a65c756070001d43c6c` |
| `url` | `https://www.xiaohongshu.com/user/profile/5b723a65c756070001d43c6c` |
| `nickname` | `无糖小馒头` |
| `redId` | `607277765` — the 小红书号 people search each other by |
| `avatar` / `bannerImage` | CDN image URLs |
| `description` | `十年美食无人问，一朝绑匪天下知。` |
| `followerCount` | `1310` |
| `followerCountText` | `"1310"` — the exact string the page showed |
| `followerCountIsExact` | `true` |
| `followingCount` | `67` |
| `likesAndCollectsCount` | `94300` |
| `likesAndCollectsCountText` | `"94.3K"` |
| `countsAreApproximate` | `true` — set when either count above was abbreviated |
| `ipLocation` | `江苏` |
| `gender` | `male` / `female` / `null` |
| `location` | the city chip on the profile, when set |
| `profession` | the profession chip, when set |
| `isVerified` / `verifiedType` / `verifiedReason` | verification badge and its stated reason |
| `tags` | the chips on the profile, e.g. `["25岁", "浙江杭州", "FoodBlogger"]` |
| `recentNoteCount` / `recentNotes` | `[{ title, type, likedCount, collectedCount, commentCount, pinned, coverImage }, …]` |
| `source`, `scrapedAt` | provenance |

### Field coverage, measured

220 profiles pulled from RedNote's live explore feed in one run on 2026-08-10, nothing excluded:

| Field | Filled |
|---|---|
| `nickname`, `redId`, `avatar`, `bannerImage` | 100% |
| `followerCount`, `followerCountText`, `likesAndCollectsCount` | 100% |
| `recentNotes` (6.9 notes per profile on average) | 100% |
| `followingCount` | 97.7% |
| `description` | 90.0% |
| `ipLocation` | 81.4% |
| `gender` | 74.1% |
| `tags` | 70.9% |
| `location` | 47.3% |
| `profession` | 40.0% |
| `verifiedReason` | 6.4% |
| `isVerified` = true | 5.9% |

Inside `recentNotes`: `type`, `collectedCount`, `commentCount` and `coverImage` on 100%, `likedCount` on 96.5%, `title` on 98.4%.

The fields under 100% are blank because the creator left them blank. Most people have no profession chip and only about 5% of accounts are verified. Nothing there is null because the scraper failed to read it.

### Follower counts are exact for most accounts

RedNote publishes the exact number up to roughly 10,000 followers and abbreviates above that. Across those 220 profiles, 52.7% came back exact (`5911`, `1306`, `83`) and the rest abbreviated to one decimal (`194.8K`, `15.9K`). You get both readings:

- `followerCount` — a number, so you can sort and filter on it.
- `followerCountText` — the original string.
- `followerCountIsExact` — `true` when the string was a plain integer.

`countsAreApproximate` is `true` whenever the follower or likes figure was abbreviated. `194.8K` becomes `194800`, which is within 0.05% of the truth rather than a bucket floor.

### Input

```json
{
  "profileUrls": [
    "https://www.xiaohongshu.com/user/profile/5b723a65c756070001d43c6c",
    "620f2fbd000000001000e44c"
  ],
  "maxNotesPerProfile": 10
}
```

Bare 24-character user IDs work as well as full URLs. `maxItems` is a cap, not a target: leave it at `0` and you get one row per URL you supplied. `maxNotesPerProfile` takes 0–30; set it to 0 to skip notes entirely.

`includeExploreFeed` tops the list up with authors from RedNote's public explore feed, so you can try the actor without hunting for links first. Off by default.

### How it opens a profile, and the one thing that can go wrong

The actor reads RedNote's mobile profile page. That page needs an `xsec_token`, which the actor mints for itself from the public explore feed at the start of each run — one request, and the token then opens every profile in the queue. You never have to supply one.

The mint is the only step that can end a run with zero rows. RedNote meters its server-rendered pages per exit address, and on a busy day it answers with an empty client-render shell instead of the feed. The actor races several exit pools looking for one that answers. If none does, you get a single uncharged `TOKEN_UNAVAILABLE` row and the run stops right there instead of burning your compute.

Two fixes: re-run a few minutes later, or open xiaohongshu.com in a browser, click any creator, and paste the `xsec_token` out of the address bar into the `xsecToken` input. One token opens every profile and stays valid for at least an hour.

### Limits, stated plainly

**No note permalinks.** The profile page identifies each recent note by a 32-character hash, not the 24-character note ID that `/explore/<id>` accepts, and there's no way to turn one into the other. So each note comes back with its title, type, likes, collects, comments and cover image, and no `url` — emitting one that would 404 is worse than omitting it. If you need note bodies, the companion [RedNote Scraper](https://apify.com/dami_studio/rednote-scraper) reads note pages directly.

**There is no lifetime note total.** The profile shows following, followers and likes+collects. It doesn't show "posted N notes", so the actor doesn't invent one. `recentNoteCount` is how many recent notes are in that row, not a career total.

**Up to 30 recent notes.** That's the first page of the profile. There's no full note history here.

**The explore feed is a bonus, not a feature.** It yields about thirty authors per page and gets refused more often than a profile page does. When it's on and RedNote refuses it, you get one uncharged `FEED_UNAVAILABLE` row and the run carries on with the URLs you supplied.

**A user ID that doesn't exist looks identical to a refusal.** RedNote serves the same login shell for both, so the diagnostic row names both possibilities. Check the ID before assuming you were rate-limited.

**Bios are as written.** RedNote's own `还没有简介` placeholder ("no bio yet") is site text, not user text, so it comes back as `null`.

**No email or phone.** RedNote doesn't publish either on a profile.

### Throughput

Two runs on the Apify platform, 2026-08-10: 220 of 220 profiles in 47 seconds, and 240 of 240 in 72 seconds, at 8 concurrent requests. About 47 KB of traffic per profile.

Each profile gets four attempts across four exit addresses and four browser fingerprints before it's given up on. If eight profiles in a row fail, the run stops and writes an uncharged `RATE_LIMITED` row listing every URL it didn't attempt, so you can feed that list straight back in later.

### Billing

$2.90 per 1,000 profiles. One charge per profile row actually returned. Blocked pages, missing users, `TOKEN_UNAVAILABLE` and empty runs produce `_diagnostic` rows that cost nothing. Empty input returns one labelled `_sample` row so you can see the shape, also free.

### FAQ

**Do I need a RedNote account or cookies?**
No. Everything here is the public, signed-out profile page.

**Is RedNote the same thing as Xiaohongshu?**
Yes. 小红书 / Xiaohongshu is the Chinese name; RedNote is what most English speakers call it.

**How do I find a user ID?**
Open any RedNote post, click the author, copy the URL. The 24-character hex string after `/user/profile/` is the ID. Paste either the whole URL or just that string.

**Can I get a user's full note history?**
No. Up to 30 recent notes from the first page of the profile, with engagement counts but without permalinks.

**What is the `xsecToken` input for?**
Nothing, normally. Leave it empty and the actor mints its own. It exists only so you can unblock a run that reported `TOKEN_UNAVAILABLE`.

**What happens if a profile is deleted or the ID is wrong?**
An uncharged diagnostic row with an `errorCode` and a hint. You're not billed for it.

# Actor input Schema

## `profileUrls` (type: `array`):

The main input. RedNote profile links (https://www.xiaohongshu.com/user/profile/...) or bare 24-character user IDs. One row is returned per URL. If your links still carry the ?xsec\_token=... they came with, keep it - it saves the Actor a request.

## `maxNotesPerProfile` (type: `integer`):

How many of the profile's recent notes to include (0-30). Each note carries its title, type, likes, collects, comments and cover image. Set 0 to skip them.

## `maxItems` (type: `integer`):

Cap on profiles returned. Leave at 0 to return one row for every profile URL you supply. You are charged per profile actually returned.

## `includeExploreFeed` (type: `boolean`):

Optional discovery helper: top up the list with the authors of posts on RedNote's public explore feed. Off by default. A refused feed costs nothing and does not stop the run.

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

Leave empty. The Actor mints its own token from RedNote's public explore feed on every run. If a run ever reports TOKEN\_UNAVAILABLE, open xiaohongshu.com in a browser, click any creator, and paste the xsec\_token from the address bar here - one token works for every profile and stays valid for at least an hour.

## `proxyConfiguration` (type: `object`):

Leave this alone unless you have your own proxies. The Actor takes a fresh Apify Proxy exit address for every request, which is what keeps this target answering. Supplying your own proxy URLs replaces that rotation - do it only if your pool is larger.

## Actor input object example

```json
{
  "profileUrls": [
    "https://www.xiaohongshu.com/user/profile/5b723a65c756070001d43c6c",
    "https://www.xiaohongshu.com/user/profile/620f2fbd000000001000e44c"
  ],
  "maxNotesPerProfile": 10,
  "maxItems": 0,
  "includeExploreFeed": false,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

One row per profile: nickname, RedNote ID, avatar, bio, follower, following and likes+collects counts with a flag saying whether each count is exact or rounded, verification, IP location, gender, profession and the recent notes with their like, collect and comment counts. A profile RedNote refuses returns a labelled diagnostic row instead, and that row is not charged.

# 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 = {
    "profileUrls": [
        "https://www.xiaohongshu.com/user/profile/5b723a65c756070001d43c6c",
        "https://www.xiaohongshu.com/user/profile/620f2fbd000000001000e44c"
    ],
    "maxNotesPerProfile": 10,
    "maxItems": 0,
    "proxyConfiguration": {
        "useApifyProxy": true
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("dami_studio/rednote-profile-scraper").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 = {
    "profileUrls": [
        "https://www.xiaohongshu.com/user/profile/5b723a65c756070001d43c6c",
        "https://www.xiaohongshu.com/user/profile/620f2fbd000000001000e44c",
    ],
    "maxNotesPerProfile": 10,
    "maxItems": 0,
    "proxyConfiguration": { "useApifyProxy": True },
}

# Run the Actor and wait for it to finish
run = client.actor("dami_studio/rednote-profile-scraper").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 '{
  "profileUrls": [
    "https://www.xiaohongshu.com/user/profile/5b723a65c756070001d43c6c",
    "https://www.xiaohongshu.com/user/profile/620f2fbd000000001000e44c"
  ],
  "maxNotesPerProfile": 10,
  "maxItems": 0,
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}' |
apify call dami_studio/rednote-profile-scraper --silent --output-dataset

```

## MCP server setup

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

```

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/bFxeAYIyk3i8LwiFY/builds/2U2VsrvYIz7oMZr5l/openapi.json
