Xiaohongshu Pugongying API: Creator Search, Rates and Audience Profiles
Build a Xiaohongshu Pugongying creator shortlist with Just One API. Filter by follower count, retrieve profiles and collaboration rates, and save audience data with Python.
Build a creator shortlist for a Xiaohongshu campaign
A useful creator shortlist combines discovery, collaboration rates and audience fit. Just One API provides Xiaohongshu Pugongying endpoints for each step: search for creators, retrieve their profiles, then inspect their follower distributions.
This tutorial searches for creators with 10,000–100,000 followers, reads at most two result pages, and retrieves profiles and audience data for up to three creators. Adjust the follower range to your project. The output is a shortlist for review; content quality and commercial suitability still need to be assessed.
For note content or comments, start with the Xiaohongshu versus Pugongying guide. This workflow uses the creator marketplace's marketing data.
Get a token and test a request
Register for Just One API, obtain your API token, and use the interactive documentation to test for free. One token works across platform APIs, with usage-based billing. Check your account for the permissions and trial allowance available for each endpoint.
Open Creator Search V1, enter your token and follower limits, and request page 1. Check the response body's business code: it must be 0 before you process the data. HTTP success alone is insufficient.
All three endpoints in this tutorial use GET and require a token query parameter. The script reads the token from an environment variable and avoids printing full request URLs containing it.
Step 1: Search and retain each creator's userId
The search endpoint is /api/xiaohongshu-pgy/api/solar/cooperator/blogger/v2/v1. The example sends:
fansNumberLower=10000andfansNumberUpper=100000for the follower range.sort=FANSfor descending follower count. UseDEFAULTfor the platform's intelligent ranking.page=1for the first page, incrementing the page number for subsequent requests.
In the current public response example, creators appear in data.kols. Retain each row's userId for profile and audience requests. The script deduplicates these IDs before choosing a small sample.
The returned total describes the reported search result size; it is not a count of all creators on the platform. This example stops after two pages, an empty page, or a page with no new IDs. Restart at page 1 when changing filters.
Step 2: Read profiles and collaboration rates
Pass a selected userId to Creator Profile V1. The current public example includes data.name, data.fansCount, data.picturePrice, data.videoPrice and data.showPrice.
Image-post and video rates can be null. A null rate means no value was returned in that response; it does not mean a free collaboration. Preserve showPrice alongside the raw rates. Before comparing budgets, confirm the unit, content format and conditions associated with each quote.
The script saves complete profile responses and creates a compact shortlist.json. Search and profile data may reflect different retrieval times, so retain both source responses when values differ instead of silently overwriting one with the other.
Step 3: Retrieve follower distributions
Call Follower Distribution V1 with the same userId. The current example contains:
data.ages, withgroupandpercentvalues.data.genderfor gender distribution.data.provincesanddata.citiesfor geography.data.interestsanddata.devicesfor interest and device distributions.data.dateKeyfor the audience data's date marker.
These fields help you assess audience fit. Check each metric's scale and denominator before charting it; do not automatically multiply every proportion by 100 or replace missing groups with zero. The script preserves the complete audience response and adds dateKey to the shortlist so its data period remains visible.
Python example: Export profiles and audience data
Install the dependency and set your token. Replace your_token with your own value. These commands work in a macOS or Linux terminal.
python3 -m pip install requests
export JUSTONEAPI_TOKEN='your_token'Save the code as pugongying_sample.py and run python3 pugongying_sample.py. It makes at most two search requests plus profile and audience requests for three creators: up to 8 API requests. It makes fewer calls if results end early or an error stops execution. These are sample limits, not service quotas.
import json
import os
from datetime import datetime, timezone
from pathlib import Path
import requests
BASE_URL = "https://api.justoneapi.com"
TOKEN = os.environ.get("JUSTONEAPI_TOKEN", "")
def call_api(path, **params):
try:
response = requests.get(
BASE_URL + path,
params={"token": TOKEN, **params},
timeout=120, allow_redirects=False,
)
except requests.RequestException:
raise RuntimeError("API network error or timeout") from None
if response.status_code != 200:
raise RuntimeError(f"API HTTP {response.status_code}")
try:
result = response.json()
except ValueError:
raise RuntimeError("API response is not JSON") from None
if not isinstance(result, dict) or result.get("code") != 0:
code = result.get("code") if isinstance(result, dict) else None
raise RuntimeError(f"API failed: code={code}; check the docs")
data = result.get("data")
if not isinstance(data, dict):
raise RuntimeError("Unexpected data shape; inspect the docs")
inner = data.get("base_resp")
if isinstance(inner, dict) and inner.get("status_code") not in (0, "0"):
raise RuntimeError("Platform response was unsuccessful")
return result
def save_json(folder, name, value):
(folder / name).write_text(
json.dumps(value, ensure_ascii=False, indent=2), encoding="utf-8"
)
def require_list(data, key):
value = data.get(key)
if not isinstance(value, list):
raise RuntimeError(f"Expected a list at {key}; inspect saved JSON")
return value
def output_folder(topic):
if not TOKEN or TOKEN == "your_token":
raise RuntimeError("Set JUSTONEAPI_TOKEN before running")
run_id = datetime.now(timezone.utc).strftime("%Y%m%dT%H%M%S%fZ")
folder = Path(topic + "-output") / run_id
folder.mkdir(parents=True, exist_ok=False)
return folder
MAX_PAGES = 2
MAX_CREATORS = 3
SEARCH = "/api/xiaohongshu-pgy/api/solar/cooperator/blogger/v2/v1"
PROFILE = "/api/xiaohongshu-pgy/api/solar/cooperator/user/blogger/userId/v1"
AUDIENCE = "/api/xiaohongshu-pgy/api/solar/kol/data/userId/fans_profile/v1"
def main():
folder = output_folder("pugongying")
ids, seen = [], set()
for page in range(1, MAX_PAGES + 1):
result = call_api(
SEARCH, page=page, sort="FANS",
fansNumberLower=10000, fansNumberUpper=100000,
)
save_json(folder, f"search-{page}.json", result)
rows = require_list(result["data"], "kols")
if not rows:
break
previous_count = len(ids)
for row in rows:
uid = row.get("userId") if isinstance(row, dict) else None
if uid and str(uid) not in seen:
seen.add(str(uid))
ids.append(str(uid))
if len(ids) == previous_count:
break
selected = ids[:MAX_CREATORS]
save_json(folder, "selected-creators.json", selected)
summary = []
for index, uid in enumerate(selected, start=1):
profile = call_api(PROFILE, userId=uid)
save_json(folder, f"creator-{index}-profile.json", profile)
audience = call_api(AUDIENCE, userId=uid)
save_json(folder, f"creator-{index}-audience.json", audience)
data = profile["data"]
summary.append({
"userId": uid, "name": data.get("name"),
"fansCount": data.get("fansCount"),
"picturePrice": data.get("picturePrice"),
"videoPrice": data.get("videoPrice"),
"showPrice": data.get("showPrice"),
"audienceDate": audience["data"].get("dateKey"),
})
save_json(folder, "shortlist.json", summary)
print(f"Saved {len(selected)} creator samples to {folder}")
if __name__ == "__main__":
try:
main()
except RuntimeError as error:
raise SystemExit(str(error)) from NoneWork with the saved shortlist
Each run creates a dated folder under pugongying-output. selected-creators.json contains the selected IDs. shortlist.json summarizes names, follower counts, raw rates and audience dates. The individual creator-*-profile.json and creator-*-audience.json files retain full responses.
Review the shortlist before expanding enrichment to more creators. This keeps the relationship between candidate volume and request count clear. If you export CSV, leave unknown rates empty and track missing data separately so spreadsheet totals do not treat unknown rates as zero cost.
Common questions
Can I skip search if I already have an ID?
Yes. Use the corresponding Pugongying userId to request the profile and follower distribution directly. Names can change or be shared by multiple creators; IDs are better join keys.
What should I do with missing rates or audience fields?
Distinguish a failed API request from a successful response with a null field or an empty list. The script stops on a business error and retains the successful responses already saved. It does not convert a failure into a valid creator record.
How can I keep the data updated?
Add scheduling and incremental storage around this workflow. Store snapshots by userId and retrieval time, retain the search filters, and set explicit page, concurrency and retry limits. See the API failure and retry guide before adding retries.
Start with one page in the creator search documentation, then generate a shortlist using your own criteria.
Continue with Just One API
Log in to the Dashboard for your token, read the full API docs, or open the MCP GitHub project for the latest configuration.