# What do mid, idx and sn mean in a WeChat article link, and why are there two link formats?

> A long WeChat article link names the account (__biz), the push (mid), the article's slot (idx) and a signature (sn); the short /s/ link hides all four. What to keep, drop and dedupe on.

Canonical page: https://okdata.online/answers/wechat-article-link-mid-idx-sn/

**Short answer: **In a long link, __biz is the account, mid is one push (群发) from that account, idx is the article's position in that push (1 is the lead article) and sn is a signature that has to match the other three. The short mp.weixin.qq.com/s/ form points at the same article without showing them. okdata's article detail accepts both for $0.02 and returns the long form, using sn as the article's id.

WeChat article links come in two shapes. The long one, which you get from a browser address bar, an account's history page or most scrapers, looks like `mp.weixin.qq.com/s?__biz=MzA5NTI3MjIwMA==&mid=2650412873&idx=2&sn=8c1f0e5a3d9b47e6a2c4f17b0d9e3a65&chksm=…&scene=21#wechat_redirect`. The short one, which WeChat increasingly hands out when you share or copy a link, is `mp.weixin.qq.com/s/` plus a short code. Both open the same article. The trouble starts when one data set mixes them: the same article counts twice, a join on URL misses, and a feed reader announces an old post again because its link changed form.

## The four parameters that matter

| Parameter | Example | Meaning |
|---|---|---|
| `__biz` | `MzA5NTI3MjIwMA==` | The Official Account; see [what __biz is](/answers/wechat-biz-parameter/) |
| `mid` | `2650412873` | One push (群发) from that account; unique within the account |
| `idx` | `2` | The article's position in that push: 1 is the lead article (头条), 2 the second, and so on |
| `sn` | 32 hexadecimal characters | A signature that goes with the three above; WeChat checks it, so a link with a missing or altered `sn` usually fails to open |

`__biz` + `mid` + `idx` pin down one article. `sn` makes the link valid. Everything else is session or tracking data you can drop: `chksm` (a checksum that changes from fetch to fetch), `scene`, `sessionid`, `key`, `pass_ticket`, `#rd`, `#wechat_redirect`. A clean long link keeps `__biz`, `mid`, `idx` and `sn` and nothing more.

## Two practical traps

- **`&amp;` in links.** Links pulled out of HTML or RSS often have `&amp;` (sometimes `&amp;amp;`) between parameters. Replace it with `&` before you parse or send the link.
- **No offline conversion.** A short code cannot be turned into `mid`/`idx`/`sn` without fetching the article. Fetch once, store the long form or its `sn`, and dedupe on that.

## How the API handles both

[Official Account article detail](/apis/wechat_mp/articles/get/) takes either form as `url`. It returns the full text, title, account and publish time, and a `url` that is normally the long form. The article's `id` is its `sn` when the link has one, otherwise `__biz`, `mid` and `idx` joined with underscores, so the same article normally gets the same `id` whichever link you started from. [Article history](/apis/wechat_mp/accounts/articles/list/) returns long links, with each article's `idx` as `ext.position`.

| Task | Calls | Cost |
|---|---|---|
| One short or long link to full text | 1 | $0.02 |
| A sheet of 400 mixed links | 400 | $8.00 |
| 1,000 links | 1,000 | $20.00 |

## Example: clean, fetch, dedupe

```python
import html, os, requests
from urllib.parse import urlparse, parse_qs, urlencode

def clean(link):
    link = html.unescape(html.unescape(link))          # &amp;amp; -> &
    q = parse_qs(urlparse(link).query)
    keep = {k: q[k][0] for k in ("__biz", "mid", "idx", "sn") if k in q}
    return "https://mp.weixin.qq.com/s?" + urlencode(keep) if len(keep) == 4 else link

seen = {}
for link in ["https://mp.weixin.qq.com/s/k3Vq8ZtYwLr2PxN0aHd5Fg",
             "http://mp.weixin.qq.com/s?__biz=MzA5NTI3MjIwMA==&amp;mid=2650412873&amp;idx=2&amp;sn=8c1f0e5a3d9b47e6a2c4f17b0d9e3a65&amp;chksm=bc2f"]:
    r = requests.get("https://api.okdata.online/v1/wechat_mp/articles/get",
                     headers={"Authorization": f"Bearer {os.environ['OKDATA_API_KEY']}"},
                     params={"url": clean(link), "fields": "id,url,title,published_at"}, timeout=60)
    item = r.json()["data"]["item"]
    seen.setdefault(item["id"], item)
print(len(seen), "unique articles")
```

