How to shortlist Xiaohongshu PGY creators by rate and reads
Two endpoints: Xiaohongshu PGY creator search to filter creators by topic, followers and note type, sorted by rate, reads or engagement, then Xiaohongshu PGY creator detail for each one you shortlist. The worked example below is 6 calls and costs $0.24; a failed call is not charged.
Updated
The job: a skincare brand has a budget for ten sponsored notes and wants creators who fit the topic, sit in a follower band it can afford, and actually get read. PGY (蒲公英) is Xiaohongshu's official marketplace where brands book creators, and every creator page there shows a rate for an image note and a video note, plus median reads and engagements of everyday notes. You search PGY by topic with filters, work out what a note costs per thousand reads, and pull the full profile of the five you would pitch. You end with one table you can paste into a brief.
No PGY brand account is needed for this. You read what PGY shows advertisers, through your API key. Booking still happens in PGY.
Step by step
Step 1: search PGY with filters
Call Xiaohongshu PGY creator search with query. The parameters that shape the list:
search_by:notes(the default) matches your words against what creators' notes are about;namematches nicknames.followers_minandfollowers_max: the follower band.type:all(the default),imageorvideo, for creators who mostly post image notes or mostly video notes.sort:relevance(the default),most_followers,most_engagements,most_reads,lowest_rateorhighest_rate.
One call returns up to 20 creators for $0.04. Each has id (24 hex characters, the same as the Xiaohongshu user ID), name, username (the Xiaohongshu number), location, gender, followers, categories, median_views (median reads of everyday notes) and median_engagements. rates lists what the creator charges in yuan: image_note (图文笔记) and video_note (视频笔记), each with price and currency: "CNY".
curl -G "https://api.okdata.online/v1/xiaohongshu/pgy/creators/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=敏感肌' \
--data-urlencode 'followers_min=10000' \
--data-urlencode 'followers_max=100000' \
--data-urlencode 'type=video' \
--data-urlencode 'sort=lowest_rate'
median_views deserves attention. Xiaohongshu hides view counts on public notes, so the median reads PGY shows advertisers are the nearest thing to a reach figure. engagement_rate is always null here: PGY does not publish one, and meta.unavailable says so. Divide median_engagements by median_views if you want your own.
For more creators, send page.next_cursor back as cursor. PGY lets a search be read only to its first 5,000 results, so narrow the filters rather than paging forever.
Step 2: pull the full profile
Xiaohongshu PGY creator detail takes the creator id and returns their current PGY profile for $0.04. It carries the same core fields as search, refreshed, and for each rate whether the creator is open for that kind of order (available). With view=full, ext adds PGY's own figures where it shows them: total likes and saves (ext.likes_and_saves), feature tags (ext.feature_tags), PGY's estimated CPM for a video note (ext.cpm_video), sponsored notes in the last 30 days (ext.sponsored_notes_30d) and how often the creator answers an invitation within 48 hours (ext.invite_reply_48h_pct).
curl -G "https://api.okdata.online/v1/xiaohongshu/pgy/creators/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=5e8b2c41000000000100a7d3' \
--data-urlencode 'view=full'
Because the PGY ID is the Xiaohongshu user ID, you can also call detail straight away with an author.id from note search, when a creator you found by their notes might be on PGY.
Step 3: rank and export in Python
The script searches once, scores each creator by video note price per 1,000 median reads, takes the five best, fetches their profiles and writes a CSV.
import csv
import os
import requests
API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
SHORTLIST = 5 # profiles to fetch; each is one call
def get(path, **params):
body = requests.get(API + path, headers=HEADERS, params=params, timeout=60).json()
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
return body["data"]
def rate(creator, kind):
return next((r for r in creator["rates"] or [] if r["type"] == kind), None)
def per_1k_reads(creator):
video = rate(creator, "video_note")
reads = creator["median_views"]
return video["price"] / reads * 1000 if video and video["price"] and reads else float("inf")
found = get("/v1/xiaohongshu/pgy/creators/search", query="敏感肌", followers_min=10000,
followers_max=100000, type="video", sort="lowest_rate")["items"]
shortlist = sorted(found, key=per_1k_reads)[:SHORTLIST]
with open("pgy_shortlist.csv", "w", newline="", encoding="utf-8-sig") as f:
out = csv.writer(f)
out.writerow(["name", "pgy_id", "followers", "median_reads", "median_engagements",
"image_note_cny", "image_open", "video_note_cny", "video_open", "cny_per_1k_reads"])
for c in shortlist:
p = get("/v1/xiaohongshu/pgy/creators/get", id=c["id"])["item"]
image, video = rate(p, "image_note") or {}, rate(p, "video_note") or {}
score = per_1k_reads(p)
out.writerow([p["name"], p["id"], p["followers"], p["median_views"], p["median_engagements"],
image.get("price"), image.get("available"), video.get("price"), video.get("available"),
round(score, 1) if score != float("inf") else ""])
Thirty profiles instead of five would cost $1.20 for the detail calls.
Good to know
- List price, not deal price. PGY shows what the creator lists. Platform fees and negotiated discounts are settled in PGY when you place the order.
- Closed orders.
available: falsemeans the creator lists that kind of note but is not taking it now. Check it before you pitch. - Only creators on PGY. Someone who has not joined PGY has no profile; detail returns
not_found, which is free. - What stays in PGY. The audience profile and the creator's past sponsored notes are not in these fields. Look at them in the PGY console before signing.
- Retries without paying twice. Send an
Idempotency-Keyheader with each call. The same request with the same key within 24 hours returns the stored answer withmeta.replayed: trueand no new charge. - Refresh before you book. Rates and medians move with every campaign; fetch the profile again on the day you send the brief.
For what PGY offers developers officially and how this compares, see the PGY creator data API answer. For creator discovery across platforms, see creator discovery.
What the example costs
One PGY search for 敏感肌 (sensitive skin) creators with 10k to 100k followers who mostly post video notes, cheapest first, then the full profile of 5 of them
| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| Xiaohongshu PGY creator search | 1 | $0.04 | $0.04 |
| Xiaohongshu PGY creator detail | 5 | $0.04 | $0.20 |
| Total | 6 | $0.24 |
Prices in force when this page was built. A failed call costs nothing.
In your AI (MCP)
Connect the MCP server once, then say what you want. The agent finds these endpoints, reads their prices and calls them on your balance.
SaySearch Xiaohongshu PGY for 敏感肌 (sensitive skin) creators with 10k to 100k followers who mostly post video notes, cheapest first. Work out the video note price per 1,000 median reads, keep the 5 best value, get their full PGY profiles and give me one table.
What the agent sends to the call tool first
{
"endpoint": "xiaohongshu.pgy.creators.search",
"params": {
"query": "户外"
},
"idempotency_key": "<a new UUID>"
}