# Fixed reference example. Playground inputs do not update this sample.
curl --request POST \
--url https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"keyword": "People'"'"'s Daily"
}'curl --request POST \
--url https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"keyword": "People's Daily"
}
EOFimport requests
url = "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search"
payload = { "keyword": "People's Daily" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({keyword: 'People\'s Daily'})
};
fetch('https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'keyword' => 'People\'s Daily'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search"
payload := strings.NewReader("{\n \"keyword\": \"People's Daily\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"keyword\": \"People's Daily\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"keyword\": \"People's Daily\"\n}"
response = http.request(request)
puts response.read_body{
"cache_message": "This response is cached and accessible via the URL below for 24 hours at no extra cost. The cache is for request tracing only — it doesn't affect the API's data freshness and won't be returned through the API again.",
"cache_message_zh": "本次响应已缓存,可通过下方 URL 直接查看,有效期 24 小时,访问缓存链接无额外费用。缓存仅用于请求溯源,不影响接口数据的时效性,也不会再次通过接口返回。",
"cache_url": "<string>",
"code": 200,
"data": "<unknown>",
"docs": "<string>",
"message": "Request successful. This request will incur a charge.",
"message_zh": "请求成功,本次请求将被计费。",
"params": {},
"request_id": "<string>",
"router": "",
"support": "Discord: https://discord.gg/aMEAS8Xsvz",
"time": "<string>",
"time_stamp": 123,
"time_zone": "America/Los_Angeles"
}wechat_search fetch_search
WeChat Universal Search
# Fixed reference example. Playground inputs do not update this sample.
curl --request POST \
--url https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"keyword": "People'"'"'s Daily"
}'curl --request POST \
--url https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data @- <<EOF
{
"keyword": "People's Daily"
}
EOFimport requests
url = "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search"
payload = { "keyword": "People's Daily" }
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.post(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'POST',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({keyword: 'People\'s Daily'})
};
fetch('https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "POST",
CURLOPT_POSTFIELDS => json_encode([
'keyword' => 'People\'s Daily'
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search"
payload := strings.NewReader("{\n \"keyword\": \"People's Daily\"\n}")
req, _ := http.NewRequest("POST", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.post("https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"keyword\": \"People's Daily\"\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Post.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"keyword\": \"People's Daily\"\n}"
response = http.request(request)
puts response.read_body{
"cache_message": "This response is cached and accessible via the URL below for 24 hours at no extra cost. The cache is for request tracing only — it doesn't affect the API's data freshness and won't be returned through the API again.",
"cache_message_zh": "本次响应已缓存,可通过下方 URL 直接查看,有效期 24 小时,访问缓存链接无额外费用。缓存仅用于请求溯源,不影响接口数据的时效性,也不会再次通过接口返回。",
"cache_url": "<string>",
"code": 200,
"data": "<unknown>",
"docs": "<string>",
"message": "Request successful. This request will incur a charge.",
"message_zh": "请求成功,本次请求将被计费。",
"params": {},
"request_id": "<string>",
"router": "",
"support": "Discord: https://discord.gg/aMEAS8Xsvz",
"time": "<string>",
"time_stamp": 123,
"time_zone": "America/Los_Angeles"
}code is 200.
Example
curl -X POST "https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search" \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}' # see request schema below
Request contract
- Method and path: POST /apis/v1/tikhub/wechat_search/v2/fetch_search
- Availability: enabled
- Request URL template:
https://api.aisa.one/apis/v1/tikhub/wechat_search/v2/fetch_search - Runtime facts: 85ae03121f63417c9ff9d57a0fd59fdc6386fd71e2dc732a002843e6d8979d87
{
"operationId": "post_tikhub_wechat_search_v2_fetch_search",
"method": "POST",
"path": "/apis/v1/tikhub/wechat_search/v2/fetch_search",
"servers": [
{
"url": "https://api.aisa.one"
}
],
"parameters": [],
"security": [
{
"bearerAuth": []
}
],
"requestBody": {
"content": {
"application/json": {
"schema": {
"properties": {
"business_type": {
"default": "all",
"description": "ai_search) are gated server-side per account & region and currently always come back empty (count=0 plus a no_more message — still billed as a normal call). Use the `categories` field of an `all` search for the authoritative per-account tab list. Values outside this list are rejected (422\n\nUsage: Optional, default `all`. Vertical string key (18 total). **Verified to return data**: `all` / `account` / `article` / `video` / `sticker`. The rest (`underline` / `encyclopedia` / `live_stream` / `comment` / `listen` / `news` / `photos` / `book` / `moments` / `image` / `mini_game` / `weixin_index` / `ai_search`) are gated server-side per account & region and currently always come back empty. Any value outside this list is rejected (422).",
"enum": [
"all",
"account",
"article",
"video",
"sticker",
"underline",
"encyclopedia",
"live_stream",
"comment",
"listen",
"news",
"photos",
"book",
"moments",
"image",
"mini_game",
"weixin_index",
"ai_search"
],
"example": "account",
"title": "Business Type",
"type": "string"
},
"cursor": {
"description": "Optional. Pagination cursor. Leave empty for the first page; for the next page pass back the `cursor` returned in the previous response (repeat the same `sort` / `publish_time`), and use `continue_flag` to check whether there are more pages.",
"title": "Cursor",
"type": [
"string",
"null"
]
},
"keyword": {
"description": "Search keyword, 1-100 characters after trimming. For account searches, use the account display name.",
"example": "People's Daily",
"maxLength": 100,
"minLength": 1,
"title": "Keyword",
"type": "string"
},
"offset": {
"default": 0,
"description": "Optional, default 0 (>=0). Pass `0` for the first page; **use `cursor` to paginate — offset alone does not work** (it returns the first page every time).",
"minimum": 0.0,
"title": "Offset",
"type": "integer"
},
"publish_time": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"default": "all",
"description": "Optional, default `all`. Publish time (result page \"time\" dropdown, common) — `all`/0 / `day`/1 / `week`/2 / `half_year`/3; string key or integer, invalid values rejected (400).",
"example": "week",
"title": "Publish Time"
},
"raw": {
"default": true,
"description": "True=raw search response; False=simplified parsed structure",
"title": "Raw",
"type": "boolean"
},
"sort": {
"anyOf": [
{
"type": "integer"
},
{
"type": "string"
}
],
"default": "default",
"description": "Optional, default `default`. Sort (result page \"sort\" dropdown, common to all verticals) — `default`/0 (relevance) / `latest`/1 (newest) / `hot`/2 (most liked); string key or integer, invalid values rejected (400).",
"example": "hot",
"title": "Sort"
}
},
"required": [
"keyword"
],
"title": "FetchSearchRequest",
"type": "object"
}
}
},
"required": true
},
"x-aisa-status": "enabled",
"x-aisa-pricing": {
"cost_contract": "fixed_success",
"customer_multiplier": 1.0,
"customer_pricing": "provider_cost_multiplier",
"default_request_estimate_usd": 0.01,
"estimate_source": "profile_seed",
"evidence_source": "request_snapshot"
},
"components": {
"securitySchemes": {
"bearerAuth": {
"scheme": "bearer",
"type": "http"
}
}
}
}
Cost and request rules
Published reference price: $0.01 USD per successful request. Account-specific pricing and final settlement may differ. Published reference values are not an account-specific quote or a settled charge. For endpoints supporting X-AISA-Cost-Mode: quote, obtain a free quote for your exact request before execution; reconcile the settled cost with response metadata and Usage Logs. USD amounts use 1,000,000 integer micro-USD per dollar.- Default request reference estimate (USD): 0.01
- Cost contract: fixed_success
- Published reference multiplier: 1.0
- Settlement evidence source: request_snapshot
Authorizations
Bearer authentication header of the form Bearer <token>, where <token> is your auth token.
Body
Search keyword, 1-100 characters after trimming. For account searches, use the account display name.
1 - 100"People's Daily"
ai_search) are gated server-side per account & region and currently always come back empty (count=0 plus a no_more message — still billed as a normal call). Use the categories field of an all search for the authoritative per-account tab list. Values outside this list are rejected (422
Usage: Optional, default all. Vertical string key (18 total). Verified to return data: all / account / article / video / sticker. The rest (underline / encyclopedia / live_stream / comment / listen / news / photos / book / moments / image / mini_game / weixin_index / ai_search) are gated server-side per account & region and currently always come back empty. Any value outside this list is rejected (422).
all, account, article, video, sticker, underline, encyclopedia, live_stream, comment, listen, news, photos, book, moments, image, mini_game, weixin_index, ai_search "account"
Optional. Pagination cursor. Leave empty for the first page; for the next page pass back the cursor returned in the previous response (repeat the same sort / publish_time), and use continue_flag to check whether there are more pages.
Optional, default 0 (>=0). Pass 0 for the first page; use cursor to paginate — offset alone does not work (it returns the first page every time).
x >= 0Optional, default all. Publish time (result page "time" dropdown, common) — all/0 / day/1 / week/2 / half_year/3; string key or integer, invalid values rejected (400).
"week"
True=raw search response; False=simplified parsed structure
Optional, default default. Sort (result page "sort" dropdown, common to all verticals) — default/0 (relevance) / latest/1 (newest) / hot/2 (most liked); string key or integer, invalid values rejected (400).
"hot"
Response
Successful response. The outer object follows ResponseModel; the endpoint-specific payload is in data.
Return
- Search result list (structure varies slightly by vertical)
Response structure & JSON Path
raw=false (simplified, snake_case):
- Keyword echo:
$.data.keyword - Effective vertical code (e.g. account=33554499):
$.data.business_type - Total results:
$.data.total— the maximumtotalCountscanned across every box and subBox (a vertical'stotalCounthangs offsubBoxes; the All tab has no single total, so this is the largest contributing box). null on a zero-result page (no positive totalCount anywhere), so it is always null for the always-empty verticals - Has next page:
$.data.continue_flag - Pagination cursor (pass back as the
cursorparameter for the next page):$.data.cursor - Server-side offset (informational only; passing it back alone does not paginate):
$.data.offset - Results on this page:
$.data.count - Flattened result item list (items of all boxes / subBoxes merged):
$.data.items[] - Server-issued vertical tab list (only present for
business_type=all, null otherwise):$.data.categories[]— each entry has.type/.word/.extra_kvs. This is the authoritative list of verticals actually available to the serving account. Note.typeis the vertical's integer code (e.g. 33554499) while this endpoint'sbusiness_typeaccepts only the 18 string keys above — an integer is rejected (422), so map it yourself (e.g. 33554499 →account). - Server wording for a zero-result page:
$.data.no_more(present = a legitimate empty result from WeChat, not a failed call) - Single item (N is the index; fields vary by vertical; below is an
accountexample):- Title (with
<em>highlight):$.data.items[N].title - Description:
$.data.items[N].desc - Document id:
$.data.items[N].docID - Type name:
$.data.items[N].accTypeName - Jump info:
$.data.items[N].jumpInfo(.userName=gh_…,.nickName,.signature) - Video vertical items also carry
exportId(+jumpInfo.extInfo.feedNonceId) → see "Typical chains" above
- Title (with
raw=true (raw, default for this endpoint):
datatop level:keyword/business_type/results(items are not flattened) /total/continue_flag/offset/cursor/categories/no_more(total/categories/no_moreare top level in both modes — the key sets are aligned)- Full result set:
$.data.results - Result box array:
$.data.results.data[]; each box's results are in$.data.results.data[M].items[]and$.data.results.data[M].subBoxes[K].items[]— theitems[]ofraw=falseis the flattened merge of these. - Has next page:
$.data.continue_flag(top level for bothraw=true/raw=false) - Pagination cursor:
$.data.cursor— pass it back as thecursorparameter for the next page;$.data.offsetis only the server-side offset and passing it back alone does not paginate - Read the total from the top level
$.data.total(present in both raw modes) — it is the maximum of$.data.results.data[M].totalCountand$.data.results.data[M].subBoxes[K].totalCount; a vertical's number hangs offsubBoxes, so reading only the top-level box'stotalCountyields null - For result iteration, prefer
raw=false(items already flattened) for cleaner paths.
Cache message (EN-US)
Cache message (ZH-CN)
The URL to access the cached result
HTTP status code
Endpoint-specific response payload. The official shared model does not declare a fixed type or field set. Use the operation's documented return fields or response example; an operation-specific schema, when present, describes the documented fields. Undocumented fields must be read from the actual response rather than assumed.
Link to the API Swagger documentation for this endpoint
Response message (EN-US)
Response message (ZH-CN)
The parameters used in the request
Unique request identifier
The endpoint that generated this response
Support message
The time the response was generated
The timestamp the response was generated
The timezone of the response time