## Limits

- Deleted articles, and articles removed after a complaint, return `not_found`, which is not charged.
- Read and like counts are not part of article detail; `metrics` fields are null and `meta.unavailable` says why.
- More on pulling text out of article links in [full text from a mp.weixin.qq.com link](/answers/wechat-article-full-text-from-link/).

## Endpoints used

- [Official Account article detail](https://okdata.online/apis/wechat_mp/articles/get/) `wechat_mp.articles.get`: $0.02 per call

## More about WeChat Official Accounts

- [WeChat Official Accounts API](https://okdata.online/apis/wechat_mp/)
- [WeChat Official Account API in Python for RAG (2026)](https://okdata.online/guides/wechat-official-account-api-python/)
- [How to get a WeChat Official Account's articles and full text](https://okdata.online/guides/wechat-official-account-articles/)
- [Why do Jina Reader and other web readers fail on WeChat article links?](https://okdata.online/answers/ai-cant-read-wechat-article-link/)
- [Why can't ChatGPT or Claude read a WeChat article link, and how do I fix it?](https://okdata.online/answers/ai-read-wechat-article-link/)
- [How do I export all articles of a WeChat Official Account without logging in?](https://okdata.online/answers/export-wechat-official-account-articles/)
- [How do I monitor competitors' WeChat Official Accounts for new articles?](https://okdata.online/answers/monitor-competitor-wechat-official-accounts/)
- [Why are some fields empty in my social data API results, and do I still pay?](https://okdata.online/answers/null-fields-still-charged/)
- [How do I get past WeChat's 200013 freq control error when fetching Official Account articles?](https://okdata.online/answers/wechat-200013-freq-control/)
- [Official platform APIs vs third-party data APIs (2026)](https://okdata.online/compare/official-apis-vs-data-apis/)
- [MCP servers for social media data: self-hosted vs hosted](https://okdata.online/compare/social-media-data-mcp-servers/)
- [WeChat article APIs: official vs third-party vs open-source (2026)](https://okdata.online/compare/wechat-article-data-apis/)
- [Ways to get WeChat Official Account data: the official API, RSS bridges and data APIs](https://okdata.online/compare/wechat-official-account-data-apis/)
- [Xiaohongshu, Douyin and WeChat MCP servers: self-hosted vs hosted](https://okdata.online/compare/xiaohongshu-douyin-wechat-mcp-servers/)

## Sources

- [V2EX: a WeChat article is identified by biz + mid + idx, and mid is unique within one account](https://www.v2ex.com/t/474105) (read 2026-11-12)
- [ClearURLs rules: a WeChat article link only needs __biz, mid, idx and sn; the rest is tracking (issue #13)](https://github.com/ClearURLs/Rules/issues/13) (read 2026-11-12)
- [Same WeChat article pushed twice when a feed switches between long and short links (rss2telegram issue #18)](https://github.com/Hootrix/rss2telegram/issues/18) (read 2026-11-12)
- [WeChat link with &amp;amp; escaping fails to open from Python (Stack Overflow)](https://stackoverflow.com/questions/65606060/how-can-use-python-get-this-url-from-wechat) (read 2026-11-12)

Where people asked this (read 2026-11-12): 

- https://github.com/ClearURLs/Rules/issues/13
- https://github.com/Hootrix/rss2telegram/issues/18
- https://stackoverflow.com/questions/65606060/how-can-use-python-get-this-url-from-wechat
- https://www.v2ex.com/t/474105

Updated 2026-11-12
