RedNote Scraper & Data API — Private Beta
Under maintenancePricing
$9.00 / 1,000 valid records
RedNote Scraper & Data API — Private Beta
Under maintenancePublic RedNote search, creator posts, profiles and comments with strict caps, normalized records, safe exports and explicit access errors.
Pricing
$9.00 / 1,000 valid records
Rating
0.0
(0)
Developer
Ivan Tech
Maintained by CommunityActor stats
0
Bookmarked
2
Total users
1
Monthly active users
23 days ago
Last modified
Categories
Security
Limited permissionsShare
RedNote Scraper & Data API
A TypeScript Apify Actor for bounded collection of publicly accessible Xiaohongshu/RedNote search cards, creator posts, profiles, and comments. It produces normalized records, a run manifest, a spreadsheet-safe CSV, and JSONL.
Deployment: Open the private Actor in Apify. The default run configuration pins a tested build, with 1,024 MB memory and a 900-second platform timeout; docs/deployment.json records the current build number. The verified profile run returned one real record. On that collection-validation build, search and comments were access-restricted; creator posts returned an unrecognized source error. See docs/cloud-smoke.json for the exact outcomes and docs/monetization.json for later billing checks.
Release: private engineering beta, with pay-per-event monetization configured at $9 per 1,000 valid unique records. The collector uses a fresh anonymous Chromium context and reads the page's public state and its normal network responses. RedNote can require login or verification. Those targets return explicit errors; an empty dataset does not mean that the keyword or creator has no content. Reliable live coverage and commercial reuse have not been established. This independent service is not affiliated with RedNote.
Search and user posts are the MVP modes. Profiles and comments, including replies, are experimental. No direct full-post-detail mode is offered. No passwords, imported cookies, account pools, CAPTCHA solving, private content, posting, messaging, or media downloading are supported.
Run on Apify
Open the Actor's Input tab and select one mode. Supply only that mode's target array. Example files are in examples/.
Search:
{"mode":"search","keywords":["咖啡","AI productivity"],"maxItems":100,"maxItemsPerTarget":50,"schemaVersion":"1.0"}
Creator posts:
{"mode":"userPosts","profileUrls":["https://www.xiaohongshu.com/user/profile/6784ba7f00000000080191fb"],"maxItems":50,"maxItemsPerTarget":50,"schemaVersion":"1.0"}
Profile (experimental):
{"mode":"profile","profileUrls":["https://www.xiaohongshu.com/user/profile/6784ba7f00000000080191fb"],"maxItems":1,"schemaVersion":"1.0"}
Comments (experimental):
{"mode":"comment","postUrls":["https://www.xiaohongshu.com/explore/670a46a50000000024017580"],"maxItems":20,"maxItemsPerTarget":20,"includeReplies":true,"maxRepliesPerComment":5,"schemaVersion":"1.0"}
These example URLs are public documentation examples, not availability guarantees. Replace them with the public targets you are authorized to analyze. Supported URL routes are /user/profile/<24-character hex ID>, /explore/<ID>, and /discovery/item/<ID>. HTTPS only; short links are rejected. Public share parameters xsec_token and xsec_source can be used for navigation but are removed from customer-facing records and the manifest. Apify retains the original input separately in its access-controlled run storage.
| Option | Meaning |
|---|---|
mode | Required: search, userPosts, profile, or comment |
keywords / profileUrls / postUrls | Exactly the relevant array, 1–20 targets before deduplication |
maxItems | Global unique record cap; default 100, maximum 1,000 |
maxItemsPerTarget | Unique records associated with each target; default 50, maximum 1,000 |
includeReplies | Comment mode only; omitted means false |
maxRepliesPerComment | Only with replies enabled; default 10, maximum 100 |
schemaVersion | 1.0 |
Profile mode returns at most one record per target. Parents and replies both consume record caps. A post found under two keywords is exported once, with both associations in the manifest. Repeated targets are deduplicated without translating or lowercasing keywords. Unknown properties and irrelevant target arrays are rejected before collection.
The run uses one worker and one page at a time, at most three retries after transient navigation failures, a two-minute per-target collection deadline, and a fourteen-minute application deadline within the fifteen-minute platform timeout. Login, verification, and rate-limit responses are not repeatedly retried. Pagination uses the visible page; there is no guarantee of chronological order or exhaustive results. No date filtering is implemented.
Read results correctly
- Check
OUTPUTandMANIFESTin the run's key-value store. - Read source records from the default dataset or
RESULTS.jsonl. - For spreadsheets, download
RESULTS.csvfrom the Output tab. It neutralizes formula-leading cells. The platform's raw dataset-to-CSV export does not apply this extra transformation. - Inspect
MANIFEST.targets, queryassociations,commentThreads, andRECONCILIATIONbefore interpreting coverage or charges.
sourceCoverage is always unknown. Reaching your requested cap can be a successful bounded run without proving comprehensive coverage.
| Product status | Interpretation |
|---|---|
succeeded | Accessible collection ended or customer caps were reached without parser/access errors. A source-confirmed empty result can succeed. |
partial | Some valid output exists, but access, pagination, parsing, time, or reconciliation prevented a clean completion. |
failed | No useful results and an error. The Apify run is also marked FAILED. |
cancelled | Application-observed graceful cancellation; completed records remain available. |
running | In-progress manifest, not a final result. |
Apify execution status is separate. A partial product run exits normally so exports remain available. A hard platform abort can leave an earlier manifest; check the platform status as well. A resurrected run reuses its checkpoint and dataset. An uncertain publication or charge freezes admission for operator reconciliation instead of replaying the side effect.
Example empty outcome: status: succeeded, uniqueRecords: 0, target reason ACCESSIBLE_END with verified source evidence. Example blocked outcome: status: failed, target reason ACCESS_RESTRICTED, zero result charges. Example partial outcome: status: partial, some records, target reason PAGINATION_UNAVAILABLE. No blocked response is labeled as a genuine empty search.
Structured errors include INVALID_INPUT, ACCESS_RESTRICTED, RATE_LIMITED, TARGET_UNAVAILABLE, PARSER_CHANGED, BUDGET_REACHED, TIMEOUT, NETWORK_ERROR, MODE_DISABLED, BILLING_UNCERTAIN, PUBLICATION_UNCERTAIN, CONFIGURATION_ERROR, and CANCELLED.
Field dictionary
| Fields | Contract |
|---|---|
recordType, sourceId, sourceUrl | Record type, original string ID, canonical link without session/share tokens |
observedAt, runId, buildId | UTC observation time and actual run/build provenance |
schemaVersion, parserVersion | Output contract and extraction implementation versions |
fieldAvailability | available, not_provided_by_source, invalid_source_value, sanitized, or truncated |
transformations | Field-specific contact/token minimization, control-character removal, or truncation reasons |
Post: title, text, postType | Source-provided values; unavailable content is null, never invented full text |
Post/comment: creator | String creator ID, display name, canonical profile link when present |
Post: media | Image descriptors only: URL, available dimensions, isTemporary: true; no download or durability promise |
Post: metrics | Likes, comments, saves and shares, independently null when unavailable |
Profile: displayName, biography, avatarUrl | Minimized public attributes; no age, gender, location, email or phone fields |
Profile: metrics | Followers, following, and combined likesAndCollections; the aggregate is not split |
Comment: postId, parentCommentId, text | Post association and reply hierarchy; parentCommentId is null for root comments |
Comment: repliesReported | Source-reported count with precision metadata |
MANIFEST.commentThreads | Actual repliesCollected, repliesReported, repliesComplete and a reason for incompleteness |
publishedAt | {raw, iso, precision, timezone} or null. Relative/local source text keeps null ISO/timezone; epoch timestamps retain second/millisecond precision. |
Every metric is { "value": number|null, "raw": string|null, "isApproximate": boolean }. 1.2万 maps to 12,000 with isApproximate: true. Missing values are null. All records pass a discriminated runtime schema before publication. The field mapping registry is exported from src/normalize.ts; only explicit reviewed source paths are accepted.
Pricing and budget
The configured price is $0.009 per valid unique record ($9 per 1,000), effective October 15, 2026. One custom event, valid-record, is the primary pricing unit. There is no startup fee or automatic dataset-item fee. Platform execution usage is included in the customer event price; operator/owner runs and post-run storage access can still incur Apify usage costs. The Actor remains private.
The minimum selectable maximum run budget is $0.009, enough for one result. This is a budget floor, not a minimum fee: a blocked or empty collection has zero result events. A 100-record cap permits at most $0.90 in result fees, subject to a lower launch spending cap. Pricing is configured but profitability is not established; Apify's initial small-sample usage estimate was $10.16 per 1,000 results, above the $7.20 remaining from $9 after the standard 20% marketplace share. See docs/monetization.md.
The paid path uses one custom event, valid-record, after confirmed dataset publication. A stable per-run/record idempotency key accompanies each charge. It refuses a paid configuration with additional nonzero event types and requires a finite maxTotalChargeUsd launch setting. Automatic dataset/start fees are removed. Duplicates, status rows, invalid inputs and failed collection are never intentionally charged. A later independent observation is a new record for billing purposes.
MANIFEST.billing exposes the maximum result charge, confirmed count, actual result charges or null if uncertain, and reconciliation. actualResultChargesUsd excludes compute/storage costs, which are shown on the Apify run. An in-flight operation may consume operator resources even after admission stops. See docs/operations.md for interruption and correction procedures.
Native API
Use the asynchronous native Apify API. Keep credentials on your server and pin the tested build number from docs/deployment.json.
export APIFY_TOKEN='your-server-side-token'node scripts/launch.mjs examples/search.json --build YOUR_TESTED_BUILD --max-charge-usd 0.25
The script requires an explicit spending cap and returns the run, dataset, and key-value-store IDs. Poll GET /v2/actor-runs/{runId}; fetch the manifest at GET /v2/key-value-stores/{storeId}/records/MANIFEST; retrieve results at GET /v2/datasets/{datasetId}/items?format=json. Send Authorization: Bearer … server-side. For graceful cancellation use POST /v2/actor-runs/{runId}/abort?gracefully=true.
Input maxItems is our record cap; the Apify run-query maxItems has separate platform semantics. Spending caps are launch options. There is no companion API, subscription dashboard, custom webhook sender, or 24-hour job submission idempotency service in this release; the PRD defers those until paying integrations justify them. Use native polling now. Avoid retrying an ambiguous job-launch request automatically.
Development and deployment
npm cinpm run checknpm run buildapify run --input-file examples/search.jsonapify push --build-tag beta --wait-for-finish 60
Node.js 22 is required. Docker installs the Chromium version matching the pinned Playwright package. For local development, installed Google Chrome is used on macOS, or set REDNOTE_BROWSER_EXECUTABLE to an explicit browser path; alternatively run npx playwright install chromium. REDNOTE_ENABLED_MODES=search,userPosts independently disables other adapters. Never put Apify tokens in source files or client-side code.
The browser can connect only to HTTPS RedNote/CDN hosts through a local validating proxy. Every tunnel resolves DNS, rejects nonpublic answers and connects to the vetted address. Browser routes also check redirects, block downloads/media and disallow WebSockets and service workers. Raw HTML, screenshots, imported sessions and raw API response diagnostics are not retained.
The fixture suite tests contracts, normalization, SSRF controls, deduplication, caps, missing fields, reply relationships, publication/charge failure boundaries and restarts. These fictional fixtures are not the PRD's 200 annotated live fixtures. See docs/validation.md for observed test results and outstanding commercial gates, and docs/access-review.md for source restrictions.
Retention and responsible use
Direct customers own their Apify storage and control its deletion/retention. The Actor does not promise to delete their data seven days later. Operator-managed validation runs can use scripts/retention.mjs to remove this Actor's datasets and key-value stores after seven days. It defaults to a dry run, scopes by Actor ID and supports whole-dataset deletion; see operations documentation. No raw diagnostics are retained, so there is no hidden 24-hour raw-data store.
Use the data only for legitimate public-content research you are authorized to perform. Private-data collection, contact harvesting, harassment, sensitive-person profiling and deanonymization are outside this product's scope. Public visibility does not establish redistribution rights. Missing observations do not establish deletion, and likes are not a measure of sales, reach or sentiment.
For this private beta, corrections and takedowns go to the operator who supplied access (Apify account Gen_One_AI), with the run ID and source IDs. Commercial release requires a published support channel. Operators must record affected datasets and downstream exports, delete whole datasets or replace them with sanitized datasets, and notify affected recipients. Downloaded files cannot be recalled automatically.