
How to Integrate WeChat `addMaterial`
A guide to WeChat permanent media upload, covering server-side rules, file limits, media types, and common mistakes.
If you are building WeChat publishing automation, another question appears quickly:
How should the permanent media upload API addMaterial be integrated, and which limits matter in practice?
This looks like a basic upload problem. It is not. The hard parts are usually the rules around media type, file size, downstream usage, and the difference between permanent assets and article-body images.
Official WeChat reference:
What addMaterial does
The official API name is:
addMaterialThe endpoint is:
POST https://api.weixin.qq.com/cgi-bin/material/add_material?access_token=ACCESS_TOKEN&type=imageIt uploads files as permanent WeChat materials, including:
- images
- voice
- video
- thumbnails
If you are assembling a publish pipeline, this usually sits before draft creation because many later steps depend on WeChat-recognized media ids.
Rule one: call it from the server only
The official docs are explicit:
This API must be called from the server, not directly from a frontend such as a webpage, mini-program, or app client.
The correct structure is:
- the frontend hands a file or file reference to your server
- the server prepares
access_token - the server calls
addMaterial - the server stores the returned
media_idand metadata
If you try to turn permanent media upload into a browser-side request, the integration model is already wrong.
type is required and changes validation
The most important query parameters are:
access_tokentype
type is required and supports:
imagevoicevideothumb
This is not a passive category field. It controls how WeChat validates the upload.
That means:
- you cannot send a video as
image - you should not treat a thumbnail as a generic image
- your own backend should validate by
typebefore sending the request upstream
File limits should be enforced before the API call
The official constraints are:
image: up to 10MB, supportsbmp/png/jpeg/jpg/gifvoice: up to 2MB, no more than 60 seconds, supportsmp3/wma/wav/amrvideo: up to 10MB, onlyMP4thumb: up to 64KB, onlyJPG
In practice, the most common failures are:
- a thumbnail larger than 64KB
- a video that is not MP4
- a voice file longer than 60 seconds
- a backend that skips local validation and lets WeChat reject the file
A stronger implementation rejects obviously invalid files before the upstream request.
Video uploads are not identical to image uploads
The media field is required in form-data across media types, but video uploads also need description.
That object looks like this:
{
"title": "Video title",
"introduction": "Video introduction"
}If your backend tries to flatten everything into one generic media-upload wrapper, video handling is where it usually breaks.
The returned image URL is not a general-purpose public asset URL
This is one of the easiest rules to misread.
For permanent images, the API returns a URL, but that URL is intended for Tencent-domain usage and can be blocked outside the Tencent ecosystem.
So this assumption is wrong:
If addMaterial returns a URL, the image can be used as a universal public CDN link.
It is suitable for WeChat-side usage. It is not a general replacement for your own public asset hosting.
Article-body images are a different problem
This is the other major integration mistake.
The official docs state that:
- external image links in article bodies can be filtered
- article-body images should use the dedicated article-image upload interface
- those article images do not consume the permanent image library quota
- article-body images only support
jpg/pngand must be under 1MB
That creates a strict distinction:
Permanent materials
Better for:
- cover images
- thumbnail-like assets
- material-library scenarios
Article-body images
Better for:
- inline images inside the article content
- images that must survive WeChat body rendering correctly
Do not treat those as one upload path.
The permanent material library has quotas
The official limits are:
- up to
100000article/image materials - up to
1000materials for other types
So if you are building a batch publishing system, do not design as if the material library were an infinite store.
A better system usually asks:
- does this file really need to become a permanent material
- can an existing material be reused
- should usage and origin be tracked on the business side
A stable debugging order
When addMaterial fails, the safer order is:
- confirm the call is server-side
- confirm
access_tokenis valid - confirm
typematches the real file type - confirm format, size, and duration limits locally
- add
descriptionfor video uploads - decide whether this asset belongs in permanent materials or the article-image workflow
That order catches most real failures faster than staring at the final error string.
Closing thought
addMaterial is not hard because multipart upload is hard. It is hard because media type, usage boundary, and downstream rendering are easy to mix together.
If you separate permanent materials from article-body images and validate each media type before upload, the integration becomes much more predictable.
Author
Categories
addMaterial doesRule one: call it from the server onlytype is required and changes validationFile limits should be enforced before the API callVideo uploads are not identical to image uploadsThe returned image URL is not a general-purpose public asset URLArticle-body images are a different problemPermanent materialsArticle-body imagesThe permanent material library has quotasA stable debugging orderClosing thoughtMore Posts

WeChat ClawBot Can Talk to OpenClaw: I Used md2wechat Skill to Write and Publish from a Chat Window
A practical article about WeChat ClawBot, OpenClaw, and md2wechat Skill: how a chat window becomes the entrypoint for article drafting, WeChat formatting, cover generation, and draft publishing.

obsidian-md2wechat: Convert Obsidian Notes into WeChat Layouts
An overview of the obsidian-md2wechat plugin, including installation, theme support, and the Obsidian-first workflow it fits.

How to Use md2wechat-skill in Claude Code, Codex, and OpenCode
A practical comparison of how md2wechat-skill fits Claude Code, Codex, and OpenCode, with install steps, discovery commands, and reusable prompts.
Newsletter
Join the community
Subscribe to our newsletter for the latest news and updates