Explore our Marketplace to buy and sell APIs, services, and social media solutions. Connect with a vibrant community of developers, businesses, and creators!
business_type 字符串键切换,传关键词即可。no_more 文案非空即为正常空结果,raw=true / raw=false 都在顶层;raw=false 时另有 count=0 + items=[]。仍按一次正常调用计费)。docID / feedNonceId 等为 64 位大整数,超出 JavaScript 安全整数范围(2^53-1)。请始终以字符串方式接收 / 传递这类 ID(解析 JSON 用 json-bigint 或按文本取值),勿让其经过 JS Number。Swagger UI 文档页对超大整数会末位舍入显示,属正常现象,不影响接口实际返回的数据。人民日报all。垂类字符串键(共 18 个)。实测有结果:综合 all / 公众号·服务号·视频号 account / 文章 article / 视频 video / 表情 sticker。其余键 underline / encyclopedia / live_stream / comment / listen / news / photos / book / moments / image / mini_game / weixin_index / ai_search 由服务端按账号与地区下发,当前实测恒空。传列表外的值将直接报错(422)。default。排序(结果页「排序」下拉,综合与各垂类通用)—— 不限(相关性) default/0 / 最新(发布时间降序) latest/1 / 最热(点赞降序) hot/2,字符串键或整数均可,非法值报错(400)。all。发布时间(结果页「时间」下拉,通用)—— 不限 all/0 / 最近一天 day/1 / 最近七天 week/2 / 最近半年 half_year/3,字符串键或整数均可,非法值报错(400)。0;翻页请用 cursor,只传 offset 无效(每页都回到第一页)。cursor 原样传回(须同时重复上一页的 sort / publish_time),配合 continue_flag 判断是否还有下一页。/fetch_search_videos(business_type=video + duration)。video / all)的视频结果项不直接含媒体,只给 exportId(+ jumpInfo.extInfo.feedNonceId)。要下载 / 解密:取 exportId → 走视频号 V2 接口 /api/v1/wechat_channels/v2/fetch_video_detail(传 export_id)拿 media(url / url_token / decode_key)和明文 username。完整链路与解密说明见该接口文档。jumpInfo.userName(gh_…)可喂给公众号 V2 接口 /api/v1/wechat_mp/v2/fetch_account_profile / fetch_account_articles。raw=false(精简解析,snake_case):$.data.keyword$.data.business_type$.data.total —— 响应里所有 box 与 subBox 的 totalCount 全扫取最大值(垂类的 totalCount 挂在 subBoxes 上;综合搜索没有单一总数,给的是最大的那个 box)。零结果时为 null(没有任何正数 totalCount),恒空垂类恒为 null$.data.continue_flagcursor 参数取下一页): $.data.cursor$.data.offset$.data.count$.data.items[]business_type=all 时有值,其余为 null): $.data.categories[] —— 每项 .type / .word / .extra_kvs,这是当前账号真正可用垂类的权威来源。注意 .type 是垂类的整数码(如 33554499),而本接口的 business_type 只收上面那 18 个字符串键,整数会被拒(422)—— 需自行按键表映射(如 33554499 → account)$.data.no_more(有值 = 微信返回的正常空结果,不是调用失败)account 公众号示例):<em> 高亮): $.data.items[N].title$.data.items[N].desc$.data.items[N].docID$.data.items[N].accTypeName$.data.items[N].jumpInfo(.userName = gh_…、.nickName、.signature)exportId(+ jumpInfo.extInfo.feedNonceId)→ 见上「典型链路」raw=true(原始,本接口默认):data 顶层: keyword / business_type / results(不做 items 拍平)/ total / continue_flag / offset / cursor / categories / no_more(total / categories / no_more 两种模式都在顶层,字段集已对齐)$.data.results$.data.results.data[],每个 box 的结果在 $.data.results.data[M].items[] 与 $.data.results.data[M].subBoxes[K].items[] —— 即 raw=false 的 items[] 是把这些拍平后的结果。$.data.continue_flag(raw=true / raw=false 均在顶层)$.data.cursor —— 原样回传接口的 cursor 参数取下一页;$.data.offset 仅为服务端 offset,单独传回无法翻页$.data.total(raw 两种模式都有)—— 它是 $.data.results.data[M].totalCount 与 $.data.results.data[M].subBoxes[K].totalCount 全扫取的最大值;垂类的数字挂在 subBoxes 上,只读顶层 box 的 totalCount 会拿到 nullraw=false(items 已拍平),路径更干净。business_type string key — just pass a keyword.no_more is the universal signal (top level in both raw=true and raw=false); raw=false additionally gives count=0 + items=[]. Still billed as a normal call.docID / feedNonceId in the response are 64-bit big integers beyond JavaScript's safe-integer range (2^53-1). Always receive / pass such IDs as strings (parse JSON with json-bigint or read them as text), never through JS Number. Swagger UI rounds the trailing digits of huge integers in its docs view — this is expected and does not affect the actual data returned by the API.人民日报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).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).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).0 for the first page; use cursor to paginate — offset alone does not work (it returns the first page every time).cursor returned in the previous response (repeat the same sort / publish_time), and use continue_flag to check whether there are more pages./fetch_search_videos (business_type=video + duration).video / all) do not contain media directly — only exportId (+ jumpInfo.extInfo.feedNonceId). To download / decrypt: take exportId → call the Channels V2 endpoint /api/v1/wechat_channels/v2/fetch_video_detail (pass export_id) to get media (url / url_token / decode_key) and the plain username. See that endpoint's docs for the full chain and decryption notes.jumpInfo.userName (gh_…) of official account result items can be fed into the MP V2 endpoints /api/v1/wechat_mp/v2/fetch_account_profile / fetch_account_articles.raw=false (simplified, snake_case):$.data.keyword$.data.business_type$.data.total — the maximum totalCount scanned across every box and subBox (a vertical's totalCount hangs off subBoxes; 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$.data.continue_flagcursor parameter for the next page): $.data.cursor$.data.offset$.data.count$.data.items[]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 .type is the vertical's integer code (e.g. 33554499) while this endpoint's business_type accepts only the 18 string keys above — an integer is rejected (422), so map it yourself (e.g. 33554499 → account).$.data.no_more (present = a legitimate empty result from WeChat, not a failed call)account example):<em> highlight): $.data.items[N].title$.data.items[N].desc$.data.items[N].docID$.data.items[N].accTypeName$.data.items[N].jumpInfo (.userName = gh_…, .nickName, .signature)exportId (+ jumpInfo.extInfo.feedNonceId) → see "Typical chains" aboveraw=true (raw, default for this endpoint):data top level: keyword / business_type / results (items are not flattened) / total / continue_flag / offset / cursor / categories / no_more (total / categories / no_more are top level in both modes — the key sets are aligned)$.data.results$.data.results.data[]; each box's results are in $.data.results.data[M].items[] and $.data.results.data[M].subBoxes[K].items[] — the items[] of raw=false is the flattened merge of these.$.data.continue_flag (top level for both raw=true / raw=false)$.data.cursor — pass it back as the cursor parameter for the next page; $.data.offset is only the server-side offset and passing it back alone does not paginate$.data.total (present in both raw modes) — it is the maximum of $.data.results.data[M].totalCount and $.data.results.data[M].subBoxes[K].totalCount; a vertical's number hangs off subBoxes, so reading only the top-level box's totalCount yields nullraw=false (items already flattened) for cleaner paths.curl --location 'https://api.tikhub.io/api/v1/wechat_search/v2/fetch_search' \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '{
"keyword": "人民日报",
"business_type": "all",
"sort": 0,
"publish_time": 0,
"offset": 0,
"cursor": "string",
"raw": true
}'{
"code": 200,
"request_id": "string",
"message": "Request successful. This request will incur a charge.",
"message_zh": "请求成功,本次请求将被计费。",
"support": "Discord: https://discord.gg/aMEAS8Xsvz",
"time": "string",
"time_stamp": 0,
"time_zone": "America/Los_Angeles",
"docs": "string",
"cache_message": "string",
"cache_message_zh": "string",
"cache_url": "string",
"router": "",
"params": {},
"data": null
}