How to get a WeChat Official Account's articles and full text
Three endpoints in order: Official Account search to turn a name into its original ID (gh_…), Official Account article history to list its articles 10 per call, and Official Account article detail for the full text. The worked example below is 9 calls and costs $0.74, with the search counted at a full page; a failed call is not charged.
Updated
The job: you follow a competitor, a trade publication or a regulator on WeChat, and you want its recent articles in a form you can work with: titles, dates and reads in a table, and the complete text of the pieces that matter. Inside WeChat that means scrolling the account's history on a phone. Here it is three calls in a row: find the account, list its articles, fetch the ones you want in full. You end with a CSV of the article list and a text file per article.
No WeChat account, QR scan or cookie is involved. Each call is an HTTPS request with your key.
Step by step
Step 1: find the account
Official Account search takes query, the account's name or a keyword. Each result has id, the original ID (gh_ plus 12 characters), username (the WeChat ID, when the account has one), name, avatar_url and followers. With view=full, ext adds biz (the __biz value in the account's links), last_published_at and articles_per_week, which help you tell the real account from a lookalike.
curl -G "https://api.okdata.online/v1/wechat_mp/accounts/search" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'query=极客公园' \
--data-urlencode 'view=full' \
--data-urlencode 'fields=id,name,username,ext.last_published_at'
This is the one endpoint priced per item: $0.058 for each account returned, so at most $0.58 for a full page of 10. An exact account name usually returns one or a few matches and costs a fraction of that; a broad word fills the page. While the search runs, the full-page amount is held from your balance and the unused part is released right after. On a balance below a full page, the first page shrinks to the accounts your balance covers.
Check name before you keep an id; the right account is not always first. If you already know the gh_ ID or the WeChat ID, skip this step entirely. Finding an account's gh_ ID shows the free manual way too.
Step 2: list its articles
Official Account article history takes id, the gh_ ID from step 1 or the WeChat ID, and returns 10 articles per call, newest first, for $0.02. Each has title, url (the mp.weixin.qq.com link), published_at, the summary in text, the cover in images, and metrics.views and metrics.likes where WeChat shows them. With view=full, ext.position tells you where the article sat in that day's push: 1 is the headline.
curl -G "https://api.okdata.online/v1/wechat_mp/accounts/articles/list" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'id=gh_7c2a9e41b05d'
For older articles, send page.next_cursor back as cursor, unchanged, until page.has_more is false. Five pages cover about the last 50 articles.
Step 3: fetch the full text
Official Account article detail takes the article link as url and returns the body for $0.02. text is the article as plain text, paragraphs and headings on their own lines, inline images dropped; the cover stays in images. You also get title, published_at and author (the account's gh_ ID and name). With view=full, ext.author_byline is the writer named under the title, and ext.copyright and ext.source_url help you spot reposts.
curl -G "https://api.okdata.online/v1/wechat_mp/articles/get" \
-H "Authorization: Bearer $OKDATA_API_KEY" \
--data-urlencode 'url=https://mp.weixin.qq.com/s/Qm3xK7pVd2LrT9wYfZc1aB'
Reads and likes are null on the detail; take them from the history list.
Step 4: put it together in Python
The script finds the account by exact name, lists five pages, saves the list to CSV and fetches the three most-read articles as text files.
import csv
import os
import re
import requests
API = "https://api.okdata.online"
HEADERS = {"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"}
NAME = "极客公园"
HISTORY_PAGES = 5 # 10 articles per page, one call each
FULL_TEXT = 3 # articles to fetch in full
def get(path, **params):
body = requests.get(API + path, headers=HEADERS, params=params, timeout=90).json()
if body["code"] != "ok":
raise RuntimeError(f"{body['code']}: {body['message']} (charged: {body['charged']})")
return body
accounts = get("/v1/wechat_mp/accounts/search", query=NAME)["data"]["items"]
account = next((a for a in accounts if a["name"] == NAME), None)
if account is None:
raise SystemExit(f"no exact match; got {[a['name'] for a in accounts]}")
articles, cursor = [], None
for _ in range(HISTORY_PAGES):
body = get("/v1/wechat_mp/accounts/articles/list", id=account["id"], **({"cursor": cursor} if cursor else {}))
articles += body["data"]["items"]
if not body["page"]["has_more"]:
break
cursor = body["page"]["next_cursor"]
with open("articles.csv", "w", newline="", encoding="utf-8-sig") as f:
out = csv.writer(f)
out.writerow(["published_at", "title", "reads", "likes", "url"])
for a in articles:
out.writerow([a["published_at"], a["title"], a["metrics"]["views"], a["metrics"]["likes"], a["url"]])
for a in sorted(articles, key=lambda a: a["metrics"]["views"] or 0, reverse=True)[:FULL_TEXT]:
full = get("/v1/wechat_mp/articles/get", url=a["url"])["data"]["item"]
with open(re.sub(r"[^\w-]", "_", full["id"]) + ".txt", "w", encoding="utf-8") as f:
f.write(f"{full['title']}\n{full['published_at']}\n{full['url']}\n\n{full['text']}\n")
If reads are null for this account, sort by date instead and take the newest. A whole 500-article history with full text would be $11.00 after the search.
Good to know
- Reads and likes are not always there. The history list fills
metrics.viewsandmetrics.likeswhere WeChat shows them; otherwise they are null andmeta.unavailablegives the reason. Comments, shares and saves are not available. - Follower counts are estimates.
followersin search comes from a third-party database, not from WeChat, andext.followers_notesays so. - Deleted is free. An article taken down after it was listed returns
not_foundand costs nothing. - 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. - Trial credit. A new key's $0.10 covers only part of a search page, so the first search may return fewer accounts than a full page. Start from a known WeChat ID, or top up first.
- Rights. The articles belong to their authors. Use them for research and monitoring, and keep the source link when you quote.
To export a whole account rather than recent articles, see how to export all articles of an Official Account. For a running watch on several accounts, see monitoring competitor Official Accounts.
What the example costs
One name search for 极客公园 (GeekPark), five pages of its article history (about 50 articles), then the full text of the 3 most-read
| Endpoint | Calls | Price | Subtotal |
|---|---|---|---|
| Official Account search | 1 | $0.058 / item | $0.58 |
| Official Account article history | 5 | $0.02 | $0.10 |
| Official Account article detail | 3 | $0.02 | $0.06 |
| Total | 9 | $0.74 |
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.
SayFind the WeChat Official Account 极客公园, list its last 50 articles with title, date and reads, and give me the full text of the three most-read ones.
What the agent sends to the call tool first
{
"endpoint": "wechat_mp.accounts.search",
"params": {
"query": "36氪"
},
"idempotency_key": "<a new UUID>"
}