Getting Started
Read public Weibo posts, comments, profiles, search results and the hot-search list as structured JSON. No Weibo account and no developer application — just your FetchLayer key.
1. Get your API key
Create an account and generate a FetchLayer API key from your dashboard. The same key works on every platform.
Create free account →2. See what is trending
The hot-search list (热搜) needs no input. Every topic comes with its rank, its exact heat score and when it joined the list.
curl -X POST https://api.fetchlayer.dev/weibo/trending \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"limit":20}'Paid placements are left out
includePromoted: true includes them, marked isPromoted. 3. Search posts
By keyword, or wrap a topic in # to search the topic. The default tab, latest, returns every matching post newest first, 50 to a page; since and until limit the period.
curl -X POST https://api.fetchlayer.dev/weibo/search-posts \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"query":"#华为#","since":"2026-10-01","until":"2026-10-07","limit":100}'Page back with the cursor
hasMore is true and nextCursor carries an opaque value. Pass it back as cursor, with the same query, tab and since, to keep going back in time. Each 50 posts returned is 1 credit, minimum 1. Tabs top, hot and videos are Weibo's ranked picks, one page per time range. These are the posts Weibo's public search shows, which can leave out posts Weibo filters from search, and search has no region filter. Long posts are shortened in results (textTruncated); /post-detail returns the full text.
4. Read an account
By numeric id, profile link, custom address or display name. The follower count comes back exact, alongside the reposts, comments and likes the account has received across all its posts.
curl -X POST https://api.fetchlayer.dev/weibo/user-profile \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"user":"https://weibo.com/sinatech"}'An account's posts, newest first
/user-posts returns an account's posts newest first, 50 a page, and nextCursor pages back through roughly its newest 2,000. mediaOnly: true lists only its posts with photos or video, which reach further back. A post's mediaTruncated is true when a list showed fewer pictures than it has; /post-detail returns every one. 5. Read the comments
By post link, numeric id or short id, most-liked first or newest first. Each comment carries its likes, reply count, a few inline replies and the province the commenter posted from; /comment-replies reads every reply under one.
curl -X POST https://api.fetchlayer.dev/weibo/post-comments \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"post":"https://weibo.com/6420207784/RmOx7c1Yt","sort":"hot","limit":100}'Very large threads stop at a few hundred
notes says so. totalCount is Weibo's own count, which includes replies. 6. Photos and video
Weibo's own media links open only from Weibo's pages, so every asset carries a downloadUrl pointing at GET /weibo/media, which opens anywhere and supports Range.
curl -L "https://api.fetchlayer.dev/weibo/media?url=https%3A%2F%2Fwx1.sinaimg.cn%2Fmw2000%2F0070uxksgy1ii3aj0oaluj30wr1ii104.jpg" \
-H "Authorization: Bearer ss-your-key" \
--output photo.jpgWhat a download costs
/media costs 1 credit, and each range request counts as one. A link that has expired is a 404: read the post again for a fresh one. Resolving a pasted link
When you are handed a Weibo address and do not know what it points at, /resolve-url tells you — post, account, search or topic — with its ids and the route that reads it. It fetches nothing and is free.
curl -X POST https://api.fetchlayer.dev/weibo/resolve-url \
-H "Authorization: Bearer ss-your-key" \
-H "Content-Type: application/json" \
-d '{"url":"https://weibo.com/6420207784/RmOx7c1Yt"}'Errors and retries
A 400 names the field to fix, first in the message (post: not a Weibo post: 0. …); unrecognised fields are rejected rather than ignored. A 404 means the post, comment or account does not exist or is not public, and the message names it. A 503 is worth retrying after a short wait; when it is your own timeoutMs running out, it carries the header X-Timeout-Source: caller. A 502 means Weibo answered with something that could not be used.
Error responses
Every error, on every route, is JSON in one shape: error (what went wrong, in words), status, code, retryable and requestId, which also comes as the X-Request-Id header. Branch on code and retryable rather than on the text; on a 5xx the text is generic. Quote requestId when reporting a problem.
{
"error": "Missing required parameter: url",
"status": 400,
"missing": ["url"],
"code": "invalid_input",
"retryable": false,
"requestId": "922874e3-c0d0-40d8-8866-d198af132420"
}| code | Status | Retryable | Meaning |
|---|---|---|---|
| invalid_input | 400 | no | The request needs fixing; error names the field. A missing required parameter also lists it in missing. |
| unauthorized | 401 | no | The API key is missing or not valid. |
| insufficient_credits | 402 | no | Nothing left to spend: no credits, a used-up free trial, or a monthly allowance and credit balance both spent. error says which. Waiting does not help; topping up does. |
| forbidden | 403 | no | This key or account is not allowed this request. |
| not_found | 404 | no | What the request names does not exist or is not public. |
| expired | 410 | no | What the request refers to is no longer available; ask for it afresh. |
| quota_exceeded | 429 | no | A request-rate limit was reached; error says which. Slow down before sending more. |
| cancelled | 499 | no | The caller closed or cancelled the request before it finished. The work was stopped and nothing was charged. |
| time_limit | 503 | yes | Your timeoutMs ran out before there was anything to return; ask again, or allow more time. |
| temporarily_unavailable | 503 | yes | Not available right now; ask again shortly. |
| store_unreachable | 503 | yes | Store routes (Shopify, WooCommerce): the store itself can’t be reached right now — it may be offline. Ask again later. Where a store route doesn’t say so yet, an offline store is temporarily_unavailable. |
| upstream_error | 502 | yes | The source answered in a way that could not be used; ask again later. |
| internal_error | 500 | yes | Something failed on our side; ask again later, and quote requestId if it persists. |
| tool_error | — | no | MCP only: a tool call failed in a way no other code describes; error says what. |
More codes may be added; treat one you do not recognise by its retryable flag. Over MCP, a tool error carries the same fields in structuredContent, and as a JSON text block beside the message.