mpWeixin relay agent protocol Base URL: https://x-gateway.empjs.dev Endpoints: health: GET https://x-gateway.empjs.dev/healthz article draft: POST https://x-gateway.empjs.dev/api/v1/article-draft batch upload: POST https://x-gateway.empjs.dev/api/v1/batch-upload newspic draft: POST https://x-gateway.empjs.dev/api/v1/newspic-draft Auth headers: Content-Type: application/json X-Relay-Token: optional, required when relay auth is enabled Wechat-Appid: optional, only when caller must select account Wechat-App-Secret: optional, only when caller must select account Default rules for agents: - Default to draft creation. Do not direct-publish unless the user explicitly asks. - Treat response field code == 0 as success. - On failure, report HTTP status, code, and msg/error exactly. - All image inputs must be public URLs or data/local mappings supported by the request schema. Do not send local file paths as plain URLs. - If WeChat returns 40164 invalid ip ... not in whitelist, the relay server egress IP is not in the WeChat Official Account IP whitelist. 1. Article draft from Markdown POST https://x-gateway.empjs.dev/api/v1/article-draft Request body: { "markdown": "# Title\n\nBody", "coverImageUrl": "https://cdn.example.com/cover.jpg", "publish": false } Required: - markdown: article Markdown. First "# heading" is used as title. - coverImageUrl: public cover image URL. Optional: - publish: boolean. false means draft only. true submits publish after draft creation. curl: curl -X POST "https://x-gateway.empjs.dev/api/v1/article-draft" \ -H "Content-Type: application/json" \ -H "X-Relay-Token: " \ -d '{"markdown":"# Title\n\nBody","coverImageUrl":"https://cdn.example.com/cover.jpg","publish":false}' 2. Article draft from prepared HTML POST https://x-gateway.empjs.dev/api/v1/article-draft Request body: { "title": "Title", "digest": "Short summary", "html": "

Body

", "coverImageUrl": "images/a.png", "assetBaseUrl": "https://cdn.example.com/assets", "localAssetMap": { "images/a.png": "https://cdn.example.com/assets/a.png" }, "publish": false } Required: - title - digest - html - coverImageUrl, or an image resolvable through localAssetMap / assetBaseUrl / html images Optional: - author - content_source_url - need_open_comment: 0 or 1 - only_fans_can_comment: 0 or 1 - assetBaseUrl: base URL used to resolve relative image paths - localAssetMap: map from local/relative image src to public URL or data URL - publish 3. Batch upload POST https://x-gateway.empjs.dev/api/v1/batch-upload Request body: { "imageUrls": [ "https://cdn.example.com/a.jpg", "https://cdn.example.com/b.png" ] } curl: curl -X POST "https://x-gateway.empjs.dev/api/v1/batch-upload" \ -H "Content-Type: application/json" \ -H "X-Relay-Token: " \ -d '{"imageUrls":["https://cdn.example.com/a.jpg","https://cdn.example.com/b.png"]}' 4. Newspic draft POST https://x-gateway.empjs.dev/api/v1/newspic-draft Request body: { "title": "Title", "content": "Body", "imageUrls": [ "https://cdn.example.com/1.jpg", "https://cdn.example.com/2.jpg" ] } curl: curl -X POST "https://x-gateway.empjs.dev/api/v1/newspic-draft" \ -H "Content-Type: application/json" \ -H "X-Relay-Token: " \ -d '{"title":"Title","content":"Body","imageUrls":["https://cdn.example.com/1.jpg"]}' Success response shape: { "code": 0, "msg": "success", "data": { "draft_id": "MEDIA_ID", "media_id": "MEDIA_ID", "mode": "newspic", "rendered_as": "xiaolvshu-draft", "warnings": [], "published": false } } Important: - "/api/v1/newspic-draft" creates a dedicated WeChat "newspic" draft through "cgi-bin/draft/add". - Request contract: non-empty title, non-empty content, and 1-20 public image URLs. - The relay uploads each image as a permanent WeChat asset before creating the draft.