{"openapi":"3.1.0","info":{"title":"青鸾企业微信开放平台 API","description":"青鸾企业微信能力开放平台。通过稳定的 HTTP API 调用企业微信能力：实例托管、消息收发、联系人 / 群聊 / 标签管理、朋友圈、文件与回调。\n\n## 对接须知\n\n### 接入流程\n\n1. 注册并登录开发者控制台 <https://open.qingluanbot.com>。\n2. 在「实例与回调」一键扫码登录企业微信，获得实例标识 `appid`。\n3. 在「API Key」创建一个 Key（请求时通过请求头携带）。\n4. 用 `API Key` + `appid` 调用业务接口。\n5. 如需接收消息 / 事件，配置 Webhook 回调地址（见下方「Webhook 回调服务」）。\n\n### 基础约定\n\n- **统一 API 地址**：`https://api.qingluanbot.com`\n- **请求**：`POST /qingluan/api/{模块}/{动作}`，`Content-Type: application/json`\n- **鉴权**：请求头 `QL-Key: <你的 API Key>`（也支持 `Authorization: Bearer <key>`）\n- **实例**：请求体携带 `appid`（**所有接口必填**），它决定这次调用发给哪个企业微信号。\n  不传返回 `400`。请求体统一使用 `appid`，不要同时传入多个实例标识字段。\n- **响应**：**原样返回**，不额外包装信封。\n\n### ⚠️ `code = 0` 的确切含义\n\n`code = 0` 表示**请求被接受**，不保证副作用一定发生。个别接口在参数缺失或有误时\n仍会返回 `code = 0`（例如发送类接口 `content` 结构不对时，会在会话里留下一条空消息）。\n\n**建议**：发送前自行校验必填字段；对结果敏感的操作，用对应的查询接口复核一次\n（发消息用「拉取消息」，群操作用「获取群资料」，朋友圈用「查询朋友圈详情」）。\n\n### 媒体文件：先上传，再发送\n\n图片 / GIF / 语音 / 文件不能直接传 URL 或二进制，要分两步 ——\n**上传接口返回的 `data`，整体作为发送接口的 `content`**，字段逐个对应，不需要自己拼：\n\n| 要发什么 | 第一步 | 第二步 |\n|---|---|---|\n| 图片 | `api/cdn/uploadImage` | `api/message/sendImage`，`content` = 上一步的 `data` |\n| GIF | `api/cdn/uploadImage` | `api/message/sendGif`，`content` = 上一步的 `data` |\n| 文件 | `api/cdn/uploadFile` | `api/message/sendFile`，`content` = 上一步的 `data` |\n| 语音 | `api/cdn/uploadFile` | `api/message/sendVoice`，`content` = 上一步的 `data` **加 `voiceTime`** |\n\n### ⚠️ 大整数精度（JS 客户端必读）\n\n响应里的 `roomId` / `conversationId` / `uin` 是 17~19 位整数，超过 JavaScript 的\n`Number.MAX_SAFE_INTEGER`（9007199254740991）。浏览器 `JSON.parse` 会**静默**取近似值\n（例：`10952820944829695` 变成 `10952820944829696`），末位出错且不抛异常。\n\nJS / TypeScript 客户端必须用 `JSON.parse` 的 reviver、或按文本正则取值，不要直接 parse 后当数字用。\n这是「原样返回」的固有代价：转成字符串就不叫原样了。\n\n### 调用频率限制\n\n每个开发者账号 **每分钟 300 次**（按账号计，不按 Key —— 开多把 Key 不会增加额度）。\n\n超限返回 **HTTP 429**，业务码 `-42900`，并带标准的 `Retry-After` 头（单位：秒）：\n\n```json\n{ \"code\": -42900, \"message\": \"调用过于频繁，请 N 秒后重试。…\", \"data\": null }\n```\n\n正确的处理方式是**读 `Retry-After` 并退避**，不要立刻重试 —— 立刻重试只会继续消耗额度。\n\n> 这个额度是按实际用量定的：现网每分钟调用量 p99 是 7 次、历史峰值 26 次，\n> 300 已是十倍以上余量，正常业务不会碰到。触发它通常意味着**你的客户端在重试循环里**。\n> 如果你的业务确实需要更高频率（批量导入、历史数据回填等），联系客服单独调整，\n> 不必自己想办法绕。\n\n### 这几个接口有额外行为\n\n参数和返回都与其余接口一致，直接调即可；差别在于青鸾会在中间多做一步，\n免得你自己再搭一遍：\n\n| 接口 | 青鸾额外做了什么 |\n|---|---|\n| `api/device/create` | 先校验你的账号额度与有效期，建成后把 `appid` 登记到你名下 —— 不登记的话它过不了后续接口的归属校验，等于建了个用不了的设备 |\n| `api/long/start`、`api/long/updateCallbackURL` | 你传的 `callbackUrl` 会被记为**你的**接收地址；报给能力层的是青鸾的接收器。事件先到青鸾，再**带青鸾签名**转发给你，并附带失败重投与去重。你收到的包体结构见「回调（事件推送）」 |\n| `api/long/stop` | 关闭后青鸾的定时探活不会再自动把它拉起来；下次调 `api/long/start` 即恢复自动维护 |\n\n> `callbackUrl` 必须是可公网访问的 http(s) 地址，且不能填青鸾自己的接收地址。\n\n### 错误码\n\n青鸾自己产生的错误一律用**负数** `code`，不会和能力层的业务码混淆（能力层的码见各接口说明）。\nHTTP 状态与 `code` 一一对应，判断其一即可。\n\n| `code` | HTTP | 含义 | 怎么处理 |\n| :--- | :--- | :--- | :--- |\n| `401` | 401 | API Key 缺失、无效或已撤销 | 检查请求头 `QL-Key` |\n| `-40001` | 400 | 缺少 `appid`，或请求体不是 JSON 对象 | 补上 `appid`；确认 `Content-Type: application/json` |\n| `-40002` | 400 | 实例标识字段名不对，或同时传了多种写法且值不一致 | 只传一个 `appid` |\n| `-40004` | 400 | 请求路径含义不明确（多余斜杠、点段等） | 用规范路径 `/qingluan/api/{模块}/{动作}` |\n| `-40010` | 400 | 配置回调时缺少 `appid` | 补上 `appid` |\n| `-40011` | 400 | `callbackUrl` 不是 http(s) 地址 | 换成 http(s) 开头的完整地址 |\n| `-40012` | 400 | 回调地址填成了青鸾的接收地址 | 填你自己服务的公网地址 |\n| `-40013` | 400 | 回调地址不可用：域名解析不到，或落在内网 / 环回地址 | 换一个可公网访问的地址 |\n| `-40402` | 402/403 | 账号额度已满或权益过期（建设备时） | 到控制台查看剩余额度与有效期，或联系客服 |\n| `-40403` | 403 | 在不支持的接口上传了 `callbackUrl` / `pushHistory` | 回调地址只在 `api/long/start`、`api/long/updateCallbackURL` 与 `POST /qingluan/instances/set-callback` 上有效 |\n| `-40404` | 404 | `appid` 不存在或不属于你 | 核对控制台「实例与回调」里的值 |\n| `-42900` | 429 | 调用过于频繁 | 按响应头 `Retry-After` 退避；确需更高频率请联系客服 |\n| `-50000` | 502 | 回调登记失败 | 稍后重试 |\n| `-50002` | 502 | 服务暂时不可用（超时 / 网络异常 / 未就绪） | 退避重试；持续失败请联系客服 |\n\n⚠️ **`-40404` 对「不存在」和「不属于你」是同一句话**，这是有意的：区分开等于给攻击者一个\n枚举探针，可以拿别人的 `appid` 试出哪些是真实存在的。\n\n### Webhook 回调服务\n\n事件走**中转**，不是直连：\n\n```\n企业微信 ──▶ 青鸾接收器 ──┬──▶ 回调日志（控制台，原样留存 24 小时）\n                              └──▶ 转发到你的地址（青鸾信封 + HMAC 签名）\n```\n\n企业微信事件只推给青鸾接收器 —— 这个地址一号一个、扫码上号时自动注册、**不可更改也不可关闭**。\n它是回调日志、归属校验、掉线自动重连三件事的共同前提。\n\n> ⚠️ **回调只有入站。** 你自己通过接口发出去的消息**不会**产生回调 —— 这是正常的，\n> 不是回调丢了。要确认自己发的消息，用 `api/message/sync` 拉取。\n\n**配置转发地址**（三选一，优先级从高到低）：\n\n| 方式 | 作用范围 |\n|---|---|\n| 控制台「实例与回调」→ 某个实例「配置回调」 | 只这个号 |\n| 控制台「实例与回调」→ 账号默认转发地址 | 所有没单独配的号 |\n| `POST /qingluan/instances/set-callback`（body: `appid` + `callbackUrl`） | 只这个号 |\n\n**请求鉴权（可选）**：在控制台配置回调地址时，可以开启 Bearer 鉴权并填写由你自己\n管理的 Token。开启后，青鸾的每次回调 POST 都会携带：\n\n```http\nAuthorization: Bearer <你配置的 Token>\n```\n\nToken 会加密保存，保存后不再回显；留空表示保持原 Token，关闭鉴权或清空对应回调地址\n会同时清除它。实例没有独立回调地址时，会连同地址和签名密钥一起继承账号默认配置。\nBearer 鉴权与下方 HMAC 验签彼此独立，开启 Bearer 后仍会保留全部 HMAC 请求头。\n\n**保存时的测试回调**：在控制台保存非空回调地址时，青鸾会立即向该地址直发一次\n`QingluanCallbackTest`，正文事件内容固定为“青鸾回调测试”。测试请求沿用正式回调的\nHMAC 请求头；如果该地址开启了 Bearer 鉴权，也会携带相同的 `Authorization` 请求头。\n\n实例回调测试会携带该实例的真实 `appid`：\n\n```json\n{\n  \"appid\": \"<实例 appid>\",\n  \"event_type\": \"QingluanCallbackTest\",\n  \"test\": true,\n  \"events\": [\n    {\n      \"id\": \"cbtest_<唯一值>\",\n      \"content\": \"青鸾回调测试\",\n      \"created_at\": \"<UTC ISO 8601 时间>\"\n    }\n  ]\n}\n```\n\n账号默认回调不对应某一个实例，因此测试正文不含任何实例标识：\n\n```json\n{\n  \"event_type\": \"QingluanCallbackTest\",\n  \"test\": true,\n  \"events\": [\n    {\n      \"id\": \"cbtest_<唯一值>\",\n      \"content\": \"青鸾回调测试\",\n      \"created_at\": \"<UTC ISO 8601 时间>\"\n    }\n  ]\n}\n```\n\n这是一条一次性连通性测试：不进入正式投递队列、不自动重试，也不出现在回调预览里。\n配置会先保存；即使测试超时、连接失败或目标返回非 2xx，也不会回滚。界面显示测试成功\n只表示目标返回了 2xx，不代表目标一定已经完成验签或业务处理。\n\n**转发信封**：\n\n```json\n{\n  \"appid\": \"<与业务接口用的是同一个值>\",\n  \"event_type\": \"Msg\",\n  \"events\": [ ... ]\n}\n```\n\n`event_type` 是事件类型（见下方「事件类型」）。一个地址收多个号时，按 `appid` 区分。\n\n**验签**（可选，不验也能正常收）：请求头 `X-Qingluan-Timestamp`（Unix 秒）与\n`X-Qingluan-Signature`。\n\n```\nsignature = HMAC-SHA256(key   = callback_secret 的 UTF-8 字节,\n                        msg   = timestamp 的 ASCII 字节 + b\".\" + 原始请求体字节)\n            的十六进制小写\n```\n\n三个容易签错的地方：\n\n1. **`timestamp` 和一个点号也在被签的消息里**，不是只签请求体。\n2. 用**收到的原始字节**，不要先反序列化再重新序列化 —— 键顺序和空格一变签名就对不上。\n3. `callback_secret` 直接当 UTF-8 字节做密钥，不做 base64 / hex 解码。\n\n**固定测试向量**（拿它先把本地实现校准了，再去接真实回调）：\n\n| 项 | 值 |\n|---|---|\n| `callback_secret` | `whsec_demo` |\n| `X-Qingluan-Timestamp` | `1757000000` |\n| 原始请求体 | `{\"appid\":\"we_demo\",\"event_type\":\"Msg\",\"events\":[]}` |\n| 期望签名 | `cc555c9b81e1c9652c00df7d53e2e6711996d614df665dbe3dab0454fa48f41b` |\n\n**时间窗**：我方**不限制** `X-Qingluan-Timestamp` 的新旧（重试最长可能在 6 小时后到达，\n卡窗会把正常重投判成伪造）。建议你按自己的容忍度校验，取 **±10 分钟**是常见选择；\n重投场景下请以事件去重为主、时间窗为辅。\n\n密钥在控制台可见，账号级与实例级各有一个，与地址成对使用。轮换密钥后，\n**尚未送达的重试会用新密钥签名** —— 旧密钥不再保留。\n\n**投递保证：至少一次（at-least-once）**\n\n- 投递失败（超时、连接失败、非 2xx）会按 **30 秒 / 2 分 / 10 分 / 30 分 / 2 小时 / 6 小时**\n  退避重投，共 6 次；**只有 2xx 才算送达**（3xx 不算 —— 我们不跟随跳转）。\n- 6 次都失败进**死信**，可在控制台「回调投递」里查看并手动重放。\n- 因此**同一条事件你可能收到多次**（重投、或平台自身重推）。请按 `events[].id`\n  做幂等；没有 `id` 的事件（如 `GapClosed`）按你自己的业务键去重。\n- 请**先落库再回 200**。你回了 2xx 我们就认为送到了，不会再投第二次。\n\n### 事件类型\n\n`event_type`（一级事件，标明这一包是什么）：\n\n| event_type | 含义 |\n|---|---|\n| `Msg` | 消息 / 群事件，具体看 `events[].contentType` |\n| `GapConnected` / `GapSucceed` | 长连接已建立 / 就绪 |\n| `GapClosed` | 长连接断开，`code` 见下表 |\n| `BigFileUploadCompleted` / `BigFileUploadFailed` | 大文件上传结果 |\n| `Error` | 错误 |\n| `InstanceOffline` / `InstanceRecovered` | **青鸾自己发的**账号状态变化，见下方「账号状态事件」 |\n\n`GapClosed` 的 `code`：\n\n| code | 含义 | 账号是否还在线 |\n|---|---|---|\n| `-11001` | 需断线重连后判断 | **可能仍在线**，青鸾会自动重连确认 |\n| `-11002` | 已在其他设备上登录 | 否 |\n| `-1008` | 移动端主动退出登录 | 否 |\n| `-1` | 长连接异常，见 `message` | 否 |\n| `0` | 用户手动关闭长连接 | 否 |\n\n### 账号状态事件（青鸾自产）\n\n上面那些是能力层推给你的。`InstanceOffline` / `InstanceRecovered` 不一样，\n是**青鸾在探测到账号状态变化时自己发的** —— 因为能力层**会静默断**：\n连接掉了却不发 `GapClosed`，只表现为消息突然不来了。青鸾每分钟探一次，\n断了先自动尝试免扫码重连（沿用登录时的同一出口），救不回来才通知你。\n\n信封与其他事件完全一致，你已有的解析和按 `events[].id` 的幂等逻辑不用改：\n\n```json\n{\n  \"appid\": \"we_xxxxxxxxxxxxxxx\",\n  \"event_type\": \"InstanceOffline\",\n  \"events\": [{\n    \"id\": \"InstanceOffline:we_xxxxxxxxxxxxxxx:1757500000\",\n    \"reason\": \"长连接中断，自动重连未成功\",\n    \"action_required\": \"relogin\",\n    \"detected_at\": \"2026-09-10T13:31:00+00:00\",\n    \"last_seen_at\": \"2026-09-10T12:56:36+00:00\"\n  }]\n}\n```\n\n`action_required` 决定你该怎么处理：\n\n| 值 | 含义 | 该做什么 |\n|---|---|---|\n| `relogin` | 长连接断了，登录态多半还在 | 到控制台点「重新登录」，通常免扫码 |\n| `manual` | 风控 / 已在其他设备登录 / 手机端主动退出 | **必须重新扫码**。这类反复重连会加重风控，青鸾已停止自动重试 |\n\n`InstanceRecovered` 的 `events[]` 带 `recovered_at`、`offline_seconds`\n（本次中断时长）和 `auto_reconnected`（是否由青鸾自动救回）。\n\n⚠️ 只在**状态翻转**时各推一条，不会每轮重复推。短暂抖动被当轮重连救回的，\n不会打扰你。\n\n`events[].messageType`（会话维度）：`0`=私聊 · `1`=群聊 · `3`=应用/系统会话。\n⚠️ **不要用 `roomId != 0` 判群聊** —— `messageType=3` 的 `roomId` 与 `fromUserId` 同值，\n用它判会把应用会话误判成群聊。一律以 `messageType` 为准。\n\n`events[].contentType`（消息类型）：\n\n| | |\n|---|---|\n| **文本** | `0` `2` 文本（`content` 是 `[{type,text}]` 数组） |\n| **媒体** | `14` `101` 图片 · `16` 语音 · `23` `103` 视频 · `15` `102` 文件 · `20` 大文件 · `29` `104` 表情 |\n| **富消息** | `13` 链接 · `6` 位置 · `41` 名片 · `78` 小程序 · `4` 聊天记录 · `26` 红包 · `215` 笔记 · `579` 会议卡片 · `10` 邮件通知 |\n| **群事件** | `1001` 修改群名 · `1002` 成员进群 · `1003` 移除群成员 · `1005` 退群 · `1006` 群新增 · `1011` 群操作提示 · `1022` 群设置/群主变更 · `1023` 群解散 · `1029` 进群邀请申请 · `1043` 群管理员变动 · `2118` 群信息变动 · `213` 群接龙 · `2308` 群公告变更 · `2063` 撤回 |\n| **通话** | `2324` 通话通知 · `40` 通话结果 · `2350` 通话结束 · `2412` 通话记录提示 · `503` `2120` `2166` 通话信令 |\n| **其它** | `2001` 已读回执 · `2357` 好友申请 |\n| **纯信令** | `2002` `2055` `2104` `2114` `2115` `2130` `2131` `2132` `2160` `2161` `2180` `2186` `2188` `2201` `2215` `2313` —— `content` 为空，无可读内容，建议直接过滤 |\n\n三条要点，照做能少走弯路：\n\n0. **进出群事件靠载荷形态区分**：`1002` 成员进群与 `1003` 移除群成员同构\n   （`fromUserId`=操作者，`content`=被操作成员的 uid）；`1005` 退群则\n   `fromUserId`=**退群者本人**、`content`**为空**。\n   ⚠️ `1006` 是**群新增**、不是退群，别拿它判退群。\n   ⚠️ `2118` 群信息变动的 `content` 是空的，**但它不是无意义的信令** ——\n   例如微信成员自己退群就会推它。别按\"载荷为空\"一律过滤掉。\n\n1. **群系统事件的正文是 protobuf，句子的主语是一个数字 id，不是文字。**\n   例：`1022` 群主变更解出来是 `{1: <userId>, 2: \"已经成为新的群主\"}` ——\n   光读文字看不出是谁。**只有 id，没有名称**，要显示成人名得自己拿 id 去查成员资料。\n2. **群公告的正文和事件是分开的两条。** 公告正文是一条 `contentType 2`（文本），\n   靠 `flag` 的 `0x10000` 位与普通消息区分；`contentType 2308`（群公告变更）\n   **只带那条公告消息的 id、不带正文** —— 想显示内容得拿这个 id 回查那条消息。\n3. **一次音视频通话会推 8~10 条事件**，不是一条。发起固定 3 条；结束按结局不同，\n   `contentType 40` 的正文就是结局本身：\n\n   | 结局 | `40` 的正文 | 是否有 `2412` | 总条数 |\n   |---|---|---|---|\n   | 主叫取消 | 对方已取消 | 否 | 8 |\n   | 被叫拒接 | 已拒绝 | 否 | 9 |\n   | 超时未接 | 未接听 | 否 | 9 |\n   | 接通后挂断 | 通话时长 | 是 | 10 |\n\n   `2350` 每种结局都会推，代表通话结束；`2412` **只在接通后**出现（录音与 AI 总结提示）。\n\n   **来电渠道不同，信令类型也不同**：企业微信内部通话是 `2120` + `503`；\n   **微信用户打来**是 `2166` + `503`，且**不推** `2350` 与 `2412`。\n   `503` 是两种渠道共有的那条，`2120`/`2166` 按渠道区分。\n   ⚠️ 两者**成对出现、内容相同** —— 请按通话会话号去重、只处理其一，\n   否则每通电话会重复计一次。\n\n4. **资料变更只推信令、不推内容。** 改备注 / 标签 / 描述 / 聊天标签，会收到\n   `2313` `2160` `2161` `2186` `2131` 等一串信令，但它们的 `content` 是**空的** ——\n   企业微信只告诉你「有东西变了」，不告诉你变成什么。要拿新值**必须收到信令后\n   主动调接口查**，别指望从回调里解析。\n\n5. **`2357` 好友申请的 `content` 是结构化字段**（不是 hex）：\n   `corpId` / `uin` / `corpName` / `customerName` / `source`。\n   其中 `source` 直接写明来源（例如 `微信`），是判断对方是不是微信用户最可靠的字段。\n\n### 接口清单\n\n左侧列出的是当前能力层已开放的接口。由于数据面是原样透传，**清单可能滞后于能力层** ——\n新增接口即使还没出现在文档里，也可以直接按 `POST /qingluan/api/{模块}/{动作}` 调用。\n","version":"3.2.0"},"paths":{"/qingluan/api/device/create":{"post":{"tags":["登录与扫码"],"summary":"创建设备","description":"创建一个设备，返回的标识用于后续扫码登录。⚠️ `version` 是**整数**，传 `0` 即可；传版本号字符串会被拒绝。","operationId":"ql_api_device_create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"type":{"type":"string","description":"设备类型，例如 `iPad`。\n\n**注意**：**必填且强校验**：缺失或空串直接 `code=-1 / type cannot be empty`。传 `iPad` 可用，其它取值未确认。（早期契约未把它标为必填，`contract_errors.missing_required` 已记录，现按实际补齐。）","examples":["iPad"],"title":"类型"},"name":{"type":"string","description":"名称/昵称\n\n**注意**：契约标 `required`，但**完全不传也返回 `code=0`**。至少在缺失时服务端不做校验。它究竟影响什么（设备显示名？风控画像？）未确认。","examples":["东皇太一"],"title":"名称"},"version":{"type":"integer","format":"int64","description":"版本号，**整数**，传 `0` 即可。","examples":[0]}},"required":["appid","type","name","version"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","type":"iPad","name":"示例名称","version":0}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"appid":{"type":"string","description":"设备实例 ID。由 `/api/device/create` 返回；登录后保持不变，可长期复用。\n\n**注意**：契约写「登录后保持不变，可长期复用」，容易被误读成「重复调用返回同一个」。**不是**：即使请求体里带了一个已有 appid，返回的仍是一个全新值。「保持不变」指的是**同一个实例在其生命周期内不变**，不是这个接口幂等。格式 `we_` + 15 位大小写字母数字（总长 18）。","title":"设备实例 ID","examples":["{{appid}}"],"minLength":1}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"appid":"{{appid}}"},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/login/getQr":{"post":{"tags":["登录与扫码"],"summary":"获取登录二维码","description":"获取登录二维码。返回的 `data.uuid` 用于后续「查询扫码状态」。\n\n⚠️ **要求长连接处于关闭状态**，否则返回 `please close long client`。长连接由青鸾统一管理，遇到该错误请在开发者控制台「实例与回调」重新上号。","operationId":"ql_api_login_getQr","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"proxy":{"type":"string","description":"代理地址，不用则传空串","examples":[""],"title":"代理地址"}},"required":["appid","proxy"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","proxy":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"imageBase64":{"type":"string","description":"二维码图片 Base64\n\n**注意**：未确认：图片格式、尺寸、有无 `data:` 前缀都没取到样本。注意它与个人二维码接口的字段名不同（那边叫 `data.base64`），不要混用解析代码。"},"uuid":{"type":"string","description":"登录会话标识。由 /api/login/getQr 返回，checkQr/submitQrCode 需带上","title":"登录会话 ID"},"refreshInterval":{"type":"integer","format":"int64","description":"二维码刷新间隔（秒）\n\n**注意**：契约标 integer/int64、描述「二维码刷新间隔（秒）」。**单位与是否强制刷新均未确认**，接入前请取样确认。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"imageBase64":"","uuid":"","refreshInterval":0},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/login/checkQr":{"post":{"tags":["登录与扫码"],"summary":"查询扫码状态","description":"轮询扫码状态。`status`：`-1` 未扫码 · `0` 可免扫码 · `1` 已扫待确认 · `2` 登录成功 · `4` 用户取消 · `10` 待输入验证码。⚠️ `-1` 是**尚未扫码**，不是二维码失效。","operationId":"ql_api_login_checkQr","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"proxy":{"type":"string","description":"代理地址，不用则传空串","examples":[""],"title":"代理地址"},"uuid":{"type":"string","description":"登录会话标识，由「获取登录二维码」返回。轮询状态与提交验证码时都要带上。","examples":["<session-uuid>"],"title":"登录会话 ID"}},"required":["appid","proxy","uuid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","proxy":"","uuid":"<session-uuid>"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"status":{"type":"integer","format":"int64","description":"登录状态。-1=未认证需扫码 0=可免扫码 1=已扫码待确认 2=认证成功 4=用户取消 10=待输入6位验证码\n\n**注意**：契约枚举 `-1/0/1/2/4/10` **未确认**，任何一个值都没有真机样本。实现登录轮询时建议对未知值做兜底，不要用穷举 switch 直接抛错。","title":"状态"},"uuid":{"type":"string","description":"登录会话标识。由 /api/login/getQr 返回，checkQr/submitQrCode 需带上","title":"登录会话 ID"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"status":0,"uuid":""},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/login/submitQrCode":{"post":{"tags":["登录与扫码"],"summary":"提交验证码","description":"扫码后若返回 status=10 才需要调用。无需验证码时返回 `-12019 qrcode_not_need_verify`。\n\n:::tip\n🔗 **调用关系**\n\n仅在 `checkQr` 返回 `status=10` 时调用；其他状态无需提交验证码。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_login_submitQrCode","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"code":{"type":"string","description":"业务状态码。通常 0 表示成功，非 0 表示失败或异常。响应码。**0=成功，-1=失败**\n\n**注意**：**更正**：这是用户收到的**6 位数字验证码**（字符串，契约 example `\"993416\"`），**不是业务状态码**。契约现有描述「业务状态码…0=成功，-1=失败」是同名字段的公共描述被误套上来的，会误导接入方填 `0`，需要平台确认后订正。","examples":["993416"],"title":"业务状态码"},"proxy":{"type":"string","description":"代理地址，不用则传空串","examples":[""],"title":"代理地址"},"uuid":{"type":"string","description":"登录会话标识，由「获取登录二维码」返回。","examples":["<session-uuid>"],"title":"登录会话 ID"}},"required":["appid","code","proxy","uuid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","code":"993416","proxy":"","uuid":"<request-uuid>"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/login/reconnect":{"post":{"tags":["登录与扫码"],"summary":"断线重连","description":"断线重连。\n\n⚠️ **返回码不代表连接已恢复**：本接口可能返回 `code = 0`，而长连接仍处于断开状态且不会自行恢复，需要重新扫码登录。判断账号是否可用请调用任一业务读接口，不要依据本接口的返回码。","operationId":"ql_api_login_reconnect","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"proxy":{"type":"string","description":"代理地址，不用则传空串\n\n**注意**：**契约内部矛盾**：`required` 里有它，但 example 里没有。不用代理时是必须传空串还是可省略未确认；建议按必填传 `\"\"`，与同组 `getQr`/`checkQr` 的 example 写法一致。","examples":[""],"title":"代理地址"}},"required":["appid","proxy"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","proxy":"socks5://username:password@182.40.201.95:22232"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/login/logout":{"post":{"tags":["登录与扫码"],"summary":"退出登录","description":"退出登录。\n\n:::tip\n🔗 **调用关系**\n\n退出前停止业务调用；退出后会话密钥失效，下一次登录必须重新扫码。\n:::\n\n:::danger\n⛔ **高风险操作**\n\n该操作会销毁当前会话密钥，无法通过断线重连恢复。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_login_logout","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/long/start":{"post":{"tags":["长连接"],"summary":"/api/long/start","description":"开启长连接。\n\n:::tip\n🔗 **调用关系**\n\n扫码登录成功 → 配置回调地址 → 开启长连接 → 等待 `GapConnected`/`GapSucceed`。\n:::\n\n:::warning\n⚠️ **调用注意**\n\n已连接时会返回 `code=-1, message=\"started\"`——这是**已在运行**而非失败，且会重置连接。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_long_start","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"callbackUrl":{"type":"string","description":"公网可访问的回调地址，只接受 POST；事件类型见回调包体的 `event_type` 字段。\n\n**注意**：只在**建连时登记一次**。已经连着的时候想换地址，必须用 `/api/long/updateCallbackURL`；用 `start` 换会连带重置连接。另外契约 example 里这个值被生成成了 `https://example.com/sample.jpg`（占位符错误，一张图片地址不可能是回调端点），**别照抄**，实际要填能接 POST 的接口地址。","examples":["https://example.com"],"title":"回调地址"},"pushHistory":{"type":"boolean","description":"是否推送历史消息。true=登录后补推历史，false=只推新消息\n\n**注意**：未确认。因为没有在「未连接」状态下建过连，`true` 会补推多少条、补推事件与增量事件在结构上是否有区别，都没有样本。","examples":[false]}},"required":["appid","callbackUrl","pushHistory"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","callbackUrl":"<省略>","pushHistory":false}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/long/stop":{"post":{"tags":["长连接"],"summary":"/api/long/stop","description":"关闭长连接。关闭后业务接口会返回 long connection closed；调用 getQr/checkQr 前必须先关。\n\n:::tip\n🔗 **调用关系**\n\n停止长连接 → 确认收到 `GapClosed` → 再执行二维码登录相关接口。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_long_stop","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/long/check":{"post":{"tags":["长连接"],"summary":"查询连接状态","description":"查询长连接状态。\n\n⚠️ **`code = 0` 不足以证明连接可用**：存在本接口返回 `0`、而同一时刻业务接口全部返回 `long connection closed` 的情况。确认账号是否在线请调用任一业务读接口（如「获取个人信息」）。\n刚调用过连接相关接口时，本接口会先返回非 `0`、约 3 秒后转为 `0` —— 那是连接尚在建立，请退避重试，不要据此判定断线。","operationId":"ql_api_long_check","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：为 `null`，**不含任何状态字段**。契约「接口无固定结构化返回数据」本身没写错，但必须补一句结论：因此**无法从返回值判断长链是否在线**。断开状态下的返回值未确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/long/updateCallbackURL":{"post":{"tags":["长连接"],"summary":"/api/long/updateCallbackURL","description":"登录时未配回调地址可用此接口补配。\n\n:::tip\n🔗 **调用关系**\n\n登录成功后可补充或更新回调地址；新地址需支持公网 POST。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_long_updateCallbackURL","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"callbackUrl":{"type":"string","description":"公网可访问的回调地址，只接受 POST；事件类型见回调包体的 `event_type` 字段。\n\n**注意**：写入的是一条长度 42 的 https 地址，被接受。**地址校验强度未确认**：会不会拒绝 `http://`、内网地址或不可达地址，没试。另外契约 example 里该值被生成成了 `https://example.com/sample.jpg`（占位符错误），别照抄。","examples":["https://example.com"],"title":"回调地址"}},"required":["appid","callbackUrl"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","callbackUrl":"<省略>"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"appid":{"type":"string","description":"设备实例 ID。由 `/api/device/create` 返回；登录后保持不变，可长期复用。","title":"设备实例 ID","examples":["{{appid}}"],"minLength":1},"callbackUrl":{"type":"string","description":"公网可访问的回调地址，只接受 POST；事件类型见回调包体的 `event_type` 字段。\n\n**注意**：**回显刚写入的地址**（连同 `data.appid` 一起）。这是本组唯一能确认回调配置写入结果的手段 —— `long/check` 的 `data` 是 `null`，读不出配置。","title":"回调地址"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"appid":"<省略>","callbackUrl":"<省略>"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sync":{"post":{"tags":["消息"],"summary":"拉取消息","description":"分页拉取消息。首次传 `syncKey: 0`，之后传上一页返回的 `syncKey`，直到 `isEnd` 为 true。","operationId":"ql_api_message_sync","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"limit":{"type":"integer","format":"int64","description":"单页条数。","examples":[100],"title":"分页大小","minimum":1},"syncKey":{"type":"integer","format":"int64","description":"同步游标，**整数**。首次传 `0`；不把返回的 `syncKey` 存下来回传，就会一直拉到同一页。","examples":[15875106],"title":"同步游标"}},"required":["appid","limit","syncKey"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","limit":100,"syncKey":15875106}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"count":{"type":"integer","format":"int64","description":"本次返回条数\n\n**注意**：是**本页实际返回条数**，不是总数。"},"isEnd":{"type":"boolean","description":"是否执行完成"},"list":{"type":["string","null"],"description":"数据列表"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"count":0,"isEnd":false,"list":"","syncKey":0},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendText":{"post":{"tags":["消息"],"summary":"发送文本","description":"向指定会话发送一条文本。返回的 `data.id` 就是撤回时要用的 `serverMsgId`。","operationId":"ql_api_message_sendText","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[1688000000000004],"title":"会话 ID"},"content":{"type":"string","description":"消息正文，纯文本字符串。","examples":["测试消息"],"title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":"[示例] 1/文本","conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理\n\n**注意**：格式不统一。自发消息是 base64 串，但同步接口里能看到形如 `wwdailyindustrynews_appinfo_<时间戳>`、纯字母短串、带竖线分隔的队列串等多种形态。**不要假设它是 base64 并去解码**，当不透明字符串存即可。"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"内容片段类型：`0` 文本、`3` 表情、`5` @ 提及。","title":"类型"},"text":{"type":"string","description":"文本内容。"}}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":[{"text":"[示例] 1/文本","type":0}],"contentType":0,"flag":83886080,"fromUserId":1000000000000001,"id":1001241,"messageType":1,"roomId":"10000000000000006","sendTime":1788423357,"senderName":"小艺","syncKey":44527013,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendRichText":{"post":{"tags":["消息"],"summary":"发送富文本","description":"发送富文本。`content` 是**数组**，每段形如 `{type, text}`。目前只有 `type: 0`（纯文字段）可用，其他取值会被拒绝。","operationId":"ql_api_message_sendRichText","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[1688000000000004],"title":"会话 ID"},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"内容片段类型：`0` 文本、`3` 表情、`5` @ 提及。","examples":[0],"title":"类型"},"text":{"type":"string","description":"文本内容；`type=0` 或 `type=3` 时使用。","examples":["你好"]}},"required":["type"]},"description":"富文本片段数组。⚠️ 每段的 `type` **只接受 `0` 和 `3`**，`1` / `2` / `4` 都会返回「不支持的富文本类型」。","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":[{"text":"[示例] 富文本·只有 type0","type":0}],"conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"内容片段类型：`0` 文本、`3` 表情、`5` @ 提及。","title":"类型"},"text":{"type":"string","description":"文本内容。"}}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":[{"text":"[示例] 富文本·只有 type0","type":0}],"contentType":0,"flag":83886080,"fromUserId":1000000000000001,"id":1001251,"messageType":1,"roomId":"10000000000000006","sendTime":1788423389,"senderName":"小艺","syncKey":44527018,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendVoice":{"post":{"tags":["消息"],"summary":"发送语音","description":"发送语音。**没有专门的语音上传接口**：先调「上传文件」，把返回的 `data` 整体作为 `content`，再补一个 `voiceTime`（秒）。","operationId":"ql_api_message_sendVoice","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[0],"title":"会话 ID"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID\n\n**注意**：可直接用 `/api/cdn/uploadFile` 的回执句柄，无需专用语音上传接口。但音频格式要求平台未说明、也未用真实音频验证。","examples":["上传返回的 fileId"]},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","examples":[""],"title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","examples":[12216],"minimum":0},"voiceTime":{"type":"integer","format":"int64","description":"语音时长，单位通常为秒。\n\n**注意**：语音时长（秒）。**平台不校验**——用一个 115 字节的文本文件句柄配 `voiceTime:5` 也能返回成功。它只是个展示用数字，接入方必须自己填对，否则会话里显示的时长与实际音频不符。","examples":[5]},"aesKey":{"type":"string","description":"媒体解密密钥。由上传接口返回，发送/下载时原样回传，不要改写","examples":["上传返回的 aesKey"],"title":"媒体解密密钥"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","examples":["上传返回的 fileMd5"],"title":"MD5 校验值"}},"required":["id","url","size","voiceTime","aesKey","md5"],"description":"「上传文件」返回的 `data` **整体**，再加一个 `voiceTime`（秒）。","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":{"aesKey":"<上传接口返回的 aesKey>","id":"<上传接口返回的 fileId>","md5":"<上传接口返回的 md5>","name":"v.amr","size":206,"url":"","voiceTime":3},"conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"name":{"type":"string","description":"名称/昵称","title":"名称"},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"voiceTime":{"type":"integer","format":"int64","description":"语音时长，单位通常为秒。"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":{"aesKey":"<上传接口返回的 aesKey>","id":"<上传接口返回的 fileId>","md5":"<上传接口返回的 md5>","name":"v.amr","size":206,"url":"","voiceTime":3},"contentType":16,"flag":83886080,"fromUserId":1000000000000001,"id":1001343,"messageType":1,"roomId":"10000000000000006","sendTime":1788424051,"senderName":"小艺","syncKey":44527065,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendImage":{"post":{"tags":["消息"],"summary":"发送图片","description":"发送图片。先调「上传图片」，把返回的 `data` **整体**作为 `content` 传入 —— 两边字段逐个对应，不需要自己拼。","operationId":"ql_api_message_sendImage","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[7881000000000002],"title":"会话 ID"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID","examples":["<sample-media-id>"]},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","examples":[10528],"minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","examples":[284],"minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","examples":[177],"minimum":0},"aesKey":{"type":"string","description":"媒体解密密钥。由上传接口返回，发送/下载时原样回传，不要改写","examples":["ef9c3132a4790b0b6c711198e355823e"],"title":"媒体解密密钥"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","examples":["065954fddfa288194a56407d279b4aac"],"title":"MD5 校验值"},"midImageFileSize":{"type":"integer","format":"int64","description":"中等尺寸图字节数\n\n**注意**：随上传回执一起带上即可通过。它与 `thumbFileSize` 的差别（中图 vs 缩略图各自的字节数）未做单独验证，建议原样透传上传回执，不要自行计算。","examples":[11338],"minimum":0},"thumbFileSize":{"type":"integer","format":"int64","description":"缩略图字节数","examples":[11338],"minimum":0},"thumbWidth":{"type":"integer","format":"int64","description":"缩略图宽度","examples":[240],"minimum":0},"thumbHeight":{"type":"integer","format":"int64","description":"缩略图高度","examples":[149],"minimum":0},"thumbMd5":{"type":"string","description":"缩略图 MD5\n\n**注意**：契约示例把该字段的值写成了一个图片 URL，是错的。**不传该字段照样发送成功**，属非必填。缩略图相关真正需要的是 `thumbFileSize`/`thumbWidth`/`thumbHeight`。","examples":["16a7677492f36683af5c3eef54d939bd"]}},"required":["id","size","width","height","aesKey","md5","midImageFileSize","thumbFileSize","thumbWidth","thumbHeight","thumbMd5"],"description":"「上传图片」返回的 `data` **整体**。","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","conversationId":1000000000000001,"content":{"id":"<sample-media-id>","size":10528,"width":1000000000000001,"height":177,"aesKey":"00000000000000000000000000000000","md5":"00000000000000000000000000000000","midImageFileSize":1000000000000001,"thumbFileSize":11338,"thumbWidth":1000000000000001,"thumbHeight":149,"thumbMd5":"00000000000000000000000000000000"}}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","minimum":0},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"},"midImageFileSize":{"type":"integer","format":"int64","description":"中等尺寸图字节数","minimum":0},"thumbFileSize":{"type":"integer","format":"int64","description":"缩略图字节数","minimum":0},"thumbWidth":{"type":"integer","format":"int64","description":"缩略图宽度","minimum":0},"thumbHeight":{"type":"integer","format":"int64","description":"缩略图高度","minimum":0},"thumbMd5":{"type":"string","description":"缩略图 MD5"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":{"id":"","size":0,"width":0,"height":0,"md5":"","midImageFileSize":0,"thumbFileSize":0,"thumbWidth":0,"thumbHeight":0,"thumbMd5":""}},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendVideo":{"post":{"tags":["消息"],"summary":"发送视频","description":"发送视频。先调「上传视频」，把返回的 `data` **整体**作为 `content` 传入。","operationId":"ql_api_message_sendVideo","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID","examples":["<sample-media-id>"]},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","examples":[873163],"minimum":0},"duration":{"type":"integer","format":"int64","description":"视频或语音时长，单位以接口说明为准。","examples":[4],"minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","examples":[720],"minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","examples":[1280],"minimum":0},"thumbUrl":{"type":"string","description":"封面或缩略图地址。\n\n**注意**：视频封面用的是**公网直链**而非 CDN 句柄（与 `content.id` 走的取件通道不同）。由 `/api/cdn/uploadVideo` 回执给出，原样透传即可。","examples":["https://example.com/sample-media.jpg"]},"aesKey":{"type":"string","description":"媒体解密密钥。由上传接口返回，发送/下载时原样回传，不要改写","examples":["7e96d1b925cd0b8401d8350e815d13c7"],"title":"媒体解密密钥"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","examples":["e6c6f697cd8f9be46d8890d9b985320c"],"title":"MD5 校验值"}},"required":["id","size","duration","width","height","thumbUrl","aesKey","md5"],"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","conversationId":1000000000000001,"content":{"id":"<sample-media-id>","size":873163,"duration":4,"width":1000000000000001,"height":1280,"thumbUrl":"https://example.com/sample","aesKey":"00000000000000000000000000000000","md5":"00000000000000000000000000000000"}}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"path":{"type":"string","description":"小程序页面路径"},"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"duration":{"type":"integer","format":"int64","description":"视频或语音时长，单位以接口说明为准。","minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","minimum":0},"thumbUrl":{"type":"string","description":"封面或缩略图地址。"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"},"sourcePath":{"type":"string","description":"服务端记录的源文件路径。仅用于定位媒体来源，通常无需业务处理。"},"uploadDir":{"type":"string","description":"服务端媒体上传目录标识。由服务端生成，客户端原样保留。"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":{"path":"","id":"","size":0,"duration":0,"width":0,"height":0,"thumbUrl":"","md5":"","sourcePath":"","uploadDir":""}},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendFile":{"post":{"tags":["消息"],"summary":"发送文件","description":"发送文件。先调「上传文件」，把返回的 `data` 整体作为 `content` 传入。","operationId":"ql_api_message_sendFile","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID","examples":["<sample-media-id>"]},"name":{"type":"string","description":"名称/昵称\n\n**注意**：就是对方在会话里看到的文件显示名，与实际上传内容无关联校验（可任意改写）。","examples":["sample_voice_5s.silk"],"title":"名称"},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。\n\n**注意**：返回里会多出一个 `url`，是**空串**。不要把它当下载地址，普通文件的取件方式是拿 `id`+`aesKey` 调 `/api/cdn/download`。","examples":[""],"title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","examples":[12216],"minimum":0},"aesKey":{"type":"string","description":"媒体解密密钥。由上传接口返回，发送/下载时原样回传，不要改写","examples":["0c985abaf66a93d054847faf821868db"],"title":"媒体解密密钥"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","examples":["f6073d7c966718c256fc3fbf351915aa"],"title":"MD5 校验值"}},"required":["id","name","url","size","aesKey","md5"],"description":"「上传文件」返回的 `data` **整体**。","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","conversationId":1000000000000001,"content":{"id":"<sample-media-id>","name":"示例名称","url":"","size":12216,"aesKey":"00000000000000000000000000000000","md5":"00000000000000000000000000000000"}}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"name":{"type":"string","description":"名称/昵称","title":"名称"},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":{"id":"","name":"","url":"","size":0,"md5":""}},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendBigFile":{"post":{"tags":["消息"],"summary":"发送大文件","description":"发送大文件。与「上传大文件」配合使用：文件 ID 取自上传完成后推送的 `BigFileUploadCompleted` 回调事件（`content.id`，带 `*1*` 前缀），普通「上传文件」返回的 ID 会被拒绝。","operationId":"ql_api_message_sendBigFile","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID\n\n**注意**：大文件句柄，形如 `*1*` + 长串（495 字符），与普通 `/api/cdn/uploadFile` 的 ASN.1 十六进制句柄**格式完全不同、不可互换**。属媒体凭证，落库须加密、日志只记长度。","examples":["*1*u3W2k/2+7TigF3ieM2JYWY12fJ0m+w80zO84cIONH6ZKT8SyyK62oDObjIhtuywuEmdMMirU7/D2XDpybA3jNmL3Ws1EmotM0bI1Ydi3YtSwMZSy///4x9pbVL6h3f0kvoPtbEuaVJS6PnZ73MU76340FXYyWyj+6j7tXzPAIhv2KpA1WRW7E9U4ngmBx4imnfA24"]},"name":{"type":"string","description":"名称/昵称","examples":["完整pb数据.txt"],"title":"名称"},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","examples":[""],"title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","examples":[45675521],"minimum":0},"aesKey":{"type":"string","description":"媒体解密密钥。由上传接口返回，发送/下载时原样回传，不要改写\n\n**注意**：**不传也能成功**，返回里回显为空串。解密信息应已内含在 `*1*` 句柄中。这与 sendFile/sendImage 必须带 `aesKey` 的模式不同。","examples":[""],"title":"媒体解密密钥"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","examples":["6cfb4f980bcf246507fdc965d3806b43"],"title":"MD5 校验值"}},"required":["id","name","url","size","aesKey","md5"],"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","conversationId":1000000000000001,"content":{"id":"<id-已脱敏>","name":"示例名称","url":"","size":45675521,"aesKey":"","md5":"00000000000000000000000000000000"}}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"name":{"type":"string","description":"名称/昵称","title":"名称"},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":{"id":"","name":"","url":"","size":0,"md5":""}},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendLink":{"post":{"tags":["消息"],"summary":"发送链接卡片","description":"发送链接卡片。`url` 是落地地址，`imageUrl` 是卡片缩略图。","operationId":"ql_api_message_sendLink","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"content":{"type":"object","properties":{"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","examples":["https://mp.weixin.qq.com/s?__biz=MzI3MTA0MTk1MA%3D%3D&mid=2652708425&idx=1&sn=7177cd5114ee3b9637deba80237c7a11&chksm=<sample-media-id>&scene="],"title":"资源地址"},"imageUrl":{"type":"string","description":"封面图 URL","examples":["https://example.com/sample-media.jpg"],"title":"图片地址"},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","examples":["刚刚，百度开源拿下全球第一！作者疑似DeepSeek出走大神"],"title":"标题"},"source":{"type":"string","description":"来源名称。**sendLink 必填**，缺失会报 content.source is required","examples":["新智元"]}},"required":["url","imageUrl","title","source"],"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":{"desc":"链接卡片的描述行","imageUrl":"https://example.com/...","source":"青鸾开放平台","title":"[示例] 2/链接卡片","url":"https://example.com/..."},"conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","title":"资源地址"},"imageUrl":{"type":"string","description":"封面图 URL","title":"图片地址"},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","title":"标题"},"source":{"type":"string","description":"来源名称。**sendLink 必填**，缺失会报 content.source is required"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":{"imageUrl":"https://example.com/...","title":"[示例] 2/链接卡片","url":"https://example.com/..."},"contentType":13,"flag":83886080,"fromUserId":1000000000000001,"id":1001243,"messageType":1,"roomId":"10000000000000006","sendTime":1788423357,"senderName":"小艺","syncKey":44527014,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendNameCard":{"post":{"tags":["消息"],"summary":"发送名片","description":"发送名片。`cardUserId` 在**请求体顶层**，不在 `content` 里。","operationId":"ql_api_message_sendNameCard","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"cardUserId":{"type":"integer","format":"int64","description":"名片对应的用户 ID。⚠️ 字段名是 `cardUserId`，**不是 `userId`**；且它在请求体**顶层**，不在 `content` 里。","examples":[1688000000000001]}},"required":["appid","conversationId","cardUserId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","cardUserId":1000000000000018,"conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"cardUserId":{"type":"integer","format":"int64","description":"名片对应的用户 ID。sendNameCard **必填**（不是 userId）"},"avatarUrl":{"type":"string","description":"头像 URL"},"name":{"type":"string","description":"名称/昵称","title":"名称"},"corpName":{"type":"string","description":"企业名称。"},"corpId":{"type":"integer","format":"int64","description":"企业 ID。","title":"企业 ID"},"displayName":{"type":"string","description":"名片中展示的联系人名称。"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":{"avatarUrl":"<省略>","cardToken":"<省略>","cardUserId":1000000000000018,"corpId":1000000000000002,"corpName":"示例企业","displayName":"张三","name":"张三"},"contentType":41,"flag":83886080,"fromUserId":1000000000000001,"id":1001253,"messageType":1,"roomId":"10000000000000006","sendTime":1788423389,"senderName":"小艺","syncKey":44527019,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendGif":{"post":{"tags":["消息"],"summary":"发送 GIF","description":"发送 GIF。同样先调「上传图片」（GIF 也走它），返回的 `data` 整体作为 `content`。","operationId":"ql_api_message_sendGif","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"content":{"type":"object","properties":{"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。\n\n**注意**：必须是**平台可达的公网直链**。GIF 消息不经过 CDN 上传通道，所以不存在 `id`/`aesKey` 这两个字段——这一点与 sendImage 完全不同，接入时不要套用图片的流程。","examples":["https://example.com/sample-media.jpg"],"title":"资源地址"},"thumbUrl":{"type":"string","description":"封面或缩略图地址。","examples":["https://example.com/sample-media.jpg"]},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","examples":["<session-uuid>"],"title":"MD5 校验值"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","examples":[45754],"minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","examples":[240],"minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","examples":[240],"minimum":0},"name":{"type":"string","description":"名称/昵称","examples":["辛苦了"],"title":"名称"}},"required":["url","thumbUrl","md5","size","width","height","name"],"description":"「上传图片」返回的 `data` **整体**。","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":{"aesKey":"<上传接口返回的 aesKey>","height":1,"id":"<上传接口返回的 fileId>","md5":"<上传接口返回的 md5>","midImageFileSize":597,"name":"t.gif","size":42,"thumbFileSize":597,"thumbHeight":1,"thumbMd5":"8b69799ecf4a89193e600e0b70bb7b78","thumbUrl":"","thumbWidth":1,"url":"","width":1},"conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。","title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","minimum":0},"name":{"type":"string","description":"名称/昵称","title":"名称"},"thumbUrl":{"type":"string","description":"封面或缩略图地址。"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":{"height":1,"md5":"<上传接口返回的 md5>","name":"t.gif","size":42,"width":1},"contentType":29,"flag":83886080,"fromUserId":1000000000000001,"id":1001257,"messageType":1,"roomId":"10000000000000006","sendTime":1788423505,"senderName":"小艺","syncKey":44527021,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendLocation":{"post":{"tags":["消息"],"summary":"发送位置","description":"发送位置。经纬度是浮点数，注意不要当成整数传。","operationId":"ql_api_message_sendLocation","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[10000000000000000],"title":"会话 ID"},"content":{"type":"object","properties":{"longitude":{"type":"number","description":"经度","examples":[121.12781],"minimum":-180,"maximum":180},"latitude":{"type":"number","description":"纬度","examples":[31.148475],"minimum":-90,"maximum":90},"address":{"type":"string","description":"居住地址","examples":["上海市青浦区桂花园(外青松公路东100米)"]},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","examples":["青浦区桂花园(外青松公路东100米)"],"title":"标题"}},"required":["longitude","latitude","address","title"],"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":{"address":"北京市东城区天安门广场","latitude":39.90923,"longitude":116.397428,"title":"[示例] 3/位置"},"conversationId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"longitude":{"type":"number","description":"经度","minimum":-180,"maximum":180},"latitude":{"type":"number","description":"纬度","minimum":-90,"maximum":90},"address":{"type":"string","description":"居住地址"},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","title":"标题"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"content":{"address":"北京市东城区天安门广场","latitude":39.90923,"longitude":116.397428,"title":"[示例] 3/位置"},"contentType":6,"flag":83886080,"fromUserId":1000000000000001,"id":1001245,"messageType":1,"roomId":"10000000000000006","sendTime":1788423358,"senderName":"小艺","syncKey":44527015,"toUserId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/revoke":{"post":{"tags":["消息"],"summary":"撤回消息","description":"撤回消息。`serverMsgId` 取自发送接口返回的 `data.id`。","operationId":"ql_api_message_revoke","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[1970000000000001],"title":"会话 ID"},"serverMsgId":{"type":"integer","format":"int64","description":"服务端消息 ID，取自发送接口返回的 `data.id`。","examples":[1001469]}},"required":["appid","conversationId","serverMsgId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","conversationId":10000000000000006,"serverMsgId":1001311}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时返回**空对象 `{}`**，无任何回执字段。不要试图从 `data` 里读撤回结果，判据只有 `code=0` + 随后的 2063 回调。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/sendMiniProgram":{"post":{"tags":["消息"],"summary":"发送小程序卡片","description":"发送小程序卡片。需要小程序 username(gh_ 开头)、appId、path 与封面图。\n\n:::tip\n🔗 **调用关系**\n\n准备小程序信息，并先上传封面图以取得 `coverFileId`、`coverAesKey` 等字段。\n:::\n\n:::note\n🧩 **字段命名**：设备标识使用 `appid`，小程序标识使用 `appId`，两者区分大小写。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_message_sendMiniProgram","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"conversationId":{"type":"integer","format":"int64","description":"会话 ID。群聊传群号，私聊传对方 uin。**注意它超出 JavaScript 安全整数范围**，JS 侧需按大整数处理，不要经过 `Number()`。","examples":[7881000000000002],"title":"会话 ID"},"content":{"type":"object","properties":{"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","examples":["寄快递，用顺丰"],"title":"标题"},"miniProgramDetails":{"type":"object","properties":{"username":{"type":"string","description":"小程序原始 ID（gh_ 开头）\n\n**注意**：传伪造值 `gh_test` 也返回 code=0，**平台不校验小程序是否真实存在**。因此 code=0 只能证明消息发出，不能证明卡片可点开。","examples":["gh_f9d9fca26a50@app"]},"appId":{"type":"string","examples":["wxd4185d00bf7e08ac"],"description":"小程序 AppID。注意大写 `I`，不要与设备字段 `appid` 混用。","title":"小程序 AppID"},"path":{"type":"string","description":"小程序页面路径","examples":["pages/tabBar/index/index.html?sampshare=%7B%22i%22%3A%22oXJy05GA6HNgF5vZ1hY7ATHaidZY%22%2C%22p%22%3A%22pages%2FtabBar%2Findex%2Findex%22%2C%22d%22%3A0%2C%22m%22%3A%22%E8%BD%AC%E5%8F%91%E6%B6%88%E6%81%"]},"coverUrl":{"type":"string","examples":["https://example.com/sample-media.jpg"],"description":"缩略图url"},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","examples":["寄快递，用顺丰"],"title":"标题"},"appName":{"type":"string","examples":["顺丰速运+"],"description":"**必填（契约漏标）**。不传报 `content.miniProgramDetails.appName is required`。\n\n**注意**：**契约漏标的必填项**。缺失时平台返回 `code=-1`、`content.miniProgramDetails.appName is required`。是卡片上显示的小程序名称。"},"fallbackUrl":{"type":"string","examples":["https://mp.weixin.qq.com/mp/waerrpage?appid=wxd4185d00bf7e08ac&type=upgrade&upgradetype=3#wechat_redirect"],"description":"**必填（契约漏标）**。不传报 `content.miniProgramDetails.fallbackUrl is required`。\n\n**注意**：**契约漏标的必填项**。缺失时报 `content.miniProgramDetails.fallbackUrl is required`。语义应为不支持小程序时的降级跳转地址，但**未确认降级行为**，只验证了必填性。"},"coverFileId":{"type":"string","examples":["<sample-media-id>"],"description":"**必填（契约漏标）**。不传报 `content.miniProgramDetails.coverFileId is required`。值来自 `/api/cdn/uploadImage` 的返回。\n\n**注意**：**契约漏标的必填项**，且**契约里根本没有这个字段名**。取自 `/api/cdn/uploadImage` 回执的 `id`。属媒体凭证，落库须加密、日志只记长度。"},"coverMd5":{"type":"string","examples":["961aa29ebd964455b22ecfaa691924d7"],"description":"**必填（契约漏标）**。不传报 `content.miniProgramDetails.coverMd5 is required`。值来自 `/api/cdn/uploadImage` 的返回。\n\n**注意**：**契约漏标的必填项**，且契约示例把它的值错写成了一个 URL。实际应是封面图的 32 位 md5，取自图片上传回执。"},"coverAesKey":{"type":"string","examples":["caf54890e1a4f45b072e64db3d265fe7"],"description":"封面图片的解密密钥，由上传结果提供。\n\n**注意**：契约未列。与 `coverMd5` 一起补入，平台从未单独报错要求过它，因此**必填性未确认**。建议原样透传图片上传回执的 `aesKey`。属媒体凭证。"},"coverSize":{"type":"integer","format":"int64","examples":[57102],"minimum":0,"description":"封面图片大小，单位为字节。"},"coverWidth":{"type":"integer","format":"int64","examples":[500],"minimum":0,"description":"**必填（契约漏标）**。不传报 `content.miniProgramDetails.coverWidth and coverHeight are required`。\n\n**注意**：**契约漏标的必填项**。它与 `coverHeight` 由平台在**同一条报错里一起要求**（`coverWidth and coverHeight are required`），必须成对提供。"},"coverHeight":{"type":"integer","format":"int64","examples":[400],"minimum":0,"description":"**必填（契约漏标）**。不传报 `content.miniProgramDetails.coverWidth and coverHeight are required`。\n\n**注意**：**契约漏标的必填项**，与 `coverWidth` 成对，见上。"}},"required":["username","appId","appName","path","fallbackUrl","coverFileId","coverMd5","coverWidth","coverHeight"],"description":"**契约只列了 3 个字段，需要 9 个。** 必填字段是**一个一个报出来的**——补一个再报下一个，连报 5 轮才补齐。封面相关字段全部来自 `/api/cdn/uploadImage` 的返回。"}},"required":["title","miniProgramDetails"],"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"required":["appid","conversationId","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","conversationId":1000000000000001,"content":{"title":"示例名称","miniProgramDetails":{"username":"gh_example@app","appId":"wx0000000000000000","path":"pages/index/index","coverUrl":"https://example.com/sample","title":"示例名称","appName":"示例名称","fallbackUrl":"https://example.com/sample","coverFileId":"<media-file-id>","coverMd5":"00000000000000000000000000000000","coverAesKey":"00000000000000000000000000000000","coverSize":57102,"coverWidth":1000000000000001,"coverHeight":400}}}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"syncKey":{"type":"integer","format":"int64","description":"同步键。下次增量同步传回","title":"同步游标"},"messageType":{"type":"integer","format":"int64","description":"消息类型枚举（0=普通消息）"},"fromUserId":{"type":"integer","format":"int64","description":"发送方 ID"},"toUserId":{"type":"integer","format":"int64","description":"接收方 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"sendTime":{"type":"integer","format":"int64","description":"发送时间戳（秒）"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"},"senderName":{"type":"string","description":"消息发送名称"},"content":{"type":"object","properties":{"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","title":"标题"},"miniProgramDetails":{"type":"object","properties":{"username":{"type":"string","description":"小程序原始 ID（gh_ 开头）"},"appId":{"type":"string","description":"小程序 AppID。注意大写 `I`，不要与设备字段 `appid` 混用。","title":"小程序 AppID"},"path":{"type":"string","description":"小程序页面路径"},"type":{"type":"integer","format":"int64","description":"小程序卡片类型枚举值，由平台定义。","title":"类型"},"source":{"type":"integer","format":"int64","description":"来源名称。**sendLink 必填**，缺失会报 content.source is required"},"coverUrl":{"type":"string","description":"缩略图url"},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","title":"标题"},"appName":{"type":"string","description":"小程序名称。"},"fallbackUrl":{"type":"string","description":"小程序备用网页地址。"},"appNameDup":{"type":"string","description":"服务端返回的小程序名称副本字段；兼容字段，原样保留。"},"coverMd5":{"type":"string","description":"封面图片的 MD5 校验值。"},"coverSize":{"type":"integer","format":"int64","minimum":0,"description":"封面图片大小，单位为字节。"},"reserved19":{"type":"integer","format":"int64","description":"平台保留字段 19，当前无公开枚举说明。"},"reserved20":{"type":"integer","format":"int64","description":"平台保留字段 20，当前无公开枚举说明。"},"coverWidth":{"type":"integer","format":"int64","minimum":0,"description":"封面图片宽度，单位为像素。"},"coverHeight":{"type":"integer","format":"int64","minimum":0,"description":"封面图片高度，单位为像素。"},"flag":{"type":"integer","format":"int64","description":"状态标志位（按位含义见平台文档）"}},"description":"小程序卡片详情"}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":{"title":"","miniProgramDetails":{"username":"","appId":"","path":"","type":0,"source":0,"coverUrl":"","title":"","appName":"","fallbackUrl":"","appNameDup":"","coverMd5":"","coverSize":0,"reserved19":0,"reserved20":0,"coverWidth":0,"coverHeight":0,"flag":0}}},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/getMaterialList":{"post":{"tags":["消息"],"summary":"查询素材列表","description":"获取群发助手的素材库列表。注意这是群发素材，不是个人收藏消息。\n\n:::tip\n🔗 **调用关系**\n\n首次传空游标 → 保存 `nextPageStr` → 使用新游标继续翻页。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_message_getMaterialList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"nextPageStr":{"type":"string","examples":[""],"title":"下一页游标","description":"分页游标。首次请求传空字符串，后续传上次响应中的 `nextPageStr`。\n\n**注意**：必填但可为**空串**（表示首页）。不能整个省略。"}},"required":["appid","nextPageStr"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","nextPageStr":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"isEnd":{"type":"boolean","description":"是否执行完成"},"list":{"type":["string","null"],"description":"数据列表\n\n**注意**：空结果时返回 **`null` 而非空数组**，需做空值防御。账号无素材，`list[]` 的元素结构**完全未确认**。"},"nextPageStr":{"type":"string","title":"下一页游标","description":"下一页游标；为空通常表示没有更多数据。\n\n**注意**：即使 `isEnd: true` 也会返回非空游标（`\"CAA=\"`）。**翻页终止只看 `isEnd`**，不要用游标是否为空来判断。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"isEnd":true,"list":null,"nextPageStr":"CAA="}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/groupSend":{"post":{"tags":["消息"],"summary":"群发消息","description":"群发助手。**contentList[].content 是数组**，如 `[{\"type\":0,\"text\":\"内容\"}]`；receiverList 填接收人 ID。\n\n:::tip\n🔗 **调用关系**\n\n准备素材与接收人 → 创建群发任务 → 根据任务状态继续处理。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_message_groupSend","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"customerGroup":{"type":"boolean","description":"是否发送到客户群，**布尔值**。只接受 `true` / `false` —— 传数字 `0` 或字符串 `\"0\"` 都会被拒绝。","examples":[false]},"contentList":{"type":"array","items":{"type":"object","properties":{"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）","examples":[0]},"content":{"oneOf":[{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"内容片段类型：`0` 文本、`3` 表情；其他值以平台定义为准。","examples":[3],"title":"类型"},"text":{"type":"string","description":"文本内容。","examples":["[撇嘴]"]}},"required":["type","text"]},"description":"文本或表情内容片段数组。"},{"type":"object","description":"图片、视频等媒体内容对象；字段取自对应上传接口的返回数据。","additionalProperties":true}],"description":"群发内容。`contentType=0` 时传内容片段数组；媒体类型传上传接口返回的数据对象。","title":"内容"}},"required":["contentType","content"]},"description":"消息内容列表。元素为 `{contentType, content, appInfo}`，其中 **`content` 本身是数组**，如 `[{\"type\": 0, \"text\": \"内容\"}]`。"},"receiverList":{"type":"array","items":{"type":"integer","format":"int64","examples":[10000000000000002]},"description":"接收人 ID 列表。元素必须是 **uint64 数字**，传字符串会被拒绝。"},"materialId":{"type":"integer","format":"int64","examples":[117159486110430460],"description":"群发素材 ID，可从群发素材列表或待发送任务中获取。\n\n**注意**：固定传 `0`。是否允许为 0、以及与 `contentList` 的互斥/共存关系，**均未确认**。"}},"required":["appid","customerGroup","contentList","receiverList","materialId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","customerGroup":true,"contentList":[{"contentType":0,"content":[{"type":3,"text":"示例内容"},{"type":0,"text":"示例内容"}]},{"contentType":14,"content":{"id":"<sample-media-id>","size":570260,"width":1000000000000001,"height":1792,"aesKey":"00000000000000000000000000000000","md5":"00000000000000000000000000000000"}},{"contentType":22,"content":{"id":"<id-已脱敏>","size":285357,"duration":2,"width":1000000000000001,"height":720,"thumbUrl":"https://example.com/sample","md5":"00000000000000000000000000000000"}},{"contentType":20,"content":{}}],"receiverList":[10000000000000001],"materialId":1000000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"msgId":{"type":"integer","format":"int64","description":"消息 ID。用于撤回、状态查询或消息关联。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"msgId":0},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/getPendingGroupSendList":{"post":{"tags":["消息"],"summary":"查询待发群发","description":"获取待发送的群发任务列表。返回的 list[].id 供 groupSendPending 使用。\n\n:::tip\n🔗 **调用关系**\n\n获取待发送列表 → 读取任务 `id` → 调用 `groupSendPending`。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_message_getPendingGroupSendList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"hasMore":{"type":"boolean","description":"是否还有下一页数据。true 表示仍有数据可继续拉取。\n\n**注意**：**空库时返回 `true` 但 `list` 为 `null`、`nextKey.msgId` 为 `0`**，自相矛盾。不能单凭 `hasMore` 决定是否继续翻页，否则会死循环。"},"list":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"seq":{"type":"integer","format":"int64","description":"增量同步序号。首次请求通常传 `0`，后续传上次响应返回的序号。","title":"同步序号"},"timeStamp":{"type":"integer","format":"int64","description":"时间戳"},"totalCnt":{"type":"integer","format":"int64","description":"总数"},"nowCnt":{"type":"integer","format":"int64","description":"已完成数"},"contentList":{"type":"array","items":{"type":"object","properties":{"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）"},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"内容片段类型：`0` 文本、`3` 表情；其他值以平台定义为准。","title":"类型"},"text":{"type":"string","description":"文本内容。"}}},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理"}}},"description":"消息内容列表。每项 `{contentType, content}`，**content 为数组**"},"groupId":{"type":"integer","format":"int64","description":"分组 ID。"},"status":{"type":"integer","format":"int64","description":"登录状态。-1=未认证需扫码 0=可免扫码 1=已扫码待确认 2=认证成功 4=用户取消 10=待输入6位验证码","title":"状态"},"extraInfo":{"type":"object","properties":{"senderNums":{"type":"integer","format":"int64","description":"当前已发送数量。"},"senderTotalNums":{"type":"integer","format":"int64","description":"计划发送总数量。"},"serviceMember":{"type":"integer","format":"int64","description":"服务成员 ID。平台数值字段，原样保留。"},"bAllowSelect":{"type":"integer","format":"int64","description":"是否允许选择接收对象；平台使用整数标志位表示。"}},"description":"扩展信息"},"creator":{"type":"integer","format":"int64","description":"群发任务创建者 ID。"},"sendModel":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"群发模式类型枚举值，由平台定义。","title":"类型"},"groupId":{"type":"integer","format":"int64","description":"分组 ID。"}},"description":"群发任务的发送模式配置。"},"execTime":{"type":"integer","format":"int64","description":"任务执行时间，Unix 时间戳（秒）。"},"conversationType":{"type":"integer","format":"int64","description":"会话类型"}}},"description":"数据列表\n\n**注意**：空结果时是 **`null` 而非空数组**。账号无待发任务，元素结构**完全未确认**。"},"nextKey":{"type":"object","properties":{"msgId":{"type":"integer","format":"int64","description":"消息 ID。用于撤回、状态查询或消息关联。"}},"title":"下一页游标","description":"下一页游标对象；翻页时按响应原样回传。\n\n**注意**：形如 `{msgId: <数字>}`。空库时为 `{msgId: 0}`，其作为下一页入参的正确用法未确认（该接口契约中也没有对应的入参字段）。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"hasMore":true,"list":null,"nextKey":{"msgId":0}}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/groupSendPending":{"post":{"tags":["消息"],"summary":"发送待发群发","description":"发送待发送的群发任务。`id` 取自「查询待发群发」。\n\n⚠️ 超过一年的任务会被拒绝。","operationId":"ql_api_message_groupSendPending","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID\n\n**注意**：应指向一条**已存在的待发送记录**（来源为 `/api/message/getPendingGroupSendList`）。该列表为空，无合法 `id` 可用，只能传 `0` 试探——因此本次失败**不足以判定接口本身有问题**。","examples":[117159486110430460]},"contentList":{"type":"array","items":{"type":"object","properties":{"contentType":{"type":"integer","format":"int64","description":"内容类型。0=文本 14=图片（完整枚举见平台「企微错误码」章节）","examples":[0]},"content":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"内容片段类型：`0` 文本、`3` 表情；其他值以平台定义为准。","examples":[0],"title":"类型"},"text":{"type":"string","description":"文本内容。","examples":["坎坎坷坷"]}},"required":["type","text"]},"description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"},"appInfo":{"type":"string","description":"企微内部应用标识，透传字段，无需处理","examples":["CAQQiaO51AYY4Y+oq5SAgAMg56GIsQQ="]}},"required":["contentType","content","appInfo"]},"description":"消息内容列表。元素为 `{contentType, content, appInfo}`，其中 **`content` 本身是数组**，如 `[{\"type\": 0, \"text\": \"内容\"}]`。"},"conversationType":{"type":"integer","format":"int64","description":"会话类型\n\n**注意**：传 `1`，取值语义未确认。参考：`getGroupSendRecord` 返回的历史记录中该字段为 `0`（对应私聊群发场景）。","examples":[0]}},"required":["appid","id","contentList","conversationType"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","id":1000000000000001,"contentList":[{"contentType":0,"content":[{"type":0,"text":"示例内容"}],"appInfo":"CAQQiaO51AYY4Y+oq5SAgAMg56GIsQQ="}],"conversationType":0}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/getGroupSendRecord":{"post":{"tags":["消息"],"summary":"查询群发记录","description":"获取个人群发历史记录。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_message_getGroupSendRecord","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"isEnd":{"type":"boolean","description":"是否执行完成"},"list":{"type":["string","null"],"description":"数据列表"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"isEnd":true,"list":null}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/roomMessageTopAdd":{"post":{"tags":["消息"],"summary":"群消息置顶","description":"把一条群消息置顶。请求体是**整条消息对象本身**（发送接口返回的 `data` 可直接使用），不要再包一层。","operationId":"ql_api_message_roomMessageTopAdd","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"id":{"type":"integer","description":"消息 ID。发送接口返回的 `data.id`。"},"syncKey":{"type":"integer","description":"分页游标。首次传 `0`，之后传上一页返回的 `syncKey`。"},"messageType":{"type":"integer","description":"消息类型枚举。"},"fromUserId":{"type":"integer","description":"发送方 ID。"},"toUserId":{"type":"integer","description":"接收方 ID。"},"roomId":{"type":"integer","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"},"contentType":{"type":"integer","description":"内容类型码。"},"sendTime":{"type":"integer","description":"发送时间戳（秒）。"},"appInfo":{"type":"string","description":"消息指纹串，原样回填。"},"senderName":{"type":"string","description":"发送者显示名。"},"content":{"type":"array","description":"正文。结构随 `contentType` 变化，原样回填。"},"extraData":{"description":"随 `data` 一并回填，不需要自行构造。"},"flag":{"description":"随 `data` 一并回填，不需要自行构造。"},"devInfo":{"description":"随 `data` 一并回填，不需要自行构造。"},"summary":{"description":"随 `data` 一并回填，不需要自行构造。"}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":[],"extraData":"","flag":"","devInfo":"","summary":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/roomMessageTopDel":{"post":{"tags":["消息"],"summary":"取消群消息置顶","description":"取消群消息置顶。`topId` 从「获取群置顶消息」的 `all_msg[].topId` 取 —— 顶层字段里没有它。","operationId":"ql_api_message_roomMessageTopDel","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","examples":[10786447466811918],"description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"},"topId":{"type":"integer","examples":[45]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10786447466811918,"topId":45}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/roomMessageTopGetList":{"post":{"tags":["消息"],"summary":"获取群置顶消息","description":"获取群里的置顶消息。返回 `creatorId` / `msgContent` / `updateTime`；有置顶项时还会带 `all_msg` 数组，`topId` 在里面。","operationId":"ql_api_message_roomMessageTopGetList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","examples":[10786447466811918],"description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10786447466811918}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/voiceToTextGetId":{"post":{"tags":["消息"],"summary":"语音转文字·取任务 ID","description":"语音转文字第一步：用语音消息的 `msgId` 换取转写任务 ID。语音消息在消息同步结果里的 `contentType` 是 `16`。返回的 `queryIntervalMs` 是建议的轮询间隔。","operationId":"ql_api_message_voiceToTextGetId","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"msgId":{"type":"integer","examples":[1005530]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","msgId":1005530}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/message/voiceToTextQuery":{"post":{"tags":["消息"],"summary":"语音转文字·查询结果","description":"语音转文字第二步：用上一步的 `voiceId` 查询结果，文字在 `data.text`，`isEnd` 表示是否已转写完毕。\n\n内容无法识别时返回 `-2070`（例如整段静音），这是内容问题不是接口故障。","operationId":"ql_api_message_voiceToTextQuery","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"voiceId":{"type":"string","examples":[""]},"seqId":{"type":"integer","examples":[15875830]},"msgId":{"type":"integer","examples":[1005530]},"scene":{"type":"integer","examples":[1]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","voiceId":"","seqId":15875830,"msgId":1005530,"scene":1}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/getSyncList":{"post":{"tags":["联系人"],"summary":"同步通讯录","description":"同步通讯录。`svrVersion` **必须传字符串**，首次传 `\"0\"`；传数字 0 会被拒绝。","operationId":"ql_api_contact_getSyncList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"svrVersion":{"type":"string","description":"通讯录版本号，**字符串**。首次全量同步传空串 `\"\"`；增量同步把上次响应的 `data.svrVersion` 原样回传。传数字会被拒绝。","examples":[""]}},"required":["appid","svrVersion"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","svrVersion":"0"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"change":{"type":"boolean","description":"是否有变更"},"needFullUpdate":{"type":"boolean","description":"是否需要全量更新\n\n**注意**：首次调用返回 `true`。为 `true` 时应按全量重建本地通讯录，而不是做增量合并。"},"svrVersion":{"type":"string","description":"服务端版本串，增量同步时回传"},"nodeList":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"通讯录节点类型：`1` 成员，`2` 部门。","title":"类型"},"partyId":{"type":"integer","format":"int64","description":"partyId"},"seq":{"type":"integer","format":"int64","description":"增量同步序号。首次请求通常传 `0`，后续传上次响应返回的序号。","title":"同步序号"}}},"description":"通讯录节点列表。type=1 为成员（带 vid），type=2 为部门"},"corpScale":{"type":"integer","format":"int64","description":"企业规模标识\n\n**注意**：返回 `1`（测试企业规模很小）。具体分档含义未确认。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"change":true,"corpScale":1,"needFullUpdate":true,"nodeList":[{"partyId":1000000000000003,"seq":"1000000000000000011","type":2},{"partyId":1000000000000012,"seq":"1000000000000000013","type":2}],"svrVersion":"1000000000000000009_1000000000000000009_2_1000000000000000010_0_1000000000000000009_0"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/fetchUsersProfileBatch":{"post":{"tags":["联系人"],"summary":"批量查询用户详情","description":"批量获取通讯录成员资料。\n\n`nodeList[]` 需把「同步通讯录」返回的节点**整个原样回填**（含 `vid` 与 `partyId`），`type`：`1` = 成员，`2` = 部门。\n⚠️ 只传 `vid`、或把 `partyId` 填成 `0` 时，接口仍返回 `code = 0`，但每条只含 `uin` / `partyId` / `attr2` / `attr3` 且带 `isDelete: true`，**不含姓名**。","operationId":"ql_api_contact_fetchUsersProfileBatch","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"nodeList":{"type":"array","items":{"type":"object","properties":{"type":{"type":"integer","format":"int64","description":"**注意**：契约原描述写的是「设备类型，如 iPad」，**这是错的**。实际是**通讯录节点类型**：`1`=成员（配 `vid`），`2`=部门（配 `partyId`）。","examples":[1],"title":"类型"},"partyId":{"type":"integer","format":"int64","description":"partyId","examples":[1688000000000002]},"seq":{"type":"integer","format":"int64","description":"增量同步序号。首次请求通常传 `0`，后续传上次响应返回的序号。","examples":[7650540819522257000],"title":"同步序号"},"vid":{"type":"integer","format":"int64","description":"企业微信成员 VID。可从通讯录同步或成员资料接口获取。","examples":[1000000000000001],"title":"成员 VID"}},"required":["type","partyId","seq"]},"description":"节点列表，元素形如 `{\"vid\": 1688800000000001, \"type\": 1}`。**成员节点用 `vid` 字段**（不是 `id`）；`type`：1=成员，2=部门。"}},"required":["appid","nodeList"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","nodeList":[{"type":1,"vid":1000000000000001}]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"patchList":{"type":"array","items":{"type":"object","properties":{"department":{"type":"object","properties":{"partyId":{"type":"integer","format":"int64","description":"partyId"}},"description":"部门节点详情；`nodeType=2` 时返回。"},"nodeType":{"type":"integer","format":"int64","description":"通讯录节点类型：`1` 成员，`2` 部门。"},"isDelete":{"type":"boolean","description":"是否已删除"},"member":{"type":"object","description":"成员节点详情；`nodeType=1` 时返回。","properties":{"uin":{"type":"integer","format":"int64","description":"用户唯一数字 ID。外部联系人可从同步结果的 `userInfo.uin` 获取。","title":"用户 UIN"},"partyId":{"type":"integer","format":"int64","description":"成员所属部门 ID。"},"attr2":{"type":"integer","format":"int64","description":"成员属性标志位 2，按平台定义解析。"},"attr3":{"type":"integer","format":"int64","description":"成员属性标志位 3，按平台定义解析。"}}}}},"description":"增量补丁列表"},"isTrimUserInfo":{"type":"boolean","description":"用户信息是否已裁剪\n\n**注意**：返回 `false`。含义未确认（字面像是「是否裁剪了用户信息」，但返回值已经很简，未做进一步验证）。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"isTrimUserInfo":false,"patchList":[{"isDelete":true,"member":{"attr":8388608,"attr2":268435456,"attr3":1,"bindEmailStatus":1,"bizUin":1,"partyId":0,"uin":1000000000000001},"nodeType":1}]}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/getUserProfileDetail":{"post":{"tags":["联系人"],"summary":"查询用户详情","description":"获取联系人详细资料。⚠️ 入参是 **`userIdList`（数组）**，不是单个 `userId` —— 传单数会返回 `userIdList is empty`。响应也相应是**列表**，按传入顺序返回。\n\n同事取通讯录 vid（`1688` 前缀），外部联系人取 uin（`7881` 前缀）。","operationId":"ql_api_contact_getUserProfileDetail","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userIdList":{"type":"array","title":"用户 ID 列表","description":"用户 ID 列表。**必须是数组**，传单个数字会返回 `userIdList is empty`。","items":{"type":"integer","format":"int64"},"examples":[[1688000000000001]]},"userId":{"type":"integer","description":"用户 ID。**前缀决定类型**：`1688…` 是本企业成员（取自「同步通讯录」的 `vid`），`7881…` 是外部联系人（取自「同步外部联系人」的 `uin`）。其他前缀会被直接拒绝。"}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。","anyOf":[{"required":["userIdList"]},{"required":["userId"]}]},"example":{"appid":"we_xxxxxxxxxxxxxxx","userId":1000000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"vid":{"type":"integer","format":"int64","description":"企业微信成员 VID。可从通讯录同步或成员资料接口获取。","title":"成员 VID"},"info":{"type":"object","properties":{"uin":{"type":"integer","format":"int64","description":"用户唯一数字 ID。外部联系人可从同步结果的 `userInfo.uin` 获取。","title":"用户 UIN"},"name":{"type":"string","description":"名称/昵称\n\n**注意**：**姓名在 `data.info.name`，不在顶层**。契约语义容易读错，接入时注意层级。","title":"名称"},"emailAddr":{"type":"string","description":"邮箱"},"birthday":{"type":"string","description":"生日"},"phone":{"type":"string","description":"手机号（11 位）","title":"手机号"},"job":{"type":"string","description":"职位信息。"},"number":{"type":"string","description":"工号"},"gender":{"type":"integer","format":"int64","description":"性别枚举：`0` 未知，`1` 男，`2` 女。","enum":[0,1,2]},"iconUrl":{"type":"string","description":"头像 URL"},"corpId":{"type":"integer","format":"int64","description":"企业 ID。","title":"企业 ID"},"attr":{"type":"integer","format":"int64","description":"属性位"},"dispOrder":{"type":"integer","format":"int64","description":"显示排序"},"bizUin":{"type":"integer","format":"int64","description":"企业侧 uin"},"position":{"type":"string","description":"职位或位置说明。"},"alias":{"type":"string","description":"别名。传空串可清除"},"mainPartyId":{"type":"integer","format":"int64","description":"主部门 ID"},"gid":{"type":"integer","format":"int64","description":"分组 ID"},"isNameVerified":{"type":"boolean","description":"是否已实名"},"createSource":{"type":"integer","format":"int64","description":"联系人创建来源枚举值，由平台定义。"},"internationCode":{"type":"string","description":"国际区号。"},"bindEmailStatus":{"type":"integer","format":"int64","description":"邮箱绑定状态"},"englishName":{"type":"string","description":"英文名"},"customInfo":{"type":"object","properties":{},"description":"自定义信息"},"nameVerifyStatus":{"type":"integer","format":"int64","description":"实名校验状态"},"realName":{"type":"string","description":"真实姓名。"},"vCorpUseStatus":{"type":"integer","format":"int64","description":"虚拟企业使用状态"},"inviteVid":{"type":"integer","format":"int64","description":"邀请人 vid"},"holidayInfo":{"type":"object","properties":{"holidayStatus":{"type":"integer","format":"int64","description":"休假状态"},"holidayDesc":{"type":"string","description":"休假说明"},"oldHolidayIconIndex":{"type":"integer","format":"int64","description":"旧休假图标序号"},"createTime":{"type":"integer","format":"int64","description":"创建时间戳（秒）"},"holidayInfoId":{"type":"integer","format":"int64","description":"休假信息 ID"},"holidayIconIndex":{"type":"integer","format":"int64","description":"休假图标序号"},"holidayGenerateSrc":{"type":"integer","format":"int64","description":"休假来源"},"holidayStatusNew":{"type":"integer","format":"int64","description":"新版休假状态"},"vacationSyncType":{"type":"integer","format":"int64","description":"休假同步类型"}},"description":"休假信息"},"xcxStyle":{"type":"integer","format":"int64","description":"小程序样式配置"},"attr2":{"type":"integer","format":"int64","description":"属性位 2"},"tencentInfo":{"type":"object","properties":{},"description":"腾讯侧扩展信息"},"isSyncInnerPosition":{"type":"boolean","description":"是否同步内部职位"},"unionId":{"type":"string","description":"微信生态下的 unionid。"},"vCode":{"type":"string","description":"校验码"},"personalWorkType":{"type":"integer","format":"int64","description":"个人工作类型"},"bizMail":{"type":"string","description":"企业邮箱"},"attr3":{"type":"integer","format":"int64","description":"属性位 3"},"mobileAreaCode":{"type":"integer","format":"int64","description":"手机号国家码，如 86"}},"description":"用户扩展资料对象。\n\n**注意**：内部同事与外部联系人**返回的字段集不同**：内部有 `realName/englishName/bizMail/unionId/vCode/mainPartyId/holidayInfo/...`；外部只有 `uin/name/gender/iconUrl/corpId/attr2/attr3`。解析代码必须容忍缺字段，不能按内部档案的形状硬解外部联系人。"},"level":{"type":"integer","format":"int64","description":"联系人关系级别或状态枚举值，由平台定义。\n\n**注意**：内部同事 = `3`，外部联系人 = `1`。分档的确切含义未确认，仅可作为「两类联系人返回不同」的旁证。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"info":{"alias":"示例别名","attr":146082112,"attr2":777651084,"attr3":0,"bindEmailStatus":1,"birthday":"2000-09-01 12:00:00","bizMail":"xiaoyi@taichuinfo.cn","bizUin":1,"businessDesc":{"fieldId":"YnVzaV9kZXNj","fieldName":"5oiR55qE5Lia5Yqh","fieldType":4},"corpDesc":{"fieldId":"Y29ycF9kZXNj","fieldName":"5LyB5Lia5LuL57uN","fieldType":4},"corpDescInfo":{"infoName":"5LyB5Lia5ZCN54mH","jumpUrl":"d3h3b3JrOi8vanVtcD90YXJnZXQ9anVtcF90b190b29sJnRvb2xpZD0zMDAwMTAxMSZzY2VuZT0y","profileUrl":"aHR0cHM6Ly93b3JrLndlaXhp…<已截断>"},"corpId":1000000000000002,"customInfo":{},"dispOrder":0,"emailAddr":"","englishName":"XiaoYi-FuWuZhiChi","externFinder":{"addTime":1788245001,"finderId":"djJfMDYwMDAwMjMxMDAzYjIwZmFlYzhjYWUzOGUxZmMxZDdjZTAzZWUzY2IwNzdkOGQ4YzYzMTAwY2JlYjlkNzAxMDYwYWRhZGQ1YzE2NUBmaW5kZXI=","finderIntId":1,"image":"aHR0cHM6Ly93eC5xbG9nby5j…<已截断>","nickName":"5oqA5pyv5pSv5oyB5bCP5paH","status":2},"externalCustomInfo":{},"gender":1,"gid":1000000000000004,"holidayInfo":{"createTime":0,"holidayDesc":"","holidayGenerateSrc":0,"holidayIconIndex":0,"holidayInfoId":0,"holidayStatus":0,"holidayStatusNew":0,"oldHolidayIconIndex":0,"vacationSyncType":0},"iconUrl":"<省略>","internationCode":"86","inviteVid":1000000000000005,"isNameVerified":true,"isSyncInnerPosition":true,"job":"","mainPartyId":1000000000000003,"mobile":"","mobileAreaCode":0,"name":"示例昵称","nameVerifyStatus":1,"number":"","personalWorkType":0,"phone":"","position":"","realName":"示例用户","superiors":[{}],"tencentInfo":{},"uin":1000000000000001,"unionId":"<省略>","vCode":"<省略>","vCorpUseStatus":1000,"xcxStyle":0},"level":3,"vid":1000000000000001}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/phoneNumberSearch":{"post":{"tags":["联系人"],"summary":"按手机号搜索","description":"按手机号搜索。查不到时返回 `code: -1`（**不是**空列表）。\n\n命中后，返回里的 `wxTicket` / `openid` / `contactInfo.uin` / `contactInfo.corpId` 就是「按手机号添加」两个接口要的入参。","operationId":"ql_api_contact_phoneNumberSearch","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"phone":{"type":"string","description":"手机号（11 位）\n\n**注意**：11 位手机号字符串。号码不存在时返回 `code=-1 / 用户不存在`，而非空结果集——判空要按错误码判，不要按 `data` 是否为空数组判（`data` 直接是 `null`）。","examples":["138****0001"],"title":"手机号"}},"required":["appid","phone"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","phone":"13800000000"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"array","items":{"type":"object","properties":{"contactInfoWx":{"type":"object","properties":{"uin":{"type":"integer","format":"int64","description":"用户唯一数字 ID。外部联系人可从同步结果的 `userInfo.uin` 获取。","title":"用户 UIN"},"name":{"type":"string","description":"名称/昵称","title":"名称"},"gender":{"type":"integer","format":"int64","description":"性别枚举：`0` 未知，`1` 男，`2` 女。","enum":[0,1,2]},"iconUrl":{"type":"string","description":"头像 URL"}},"description":"匹配到的微信联系人基础资料。"},"openid":{"type":"string","description":"微信 OpenId\n\n**注意**：**搜索成功时返回**，是 `/api/contact/phoneNumberAddWechat` 的 `openid` 入参来源（该链路已确认）。此次落盘的是失败样本，成功返回体的其余字段未确认。"},"resultType":{"type":"integer","format":"int64","description":"搜索结果类型枚举；结合 `corpId` 等字段区分个人微信与企业微信。"}}},"description":"接口返回数据对象。不同接口的 data 结构不同。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":[{"contactInfo":{"alias":"示例别名","attr":134285632,"attr2":240779404,"attr3":0,"corpDescInfo":{},"corpId":1000000000000002,"customInfo":{},"englishName":"ZhangSan","externalCustomInfo":{},"gender":1,"gid":1000000000000019,"iconUrl":"<省略>","isNameVerified":true,"isSyncInnerPosition":true,"mainPartyId":1000000000000003,"mobile":"","name":"张三","nameVerifyStatus":1,"realName":"张三","schoolUserType":1,"uin":1000000000000018,"unionId":"<省略>","vCode":"<省略>"},"contactInfoWx":{"gender":1,"iconUrl":"<省略>","name":"示例微信昵称","uin":1000000000000020},"corpInfo":{"authCorpStatus":1,"authExpireTime":1816654520,"authLicenceStatus":3,"authTime":0,"authedDomain":"","bAuthedLicence":true,"cmSubmitTime":0,"corpAppWxaInfo":{"appId":"<省略>","enterPath":"/pages/index/index.html","userName":"gh_303bdfa3334c@app","version":0,"versionType":0},"corpCardUrl":"<省略>","corpDesc":"","corpFullName":"示例企业科技有限公司","corpId":1000000000000002,"corpLogo":"<省略>","corpName":"示例企业","corpStat":2,"corpType":15,"createSourceInfo":"","createTime":1785116462,"hasInfoCorp":false,"isAccepted":true,"isInitModUser":false,"joinNeedVerify":false,"language":1,"modUserInfo":{"name":"","vid":0},"ownerName":"示例法人","pstnOfficePhoneState":0,"sCorpId":"<省略>","staffInfo":{"alias":"示例别名","headImage":"https://example.com/...","internationCode":"86","mail":"","name":"张三","phone":"13800000000"},"staffNum":0,"trust":true,"verifyMsg":"","vid":1000000000000018,"virtualCreateDomainName":""},"flag":0,"openid":"<省略>","relation":0,"resultType":1,"searchStatus":1,"wxTicket":"<省略>"}]}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/phoneNumberAddWechat":{"post":{"tags":["联系人"],"summary":"按手机号添加微信用户","description":"通过手机号添加微信联系人。先调「手机号搜索」取得 `ticket` 与 `openid`，两个接口成对使用。\n\n⚠️ **返回码没有判别力**：即使不传任何标识字段也返回 `code = 0`。是否真的发出好友申请，需由对方是否收到来确认。","operationId":"ql_api_contact_phoneNumberAddWechat","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"ticket":{"type":"string","description":"凭证。由搜索/名片接口返回\n\n**注意**：与 `openid` 同批由搜索接口返回。属**凭证类字段**，日志与落库须脱敏。","examples":[""]},"openid":{"type":"string","description":"微信 OpenId\n\n**注意**：**来自 `/api/contact/phoneNumberSearch` 的返回**。这两个接口是成对使用的：先用手机号搜到人，再用搜到的 `openid` 发起添加。","examples":[""]},"verifyMessage":{"type":"string","description":"好友申请附言。","examples":["我是某某，添加你方便沟通一下"]},"remarkPhone":{"type":"array","items":{"type":"object","properties":{"phone":{"type":"string","description":"手机号（11 位）","examples":[""],"title":"手机号"}},"required":["phone"]},"description":"备注手机号列表，**对象数组**，元素形如 `{\"phone\": \"13800000000\"}`。不填时传空数组 `[]`，**不要传空字符串**。","examples":[[]]}},"required":["appid","ticket","openid","verifyMessage","remarkPhone"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","openid":"<省略>","remarkPhone":[{"phone":"13800000000"}],"ticket":"<省略>","verifyMessage":"您好，我想添加您为好友"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：**未采集返回体**，字段清单未知。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/phoneNumberAddWework":{"post":{"tags":["联系人"],"summary":"按手机号添加企业微信用户","description":"按手机号添加企业微信用户。入参取自「按手机号搜索」的返回。⚠️ 字段名是**全小写 `userid`**；不能添加自己。","operationId":"ql_api_contact_phoneNumberAddWework","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userid":{"type":"integer","format":"int64","examples":[0],"title":"企业微信用户 ID","description":"目标用户 ID。⚠️ 注意字段名是**全小写 `userid`**，与其他接口的 `userId` 不一致。"},"corpId":{"type":"integer","format":"int64","description":"企业 ID。\n\n**注意**：目标方所属企业 ID。**未用真实他企业的 `corpId` 验证过成功路径**。","examples":[0],"title":"企业 ID"},"ticket":{"type":"string","description":"凭证。由搜索/名片接口返回\n\n**注意**：契约称由搜索/名片接口返回，但**企微侧取 `ticket` 的具体入口未确认**（已验证的 `phoneNumberSearch` 是个微链路）。","examples":[""]},"verifyMessage":{"type":"string","description":"好友申请附言。","examples":["你好，我是某某，很高兴认识你"]},"remarkPhone":{"type":"array","items":{"type":"object","properties":{"phone":{"type":"string","description":"手机号（11 位）","examples":[""],"title":"手机号"}},"required":["phone"]},"description":"备注手机号列表，**对象数组**，元素形如 `{\"phone\": \"13800000000\"}`。不填时传空数组 `[]`，**不要传空字符串**。"}},"required":["appid","userid","corpId","ticket","verifyMessage","remarkPhone"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","corpId":1000000000000002,"remarkPhone":[{"phone":"13800000000"}],"ticket":"<省略>","userid":1000000000000018,"verifyMessage":"您好，我想添加您为好友"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/agreeToNewCustomer":{"post":{"tags":["联系人"],"summary":"同意好友申请","description":"同意新客户的好友申请。⚠️ 入参字段是 **`userId`**（旧契约写的 `uin` 已不再受理，会返回 `user profile result is empty`）。\n\n待同意的客户从「同步外部联系人」取（**`businessId` 传 `1`**）。\n\n**成功判据不是 `code = 0`**：要复核该 uin 在「同步外部联系人」里的 `flag` —— 由 `8`（非好友）变成 `2057`（正常好友）才算真的成功。","operationId":"ql_api_contact_agreeToNewCustomer","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userId":{"type":"integer","title":"用户 ID","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","format":"int64","examples":[7881000000000001]}},"required":["appid","userId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","userId":7881000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/updateExternalContactInfo":{"post":{"tags":["联系人"],"summary":"更新外部联系人资料","description":"修改外部联系人的备注信息。⚠️ 入参字段是 **`userId`**（旧契约写的 `vid` 已不再受理）。","operationId":"ql_api_contact_updateExternalContactInfo","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userId":{"type":"integer","title":"用户 ID","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","format":"int64","examples":[7881000000000002]},"remark":{"type":"string","description":"备注信息。用于联系人备注或群备注等场景。","examples":["测试下"]},"realRemark":{"type":"string","examples":["老大"],"description":"联系人真实姓名备注。传空字符串可清空。"},"remarkPhone":{"type":"array","items":{"type":"object","properties":{"phone":{"type":"string","description":"手机号（11 位）","examples":["138****0002"],"title":"手机号"}},"required":["phone"]},"description":"备注手机号列表，元素形如 `{\"phone\": \"13800000000\"}`。","examples":[[]]},"companyRemark":{"type":"string","examples":["利荣科技"],"description":"企业名称"},"remarkUrl":{"type":"string","examples":[""],"description":"联系人备注图片或关联资源地址；无内容时传空字符串。"}},"required":["appid","userId","remark","realRemark","remarkPhone","companyRemark","remarkUrl"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","userId":7881000000000002,"remark":"测试下","realRemark":"老大","remarkPhone":[],"companyRemark":"利荣科技","remarkUrl":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/delete":{"post":{"tags":["联系人"],"summary":"删除联系人","description":"删除联系人。**不可逆。**\n\n⚠️ **返回码没有判别力**：任何格式合法的 ID 都会返回 `code = 0`，包括不存在的和已删除的联系人。「获取联系人详细资料」同样无法判断 —— 删除前后逐字段一致。\n判据是「同步外部联系人」中该 `uin` 的 `flag`：`2057` 为正常好友，`8` 表示已不是好友。","operationId":"ql_api_contact_delete","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userId":{"type":"integer","format":"int64","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","examples":[7881000000000001],"title":"用户 ID"}},"required":["appid","userId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","userId":1000000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`，不回显任何删除结果。**没有任何字段可以用来确认删除是否生效。**","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/setColleagueRemark":{"post":{"tags":["联系人"],"summary":"设置同事备注","description":"设置内部同事的备注与描述。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_contact_setColleagueRemark","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userId":{"type":"integer","format":"int64","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","examples":[1688000000000004],"title":"用户 ID"},"remark":{"type":"string","description":"备注信息。用于联系人备注或群备注等场景。","examples":["备注"]},"description":{"type":"string","examples":["描述"],"description":"同事备注描述。传空字符串可清空。\n\n**注意**：契约无描述。与 `remark` 一同提交、`code=0`；其在客户端上的展示位置未确认。传空串同样返回 `code=0`（用空串做过还原）。"}},"required":["appid","userId","remark","description"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","description":"","remark":"","userId":1000000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时为 `null`，**不回显备注内容**。校验是否生效需另行读取通讯录。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/addCard":{"post":{"tags":["联系人"],"summary":"通过名片添加","description":"通过名片添加联系人。入参字段为 **`userId`**（旧契约中的 `cardSourceUserId` 已废弃）。\n\n`ticket` 取自「同步外部联系人」（`businessId = 1`）的 `list[].content.extraInfo.openimAddContactRspTicket`，长度约 512 字符。\n⚠️ 会话中收到的名片消息本身**不携带该凭证**，无法仅凭收到的名片完成添加。","operationId":"ql_api_contact_addCard","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"ticket":{"type":"string","description":"凭证。由搜索/名片接口返回\n\n**注意**：契约称由搜索/名片接口返回，但**未取得过确认有效的名片 ticket**，因此无法判断 `-2013` 是否由 ticket 无效引起。属凭证类字段，日志须脱敏。","examples":[""]},"verifyMessage":{"type":"string","description":"好友申请附言。","examples":[""]},"userId":{"type":"integer","format":"int64","title":"用户 ID","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","examples":[1000000000000001]}},"required":["appid","ticket","verifyMessage","userId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","ticket":"","verifyMessage":"","userId":1000000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/addRoomMember":{"post":{"tags":["联系人"],"summary":"从群里添加联系人","description":"把群内成员添加为联系人。`userId` 传该成员在群里的 ID，可从「获取群资料」的 `members[].vid` 取。\n\n⚠️ **`code = 0` 不代表申请已发出**：对外部联系人调用通常返回成功，但对方可能收不到申请；对内部同事或异常账号返回 `-3501`。\n若目的是把成员拉进群聊，请改用「添加群成员」。","operationId":"ql_api_contact_addRoomMember","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userId":{"type":"string","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","examples":[""],"title":"用户 ID"},"roomId":{"type":"string","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[""],"title":"群聊 ID"}},"required":["appid","userId","roomId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","userId":"","roomId":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/syncExternal":{"post":{"tags":["联系人"],"summary":"同步外部联系人","description":"同步外部联系人。⚠️ `businessId` **要传 `1`** —— 传 `0` 会返回空列表且不报错，容易被误当成「没有外部联系人」。","operationId":"ql_api_contact_syncExternal","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"seq":{"type":"integer","format":"int64","description":"增量游标，首次传 `0`。","examples":[15873502],"title":"同步序号"},"businessId":{"type":"integer","format":"int64","description":"业务类型，**传 `1`**。传 `0` 会返回空列表且不报错。","examples":[1]},"limit":{"type":"integer","description":"单页条数。"}},"required":["appid","seq","businessId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","businessId":0,"seq":0}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"businessId":{"type":"integer","format":"int64","description":"业务类型。**外部联系人同步固定传 1**"},"list":{"type":["string","null"],"description":"数据列表"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"businessId":0,"list":null}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/getCorpBriefInfoList":{"post":{"tags":["联系人"],"summary":"获取企业简要信息","description":"批量获取企业简要信息。`corpIds` 传企业 ID 数组，**不能为空数组**（会返回 `-2003`）。企业 ID 可从联系人资料的 `corpId` 取。","operationId":"ql_api_contact_getCorpBriefInfoList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"corpIds":{"type":"array","items":{"type":"string"},"examples":[[]]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","corpIds":[]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/contact/updateLabel":{"post":{"tags":["联系人"],"summary":"更新联系人标签","description":"更新某位联系人身上的标签。`operItems` 为空数组时表示清空。","operationId":"ql_api_contact_updateLabel","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userId":{"type":"integer","format":"int64","examples":[1688855874759204],"description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。"},"operItems":{"type":"array","items":{"type":"object","properties":{"op":{"type":"integer","examples":[2]},"label":{"type":"object","properties":{"id":{"type":"integer","format":"int64","examples":[14073752025997020]},"name":{"type":"string","examples":["测试"]},"dataType":{"type":"integer","examples":[1]},"bDeleted":{"type":"integer","examples":[0]},"labelGroupId":{"type":"integer","format":"int64","examples":[14073751126007792]},"createTime":{"type":"integer","examples":[1787907966]},"labelType":{"type":"integer","examples":[1]},"businessType":{"type":"integer","examples":[0]},"order":{"type":"integer","examples":[0]},"serviceGroupId":{"type":"integer","examples":[0]}},"examples":[{"id":14073752025997020,"name":"测试","dataType":1,"bDeleted":0,"labelGroupId":14073751126007792,"createTime":1787907966,"labelType":1,"businessType":0,"order":0,"serviceGroupId":0}]}}},"examples":[[{"op":2,"label":{"id":14073752025997020,"name":"测试","dataType":1,"bDeleted":0,"labelGroupId":14073751126007792,"createTime":1787907966,"labelType":1,"businessType":0,"order":0,"serviceGroupId":0}}]]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","userId":1688855874759204,"operItems":[{"op":2,"label":{"id":14073752025997020,"name":"测试","dataType":1,"bDeleted":0,"labelGroupId":14073751126007792,"createTime":1787907966,"labelType":1,"businessType":0,"order":0,"serviceGroupId":0}}]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/getInfo":{"post":{"tags":["群聊"],"summary":"获取群资料","description":"获取群资料。返回的 `roomInfo` 只有群号、群名、群主、创建时间等基本字段 —— **不含群公告、不含各项群开关的状态**，这些无法通过接口读回。","operationId":"ql_api_room_getInfo","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[10000000000000000],"title":"群聊 ID"}},"required":["appid","roomId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000024}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"roomInfo":{"type":"object","properties":{"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"roomName":{"type":"string","description":"群名称"},"ownerVid":{"type":"integer","format":"int64","description":"群主 vid"},"createTime":{"type":"integer","format":"int64","description":"创建时间戳（秒）"},"oldOwnerVid":{"type":"integer","format":"int64","description":"原群主 vid"},"oprNewFlag":{"type":"integer","format":"int64","description":"操作标志位\n\n**注意**：两个群都返回 `6`，语义未确认。"}},"description":"群基本信息"},"members":{"type":"array","items":{"type":"object","properties":{"vid":{"type":"integer","format":"int64","description":"企业微信成员 VID。可从通讯录同步或成员资料接口获取。","title":"成员 VID"},"joinTime":{"type":"integer","format":"int64","description":"入群时间戳"},"inviteVid":{"type":"integer","format":"int64","description":"邀请人 vid"},"memberType":{"type":"integer","format":"int64","description":"成员类型"},"remark":{"type":"string","description":"备注信息。用于联系人备注或群备注等场景。"},"flag":{"type":"integer","format":"int64","description":"状态标志位（按位含义见平台文档）"},"source":{"type":"integer","format":"int64","description":"来源名称。**sendLink 必填**，缺失会报 content.source is required"}}},"description":"群成员列表"},"data":{"type":"object","properties":{},"description":"接口返回数据对象。不同接口的 data 结构不同。","title":"业务数据"}},"description":"业务返回数据；字段结构见下方定义。\n\n**注意**：恒为 `{}`（与 `data.members` 同级），用途未确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"data":{},"members":[{"flag":0,"inviteVid":1000000000000001,"joinTime":1788424706,"memberType":0,"remark":"","source":1,"vid":1000000000000001}],"roomInfo":{"createTime":1788424706,"oldOwnerVid":0,"oprNewFlag":6,"ownerVid":1000000000000001,"roomId":"10000000000000024","roomName":"示例-临时群2"}}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/delMember":{"post":{"tags":["群聊"],"summary":"移除群成员","description":"把成员移出群。⚠️ 入参是 **`userIdList`（数组）**，不是单个 `userId`。\n\n注意「设置群管理员」仍然是单数 `userId`，两个接口不一致，不要统一。","operationId":"ql_api_room_delMember","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000001],"title":"群聊 ID"},"userIdList":{"type":"array","title":"用户 ID 列表","description":"要移出群的用户 ID 列表。**必须是数组**。","items":{"type":"integer","format":"int64"},"examples":[[1688000000000001]]},"userId":{"type":"integer","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。"}},"required":["appid","roomId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。","anyOf":[{"required":["userIdList"]},{"required":["userId"]}]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000024,"userId":1000000000000018}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；且回调无有效载荷、未做成员表回读，`code=0` 是唯一证据。建议接入方自行补 `getInfo` 校验。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/addMember":{"post":{"tags":["群聊"],"summary":"添加群成员","description":"拉人进群。⚠️ 入参是 **`userIdList`（数组）**，不是单个 `userId`。内部同事与外部联系人都可以拉。\n\n⚠️ **对外部成员是异步的**：同步一律返回 `code = 0`，真实结果看回调 —— 成功推 `contentType = 1002`（入群），失败推 `contentType = 1037`，失败原因在其 `content.hex` 里（例如「账号处于异常状态，无法加入外部群聊」）。所以**不能拿返回码当成功判据**，要么读回调，要么回读群成员列表。","operationId":"ql_api_room_addMember","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[10000000000000000],"title":"群聊 ID"},"userIdList":{"type":"array","title":"用户 ID 列表","description":"要拉进群的用户 ID 列表。**必须是数组**。","items":{"type":"integer","format":"int64"},"examples":[[1688000000000001]]},"userId":{"type":"integer","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。"}},"required":["appid","roomId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。","anyOf":[{"required":["userIdList"]},{"required":["userId"]}]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000024,"userId":1000000000000018}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；生效证据来自回调 `1002` 的 vid 载荷。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/setName":{"post":{"tags":["群聊"],"summary":"修改群名","description":"修改群名称。若群开启了「禁止改群名」则会失败。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_setName","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[10000000000000000],"title":"群聊 ID"},"roomName":{"type":"string","description":"群名称\n\n**注意**：中文可用。**长度上限、特殊字符、传空串能否清空群名，均未确认。**","examples":["橘子炸鸡代理1"]}},"required":["appid","roomId","roomName"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000024,"roomName":"示例-临时群2"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/getQrCode":{"post":{"tags":["群聊"],"summary":"获取群二维码","description":"获取群二维码。\n\n:::warning\n⚠️ **调用注意**\n\n若群主已开启进群验证，二维码会被停用并返回 -18000059。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_getQrCode","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000001],"title":"群聊 ID"}},"required":["appid","roomId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"qrcodeUrl":{"type":"string","title":"二维码地址","description":"群二维码的访问地址。"},"qrcodeImage":{"type":"string","title":"二维码图片","description":"群二维码图片数据，具体形态以服务端返回为准。"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"qrcodeImage":"<省略>","qrcodeUrl":"<省略>","roomId":"10000000000000006"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/setNotice":{"post":{"tags":["群聊"],"summary":"发布群公告","description":"发布群公告。发布后群内会产生系统消息，可从回调里看到。","operationId":"ql_api_room_setNotice","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000002],"title":"群聊 ID"},"notice":{"type":"string","description":"群公告正文\n\n**注意**：公告正文。**这段文本会被平台原样当作一条群文本消息（ct=2）推回给你自己**（见回调段），写入前请评估它对自身消息处理链路的影响。","examples":["测试公告"]}},"required":["appid","roomId","notice"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":1000000000000001,"notice":"示例内容"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`。成功与否只能看 `code`——`getInfo` 不返回群公告，**没有程序化回读手段**。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/setAdmin":{"post":{"tags":["群聊"],"summary":"设置/取消群管理员","description":"设置群管理员。\n\n⚠️ **只能设置，不能取消。** `enable: true` 会真正生效（`room/getInfo` 的 `members[].memberType` 由 `0` 变为 `2`）；但 `enable: false` **返回 `code = 0` 却不会生效** —— 多次调用、等待 90 秒后 `memberType` 仍为 `2`。取消管理员目前只能在企业微信客户端里操作。","operationId":"ql_api_room_setAdmin","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000001],"title":"群聊 ID"},"userId":{"type":"integer","format":"int64","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","examples":[1688000000000001],"title":"用户 ID"},"enable":{"type":"boolean","description":"`true` = 设为管理员（生效）。⚠️ `false` 虽然返回成功，但**实际不会取消**。","examples":[false]}},"required":["appid","roomId","userId","enable"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","enable":false,"roomId":10000000000000023,"userId":1000000000000018}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`。`enable=true` 可用回调 `1043` 佐证；**`enable=false` 无回调、无回读，`code=0` 是唯一证据**。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/changeOwner":{"post":{"tags":["群聊"],"summary":"转让群主","description":"转让群主。\n\n:::danger\n⛔ **高风险操作**\n\n群主转让会改变群管理权限，请确认目标成员和当前操作者权限。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_changeOwner","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000001],"title":"群聊 ID"},"userId":{"type":"integer","format":"int64","description":"用户 ID。同事取通讯录 `vid`，外部联系人取 `uin`。","examples":[1688000000000001],"title":"用户 ID"}},"required":["appid","roomId","userId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000023,"userId":1000000000000018}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；生效证据来自回调 `1022`（含新群主 vid + 「已经成为新的群主」文案）。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/create":{"post":{"tags":["群聊"],"summary":"创建群聊","description":"创建客户群。只需 appid。返回 roomId 与入群邀请链接。\n\n:::tip\n🔗 **调用关系**\n\n创建客户群 → 保存 `roomId` → 使用群资料或群管理接口继续配置。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_create","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"userList":{"type":"array","items":{"type":"integer"},"description":"建群时一并拉进来的成员 ID 列表。可选：接口定义里没有登记这个字段，经平台验证传了它能正常建群；不传则建一个只有自己的群。"}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","userList":[1000000000000018]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"inviteUrl":{"type":"string","description":"入群邀请链接"},"title":{"type":"string","description":"标题。用于链接、小程序、朋友圈等卡片展示。","title":"标题"},"desc":{"type":"string","description":"描述内容。用于联系人、链接、卡片或朋友圈场景。"},"avatarUrl":{"type":"string","description":"头像 URL"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"extra":{"type":"object","properties":{"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"field2":{"type":"string","description":"平台保留字符串字段 2。"},"operatorVid":{"type":"integer","format":"int64","description":"执行创建操作的成员 VID。"},"createTime":{"type":"integer","format":"int64","description":"创建时间戳（秒）"},"field5":{"type":"integer","format":"int64","description":"平台保留数值字段 5。"},"field6":{"type":"integer","format":"int64","description":"平台保留数值字段 6。"},"field8":{"type":"integer","format":"int64","description":"平台保留数值字段 8。"},"roomKey":{"type":"string","description":"群聊内部密钥标识；属于敏感透传字段，请勿公开。"},"field11":{"type":"integer","format":"int64","description":"平台保留数值字段 11。"},"type":{"type":"integer","format":"int64","description":"设备类型，如 iPad","title":"类型"},"field22":{"type":"integer","format":"int64","description":"平台保留数值字段 22。"}},"description":"平台返回的群聊扩展信息。未明确的 `field*` 字段建议原样保留。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"avatarUrl":"<省略>","desc":"示例用户在企业微信中邀请你加入群聊，用正式的名片聊工作","extra":{"createTime":1788424706,"field11":0,"field2":"","field22":4,"field5":0,"field6":0,"field8":0,"operatorVid":1000000000000001,"roomId":"10000000000000024","roomKey":"l3imnhXuTaKM5j7n","type":2},"inviteUrl":"<省略>","roomId":"10000000000000024","title":"邀请你加入企业微信群聊"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/setMyNickname":{"post":{"tags":["群聊"],"summary":"修改我的群昵称","description":"设置我在本群的昵称。改完可从「获取群资料」的 `members[].remark` 读回验证。⚠️ **不接受空字符串**（返回 `code = -1`），要清空只能改成别的值或在客户端操作。","operationId":"ql_api_room_setMyNickname","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[10000000000000000],"title":"群聊 ID"},"nickname":{"type":"string","description":"本群昵称。**不能传空字符串**。","examples":["虾·"]}},"required":["appid","roomId","nickname"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","nickname":"示例","roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`，且无任何回读接口，`code=0` 是唯一证据。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/saveToContact":{"post":{"tags":["群聊"],"summary":"群聊保存到通讯录","description":"把群保存到通讯录，便于快速查找。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_saveToContact","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000001],"title":"群聊 ID"},"enable":{"type":"boolean","description":"`true` = 开启，`false` = 关闭。","examples":[false]}},"required":["appid","roomId","enable"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","enable":false,"roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；无回读字段，`code=0` 是唯一证据，且该 code 未做过独立复核。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/getMyCustomerGroupList":{"post":{"tags":["群聊"],"summary":"查询我的客户群","description":"查询我的客户群。注意返回里的 `roomId` / `id` 是**字符串**，回传给其他接口前需转成整数。","operationId":"ql_api_room_getMyCustomerGroupList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"limit":{"type":"integer","format":"int64","description":"单页条数。","examples":[2000],"title":"分页大小","minimum":1}},"required":["appid","limit"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","limit":50}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"roomData":{"type":"object","properties":{"list":{"type":"array","items":{"type":"object","properties":{"id":{"type":"integer","format":"int64","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"roomId":{"type":"integer","format":"int64","description":"群聊 ID。可从创建群、群列表、群详情或回调事件中获取。","title":"群聊 ID"},"ownerVid":{"type":"integer","format":"int64","description":"群主 vid"},"createTs":{"type":"integer","format":"int64","description":"群聊创建时间，Unix 时间戳（秒）。"},"updateTs":{"type":"integer","format":"int64","description":"群聊最近更新时间，Unix 时间戳（秒）。"},"memberCount":{"type":"integer","format":"int64","description":"成员数"},"flag":{"type":"integer","format":"int64","description":"状态标志位（按位含义见平台文档）"},"roomName":{"type":"string","description":"群名称"},"roomUrl":{"type":"string","description":"群头像 URL"},"shiftTime":{"type":"integer","format":"int64","description":"群聊迁移或状态切换时间，Unix 时间戳（秒）；无记录时通常为 0。"},"oldOwnerVid":{"type":"integer","format":"int64","description":"原群主 vid"},"isCannotOnJobSucceed":{"type":"boolean","description":"是否存在无法完成在职继承的状态。"}}},"description":"数据列表"}},"description":"群数据集合"},"nextStart":{"type":"integer","format":"int64","description":"下页起始游标，-1 表示无更多\n\n**注意**：单页取完时为 `-1`。翻页语义（是否作为下一页入参）未确认。"},"totalCount":{"type":"integer","format":"int64","description":"总条数"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"nextStart":-1,"roomData":{"list":[{"createTs":1787542315,"flag":0,"id":"1000000000000000008","isCannotOnJobSucceed":false,"memberCount":6,"oldOwnerVid":0,"ownerVid":1000000000000001,"roomId":"10000000000000006","roomName":"示例群","roomUrl":"<省略>","shiftTime":0,"ticket":"<省略>","updateTs":1788423855}]},"totalCount":1}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/top":{"post":{"tags":["群聊"],"summary":"置顶/取消置顶群聊","description":"会话置顶/取消置顶。作用于整个会话，不是群内消息置顶。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_top","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[7881000000000002],"title":"群聊 ID"},"enable":{"type":"boolean","description":"`true` = 开启，`false` = 关闭。","examples":[false]}},"required":["appid","roomId","enable"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","enable":false,"roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；且无任何接口能查回当前置顶状态，`code=0` 是唯一证据。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/quit":{"post":{"tags":["群聊"],"summary":"退出群聊","description":"退出群聊。\n\n⚠️ **群主不能直接退群**（返回 `-2003`）：需先把群主转让给其他成员，成为普通成员后再退出，或直接解散群。群主且群内仅剩本人时返回 `-1`。","operationId":"ql_api_room_quit","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"string","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[""],"title":"群聊 ID"}},"required":["appid","roomId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000023}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；回调也全是空信令，`code=0` 是唯一证据，且**未做退群后的列表复核**。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/inviteConfirm":{"post":{"tags":["群聊"],"summary":"开启/关闭入群确认","description":"开启/关闭入群确认。⚠️ 该开关的当前状态**无法通过任何只读接口读回**，需要在企业微信客户端「群设置」里确认。`top` / `saveToContact` / `forbidMutualAdd` / `forbidRename` / `setAdmin` 同此。","operationId":"ql_api_room_inviteConfirm","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[1970000000000001],"title":"群聊 ID"},"enable":{"type":"boolean","description":"`true` = 开启，`false` = 关闭。","examples":[false]}},"required":["appid","roomId","enable"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","enable":false,"roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`。无回调、无回读，`code=0` 是唯一信号且**可信度存疑**（。段）。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/forbidRename":{"post":{"tags":["群聊"],"summary":"禁止/允许成员改群名","description":"群管理：禁止/允许成员修改群名。enable=true 为禁止。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_forbidRename","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[10000000000000000],"title":"群聊 ID"},"enable":{"type":"boolean","description":"`true` = 开启，`false` = 关闭。","examples":[false]}},"required":["appid","roomId","enable"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","enable":false,"roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；成功证据来自回调 `1022` 的中文文案，不是来自返回体。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/forbidMutualAdd":{"post":{"tags":["群聊"],"summary":"禁止/允许群内互加","description":"群管理：禁止/允许群成员之间互相添加好友。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_room_forbidMutualAdd","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[10000000000000000],"title":"群聊 ID"},"enable":{"type":"boolean","description":"`true` = 开启，`false` = 关闭。","examples":[true]}},"required":["appid","roomId","enable"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","enable":false,"roomId":10000000000000006}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：恒为 `null`；成功证据来自回调 `1022` 的中文文案。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/confirmInvitedMemberList":{"post":{"tags":["群聊"],"summary":"确认受邀入群成员","description":"群主确认受邀入群的成员。\n\n**触发条件**：群需先通过「设置入群邀请确认」打开开关，之后由**群成员**（不是群主）邀请新人，群主才会收到 `contentType = 1029` 的回调。\n\n五个入参全部来自那条回调：`msgId` 取回调的 `id` 字段，`roomId` / `fromVid` / `ticket` / `newMembers` 取自其 `content`。确认后成员立即进群，可用群资料回读验证。","operationId":"ql_api_room_confirmInvitedMemberList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"msgId":{"type":"string","examples":[""]},"roomId":{"type":"string","examples":[""],"description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"},"fromVid":{"type":"string","examples":[""]},"ticket":{"type":"string","examples":[""]},"newMembers":{"type":"array","items":{"type":"string"},"examples":[[]]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","msgId":"","roomId":"","fromVid":"","ticket":"","newMembers":[]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/disband":{"post":{"tags":["群聊"],"summary":"解散群聊","description":"解散群聊，**仅群主可用，不可撤销**。字段名是小驼峰 `roomId`。","operationId":"ql_api_room_disband","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。","examples":[0]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":0}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/getInfoBatch":{"post":{"tags":["群聊"],"summary":"批量获取群资料","description":"批量获取群资料。入参是 **`roomIds`（数组）** —— 契约里漏标了这个字段。结果在 `data.roomInfos`，比单个查询多返回群公告、`roomKey`、客户群类型等字段。","operationId":"ql_api_room_getInfoBatch","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomIds":{"type":"array","items":{"type":"integer","format":"int64"},"description":"群 ID 数组。契约里漏标了本字段。","examples":[[10000000000000000]]}},"required":["appid","roomIds"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomIds":[10000000000000000]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/groupMemberChange":{"post":{"tags":["群聊"],"summary":"同步群成员变更","description":"增量同步群成员变更。`ver` 是 **base64 字符串**不是数字，**首次传空字符串**取全量，之后回传上次的版本值。结果在 `data.roomInfos`。","operationId":"ql_api_room_groupMemberChange","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","examples":[10744306939831996],"description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"},"ver":{"type":"string","examples":["COfeiAUSDTEuMC4xMC4yMjkwNDM="],"description":"版本游标，**base64 字符串**（不是数字）。首次传空字符串取全量。"},"memberCount":{"type":"integer","examples":[2]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10744306939831996,"ver":"COfeiAUSDTEuMC4xMC4yMjkwNDM=","memberCount":2}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/sessionQueryList":{"post":{"tags":["群聊"],"summary":"查询会话组","description":"查询会话组配置。无需入参，结果在 `data.shieldList`。","operationId":"ql_api_room_sessionQueryList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/sessionSet":{"post":{"tags":["群聊"],"summary":"配置会话组","description":"配置会话组。入参 `roomId` —— 契约里漏标了这个字段。","operationId":"ql_api_room_sessionSet","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","format":"int64","description":"群 ID。契约里漏标了本字段。","examples":[10000000000000000]}},"required":["appid","roomId"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":10000000000000000}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/sessionSync":{"post":{"tags":["群聊"],"summary":"同步会话列表","description":"同步会话列表。`sync` 首次传 `0` 取全量。返回 `sessionList` / `topList` / `shieldList` 与游标 `syncKey`。","operationId":"ql_api_room_sessionSync","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"limit":{"type":"integer","examples":[1000],"description":"单页条数。"},"sync":{"type":"integer","examples":[15875771]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","limit":1000,"sync":15875771}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/room/setRemark":{"post":{"tags":["群聊"],"summary":"设置群备注","description":"设置群备注（只影响自己看到的名称，不改群名）。","operationId":"ql_api_room_setRemark","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"roomId":{"type":"integer","examples":[0],"description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"},"remark":{"type":"string","examples":[""]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","roomId":0,"remark":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/sendSns":{"post":{"tags":["朋友圈"],"summary":"发布朋友圈","description":"发布朋友圈。**content 是字符串**，不是对象。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_friend_sendSns","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"content":{"type":"string","description":"动态正文，纯文本字符串。","examples":["（历史内容，已脱敏）"],"title":"内容"}},"required":["appid","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":"这是一条朋友圈文本内容"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"baseRsp":{"type":"object","properties":{"ret":{"type":"integer","format":"int64","description":"内部返回码，0 为正常"}},"description":"基础响应体，含 ret 字段"},"snsInfo":{"type":"object","properties":{"sid":{"type":"integer","format":"int64","description":"朋友圈动态 ID。由 /api/friend/getSnsList 返回的 data[].sid 提供\n\n**注意**：19 位 int64（如 7679000000000000001），已超过 JS `Number.MAX_SAFE_INTEGER`（≈9.007e15）。JSON 解析必须按字符串/BigInt 处理，否则末位会被四舍五入，拿去删动态会删不掉或删错。"},"authorVid":{"type":"integer","format":"int64","description":"作者 vid"},"seq":{"type":"integer","format":"int64","description":"增量同步序号。首次请求通常传 `0`，后续传上次响应返回的序号。","title":"同步序号"},"time":{"type":"integer","format":"int64","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","title":"服务端时间"},"content":{"type":"string","description":"消息/动态正文。纯文本类接口传字符串；媒体类传对象（把上传接口返回的 data 整体带上）","title":"内容"},"postId":{"type":"string","description":"朋友圈动态内部 ID"},"isDelete":{"type":"boolean","description":"是否已删除"},"updateTime":{"type":"integer","format":"int64","description":"更新时间戳"},"taskSid":{"type":"integer","format":"int64","description":"关联任务 ID"},"visibleType":{"type":"integer","format":"int64","description":"可见范围类型"},"poiInfo":{"type":"object","properties":{"poiName":{"type":"string","description":"位置名称"},"longitude":{"type":"string","description":"经度"},"latitude":{"type":"string","description":"纬度"},"poiId":{"type":"string","description":"位置兴趣点（POI）ID。"},"city":{"type":"string","description":"位置所在城市。"},"address":{"type":"string","description":"居住地址"},"country":{"type":"string","description":"位置所在国家或地区。"}},"description":"位置信息"},"type":{"type":"integer","format":"int64","description":"设备类型，如 iPad","title":"类型"},"notifyTime":{"type":"integer","format":"int64","description":"朋友圈通知时间，Unix 时间戳（秒）。"},"notifyVid":{"type":"integer","format":"int64","description":"朋友圈通知关联的成员 VID。"}},"description":"已发布朋友圈的动态详情。\n\n**注意**：刚发布动态的完整记录，字段与 `getSnsDetails` 的返回对象一一对应（缺 `xid`）。`snsInfo.sid` 是后续所有朋友圈操作的唯一入参来源，务必落库。"},"limitLineData":{"type":"object","properties":{"limit":{"type":"integer","format":"int64","description":"单页数量。建议控制在接口推荐范围内。","title":"分页大小","minimum":1},"wording":{"type":"string","description":"提示文案"}},"description":"朋友圈可见范围配置。"},"groupLimitLineData":{"type":"object","properties":{"limit":{"type":"integer","format":"int64","description":"单页数量。建议控制在接口推荐范围内。","title":"分页大小","minimum":1},"wording":{"type":"string","description":"提示文案"}},"description":"按群组设置的朋友圈可见范围配置。"},"ret":{"type":"integer","format":"int64","description":"内部返回码，0 为正常\n\n**注意**：值 3，与 `data.baseRsp.ret = 0` 并存。**不是失败标志**——同一条动态随后被成功查询/点赞/评论/删除。含义未确认，判成败请只看外层 `code`。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"baseRsp":{"retCode":0},"corpLimtLine":{"validTime":26698},"limtLine":{"validTime":26698},"postInfo":{"authorVid":1000000000000001,"content":"这是一条朋友圈文本内容","flag":0,"linkInfo":{},"notifyTime":0,"notifyVid":0,"poiInfo":{},"seq":1788424502186,"sid":"1000000000000000021","taskSid":0,"time":1788424502,"type":0,"updateTime":1788424502186,"visibleType":0},"totalSendCnt":1}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/getSnsList":{"post":{"tags":["朋友圈"],"summary":"查询朋友圈列表","description":"查询朋友圈列表。⚠️ **返回结果包含已删除的动态**，用 `flag` 区分：`0` = 正常，`1` = 已删除。**请自行过滤 `flag == 1`**，否则会把删掉的动态当成还在。","operationId":"ql_api_friend_getSnsList","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"maxId":{"type":"integer","format":"int64","description":"分页游标。首页传 `0`，续页传上一页最后一条的 `id`。","examples":[0]},"limit":{"type":"integer","format":"int64","description":"单页条数。","examples":[30],"title":"分页大小","minimum":1}},"required":["appid","maxId","limit"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","limit":10,"maxId":0}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：**直接是动态对象数组**，不是 `{list: []}`。契约原描述有误。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":[{"authorVid":1000000000000001,"content":"这是一条朋友圈文本内容","flag":0,"linkInfo":{},"notifyTime":0,"notifyVid":0,"poiInfo":{},"seq":1788424502186,"sid":"1000000000000000021","taskSid":0,"time":1788424502,"type":0,"updateTime":1788424502186,"visibleType":0}]}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/setSnsSignature":{"post":{"tags":["朋友圈"],"summary":"设置朋友圈签名","description":"设置朋友圈个性签名。参数名是 content，不是 signature。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_friend_setSnsSignature","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"content":{"type":"string","description":"签名正文，传空串可清除。","examples":["测试下00000000"],"title":"内容"}},"required":["appid","content"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：为**空对象 `{}`**，不回显新签名，也没有 `baseRsp`。因此**无法从返回值判断签名是否真的生效**，且没有可用于回读的查询接口。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/likeSns":{"post":{"tags":["朋友圈"],"summary":"点赞/取消点赞","description":"点赞 / 取消点赞。\n\n⚠️ **`cancel` 的取值可能与你手上的旧文档相反，请以此处为准**：`cancel: true` 是**点赞**，`cancel: false` 是**取消点赞**。","operationId":"ql_api_friend_likeSns","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"sid":{"type":"integer","format":"int64","description":"朋友圈动态 ID。取自「查询朋友圈列表」。⚠️ 列表返回的是**字符串**，此处需传**整数**。","examples":[7664681089236780000]},"cancel":{"type":"boolean","description":"`true` = 点赞，`false` = 取消点赞。（取值与旧文档相反，以本文档为准）","examples":[false]}},"required":["appid","sid","cancel"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","cancel":true,"sid":1000000000000000021}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：返回 **`null`**（不是 `{}`）。取字段前必须判空。同分类的 `deleteSns` / `setSnsSignature` 返回的是 `{}`，返回形态不统一。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"baseRsp":{"retCode":0}}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/getSnsDetails":{"post":{"tags":["朋友圈"],"summary":"查询朋友圈详情","description":"查询朋友圈详情。已删除的动态**仍可查到**（`flag` 为 1），内容、点赞、评论都还在。\n\n评论正文 `commentList[].comment` 是 **base64 编码**，而动态正文 `content` 是明文。","operationId":"ql_api_friend_getSnsDetails","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"sid":{"type":"integer","format":"int64","description":"朋友圈动态 ID。取自「查询朋友圈列表」。⚠️ 列表返回的是**字符串**，此处需传**整数**。","examples":[7663992035019206000]}},"required":["appid","sid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","sid":1000000000000000021}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：**顶层直接是动态对象**，不再嵌套一层。字段集合与 `getSnsList` 的数组元素相同。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"authorVid":1000000000000001,"content":"这是一条朋友圈文本内容","flag":0,"linkInfo":{},"notifyTime":0,"notifyVid":0,"poiInfo":{},"seq":1788424502186,"sid":"1000000000000000021","taskSid":0,"time":1788424502,"type":0,"updateTime":1788424502186,"visibleType":0,"xid":[1000000000000022]}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/commentSns":{"post":{"tags":["朋友圈"],"summary":"评论朋友圈","description":"评论朋友圈。响应中的评论内容为 base64。\n\n⚠️ 返回的 `commentId` **恒为 `0`**，不是真实 ID。删除该评论需先调「获取朋友圈详情」，从 `commentList[].commentId` 取真实 ID。","operationId":"ql_api_friend_commentSns","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"sid":{"type":"integer","format":"int64","description":"朋友圈动态 ID。取自「查询朋友圈列表」。⚠️ 列表返回的是**字符串**，此处需传**整数**。","examples":[7658992575255311000]},"content":{"type":"string","description":"评论正文，纯文本字符串。","examples":["评论内容122333"],"title":"内容"},"refCommentId":{"type":"integer","format":"int64","description":"某评论的commentId\n\n**注意**：传 `0` = 发**顶层评论**（不回复任何人），调用成功。传真实 `commentid`（回复某条评论）**未确认**；契约标必填，但省略后是否报错**未做对照验证**。","examples":[3]}},"required":["appid","sid","content","refCommentId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","content":"[示例] 测试评论","refCommentId":0,"sid":1000000000000000021}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"baseRsp":{"type":"object","properties":{"ret":{"type":"integer","format":"int64","description":"内部返回码，0 为正常\n\n**注意**：0。本接口没有 sendSns 那种额外的顶层 `ret` 字段。"}},"description":"基础响应体，含 ret 字段"},"commentId":{"type":"integer","format":"int64","description":"评论 ID。朋友圈评论 ID。由 /api/friend/commentSns 返回\n\n**注意**：**恒为 `0`，不是可用的评论 ID。** 契约在 deleteSnsComment 处称「commentId 由 commentSns 返回」——该说法与实际不符。要删评论请改从 `getSnsList` / 动态对象的 `commentList[].commentid` 取值。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"baseRsp":{"retCode":0},"commentId":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/deleteSnsComment":{"post":{"tags":["朋友圈"],"summary":"删除朋友圈评论","description":"删除朋友圈评论。`commentId` 取自「查询朋友圈详情」。若动态本身已被删除（`flag` 为 1），删评论不会生效。","operationId":"ql_api_friend_deleteSnsComment","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"sid":{"type":"integer","format":"int64","description":"朋友圈动态 ID。取自「查询朋友圈列表」。⚠️ 列表返回的是**字符串**，此处需传**整数**。","examples":[0]},"commentId":{"type":"integer","format":"int64","description":"评论 ID。朋友圈评论 ID。由 /api/friend/commentSns 返回\n\n**注意**：取值来源应为 `getSnsList` / 动态对象里的 `commentList[].commentid`（全小写），**不是** `commentSns` 返回的 `data.commentId`（恒为 0）。契约原描述「由 /api/friend/commentSns 返回」与实际不符。","examples":[3]}},"required":["appid","sid","commentId"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","sid":0,"commentId":1000000000000001}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"baseRsp":{"type":"object","properties":{"ret":{"type":"integer","format":"int64","description":"内部返回码，0 为正常\n\n**注意**：0。返回体除此之外无任何内容，**拿不到「删了几条」之类的确认信息**，需要确定性的调用方必须回读列表。"}},"description":"基础响应体，含 ret 字段"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"baseRsp":{"ret":0}},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/friend/deleteSns":{"post":{"tags":["朋友圈"],"summary":"删除朋友圈","description":"删除朋友圈。sid 取自 getSnsList。\n\n:::danger\n⛔ **高风险操作**\n\n朋友圈删除后无法恢复，请核对真实 `sid`。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_friend_deleteSns","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"sid":{"type":"integer","format":"int64","description":"朋友圈动态 ID。取自「查询朋友圈列表」。⚠️ 列表返回的是**字符串**，此处需传**整数**。","examples":[7663992953016366000]}},"required":["appid","sid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","sid":1000000000000000021}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：为**空对象 `{}`**，无任何确认信息（不返回被删的 sid，也不返回受影响条数）。注意与 `likeSns` 的 `null` 区分。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"baseRsp":{"retCode":0}}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/uploadVideo":{"post":{"tags":["文件"],"summary":"上传视频","description":"上传视频。`base64` 必须是**结构完整的 mp4**（缺 `moov` 元数据盒会被拒绝），`thumbBase64` 是**封面图**的 base64，`width` / `height` 必填。","operationId":"ql_api_cdn_uploadVideo","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"base64":{"type":"string","description":"视频内容的 base64（不含 `data:` 前缀）。必须是**结构完整的 mp4** —— 缺 `moov` 元数据盒的文件会被拒绝。","examples":["AAAAHGZ0eXBtcDQyAAAAAWlzb21tcDQxbXA0MgAADnNtb292AAAAbG12aGQAAAAA5h/8J+Yf/CcAAKxEAAKxEAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAIlHRy"]},"fileName":{"type":"string","description":"文件名，需含扩展名。","examples":["123123.MP4"],"title":"文件名"},"thumbBase64":{"type":"string","examples":["/9j/4AAQSkZJRgABAQAASABIAAD/4QBARXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAC0KADAAQAAAABAAAFAAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/+ICpElD"],"description":"**视频封面图**的 base64（不含 `data:` 前缀）。注意是图片，不是地址。"},"width":{"type":"integer","format":"int64","title":"视频宽","description":"视频宽度（像素）。**必填**。","examples":[1920]},"height":{"type":"integer","format":"int64","title":"视频高","description":"视频高度（像素）。**必填**。","examples":[1080]}},"required":["appid","base64","fileName","thumbBase64","width","height"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","base64":"AAAAHGZ0eXBtcDQyAAAAAWlzb21tcDQxbXA0MgAADnNtb292AAAAbG12aGQAAAAA5h/8J+Yf/CcAAKxEAAKxEAABAAABAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAADAAAIlHRy","fileName":"123123.MP4","thumbBase64":"/9j/4AAQSkZJRgABAQAASABIAAD/4QBARXhpZgAATU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAAqACAAQAAAABAAAC0KADAAQAAAABAAAFAAAAAAD/7QA4UGhvdG9zaG9wIDMuMAA4QklNBAQAAAAAAAA4QklNBCUAAAAAABDUHYzZjwCyBOmACZjs+EJ+/+ICpElD","width":1920,"height":1080}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"duration":{"type":"integer","format":"int64","description":"视频或语音时长，单位以接口说明为准。\n\n**注意**：服务端解析视频得到，**入参没有该字段**。本次返回 `93`，**单位未确认**（源视频时长未留存，无法确认是秒还是其它单位）。","minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","minimum":0},"thumbUrl":{"type":"string","description":"封面或缩略图地址。\n\n**注意**：服务端生成的缩略图直链（64 字符）。`sendVideo` 需原样带上。"},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"},"fileId":{"type":"string","description":"旧版响应中的媒体文件 ID。","title":"文件资源 ID"},"aesKey":{"type":"string","description":"旧版响应中的媒体解密密钥。","title":"媒体解密密钥"},"fileKey":{"type":"string","description":"旧版响应中的上传任务键。"},"fileName":{"type":"string","description":"旧版响应中的文件名。","title":"文件名"},"fileMd5":{"type":"string","description":"旧版响应中的文件 MD5。"},"fileSize":{"type":"integer","format":"int64","minimum":0,"description":"旧版响应中的文件大小，单位为字节。","title":"文件大小"},"thumbMd5":{"type":"string","description":"缩略图 MD5。"},"thumbSize":{"type":"integer","format":"int64","minimum":0,"description":"缩略图大小，单位为字节。"},"thumbWidth":{"type":"integer","format":"int64","minimum":0,"description":"缩略图宽度，单位为像素。"},"thumbHeight":{"type":"integer","format":"int64","minimum":0,"description":"缩略图高度，单位为像素。"}},"description":"媒体上传结果。当前版本字段与历史版本字段可能并存，请优先以实际响应为准并按字段名原样传递。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"id":"","size":0,"duration":0,"width":0,"height":0,"thumbUrl":"","md5":"","fileId":"","aesKey":"","fileKey":"","fileName":"","fileMd5":"","fileSize":0,"thumbMd5":"","thumbSize":0,"thumbWidth":0,"thumbHeight":0},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/uploadImage":{"post":{"tags":["文件"],"summary":"上传图片","description":"上传图片（GIF 也走这里）。返回的 `data` 可**整体**作为「发送图片」或「发送 GIF」的 `content`，字段逐个对应。","operationId":"ql_api_cdn_uploadImage","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"fileName":{"type":"string","description":"文件名，需含扩展名。","examples":["美女.jpeg"],"title":"文件名"},"base64":{"type":"string","description":"文件内容的 base64 编码（不含 `data:` 前缀）。","examples":["/9j/4AAQSkZJRgABAQAAAQABAAD/2wCEAAkGBxMTEhUTExMWFRUXFxgXFxgWFRYVFxgWFx0aGBYXFxgYHSggGBolHRgdITEhJSkrLi4uFx8zODMtNygtLisBCgoKDg0OGhAQGyslICUuLS0tLS0uLS0tLS0tLS0tLS0tLS0tLS0tLTUtLS0tLS0tLS0tLS0tLS0tLS0t"]}},"required":["appid","fileName","base64"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","base64":"<省略>","fileName":"t.gif"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID\n\n**注意**：210 字符十六进制串（本次以 `3067` 开头）。作为 `sendImage.content.id` 和 `/api/cdn/download` 的 `fileId` 使用。**与大文件 `*1*` 开头的 495 字符 id 不同源，不可互换。**"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"width":{"type":"integer","format":"int64","description":"图片/视频宽度（像素）","minimum":0},"height":{"type":"integer","format":"int64","description":"图片/视频高度（像素）","minimum":0},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"},"midImageFileSize":{"type":"integer","format":"int64","description":"中等尺寸图字节数","minimum":0},"thumbFileSize":{"type":"integer","format":"int64","description":"缩略图字节数","minimum":0},"thumbWidth":{"type":"integer","format":"int64","description":"缩略图宽度","minimum":0},"thumbHeight":{"type":"integer","format":"int64","description":"缩略图高度","minimum":0},"thumbMd5":{"type":"string","description":"缩略图 MD5"},"fileId":{"type":"string","description":"旧版响应中的媒体文件 ID。","title":"文件资源 ID"},"aesKey":{"type":"string","description":"旧版响应中的媒体解密密钥。\n\n**注意**：32 位 hex。`sendImage` 与 `/api/cdn/download` 都要原样回传，不能改写。**凭证性质：不入库明文、不打日志、不出现在对外文档示例里。**","title":"媒体解密密钥"},"fileKey":{"type":"string","description":"旧版响应中的上传任务键。"},"fileName":{"type":"string","description":"旧版响应中的文件名。","title":"文件名"},"fileMd5":{"type":"string","description":"旧版响应中的文件 MD5。"},"fileSize":{"type":"integer","format":"int64","minimum":0,"description":"旧版响应中的文件大小，单位为字节。","title":"文件大小"},"thumbSize":{"type":"integer","format":"int64","minimum":0,"description":"缩略图大小，单位为字节。"}},"description":"媒体上传结果。当前版本字段与历史版本字段可能并存，请优先以实际响应为准并按字段名原样传递。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"aesKey":"<上传接口返回的 aesKey>","height":1,"id":"<上传接口返回的 fileId>","md5":"<上传接口返回的 md5>","midImageFileSize":597,"size":42,"thumbFileSize":597,"thumbHeight":1,"thumbMd5":"8b69799ecf4a89193e600e0b70bb7b78","thumbWidth":1,"width":1}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/uploadFile":{"post":{"tags":["文件"],"summary":"上传文件","description":"上传文件。返回的 `data` 可**整体**作为「发送文件」的 `content`；再补一个 `voiceTime` 就是「发送语音」的 `content`。","operationId":"ql_api_cdn_uploadFile","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"fileName":{"type":"string","description":"文件名，需含扩展名。","examples":["sample_voice_5s.silk"],"title":"文件名"},"base64":{"type":"string","description":"文件内容的 base64 编码（不含 `data:` 前缀）。","examples":["AiMhU0lMS19WMwwApyt096juSeXgI3BXCwCnK3T3qZynot6/vwwApyt096mUM6ea5a2bDACnK3T3hDaUBZwq3ccLAKcrdPepnKei3r+/CwCnK3T3qZynot6/vwsApyt096mcp6Lev78LAKcrdPepnKei3r+/CwCnK3T3qZynot6/vwsApyt096mcp6Lev78LAKcrdPep"]}},"required":["appid","fileName","base64"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","base64":"<省略>","fileName":"青鸾接口过检.txt"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"id":{"type":"string","description":"对象 ID。发消息返回时即 serverMsgId（撤回要用）；上传返回时即 fileId（发送/下载要用）；列表项中为该条记录 ID\n\n**注意**：212 字符十六进制串（本次以 `3068` 开头）。用作 `sendFile.content.id` 与 `/api/cdn/download` 的 `fileId`。"},"name":{"type":"string","description":"名称/昵称\n\n**注意**：入参 `fileName` 的原样回显，服务端不做重命名。","title":"名称"},"url":{"type":"string","description":"资源 URL、链接地址或待上传文件地址。\n\n**注意**：**恒为空串**（`\"\"`）。契约未描述该字段，容易被误当成下载直链。文件回取必须走 `/api/cdn/download`。","title":"资源地址"},"size":{"type":"integer","format":"int64","description":"文件字节数。由上传接口返回","minimum":0},"md5":{"type":"string","description":"文件 MD5。由上传接口返回，可用于校验","title":"MD5 校验值"},"fileId":{"type":"string","description":"旧版响应中的媒体文件 ID。","title":"文件资源 ID"},"aesKey":{"type":"string","description":"旧版响应中的媒体解密密钥。\n\n**注意**：32 位 hex，下载/发送时原样回传。**凭证性质，不落日志。**","title":"媒体解密密钥"},"fileKey":{"type":"string","description":"旧版响应中的上传任务键。"},"fileName":{"type":"string","description":"旧版响应中的文件名。","title":"文件名"},"fileMd5":{"type":"string","description":"旧版响应中的文件 MD5。"},"fileSize":{"type":"integer","format":"int64","minimum":0,"description":"旧版响应中的文件大小，单位为字节。","title":"文件大小"},"thumbMd5":{"type":"string","description":"缩略图 MD5。"},"thumbSize":{"type":"integer","format":"int64","minimum":0,"description":"缩略图大小，单位为字节。"},"thumbWidth":{"type":"integer","format":"int64","minimum":0,"description":"缩略图宽度，单位为像素。"},"thumbHeight":{"type":"integer","format":"int64","minimum":0,"description":"缩略图高度，单位为像素。"},"width":{"type":"integer","format":"int64","minimum":0,"description":"媒体宽度，单位为像素。"},"height":{"type":"integer","format":"int64","minimum":0,"description":"媒体高度，单位为像素。"}},"description":"媒体上传结果。当前版本字段与历史版本字段可能并存，请优先以实际响应为准并按字段名原样传递。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"aesKey":"<上传接口返回的 aesKey>","id":"<上传接口返回的 fileId>","md5":"<上传接口返回的 md5>","name":"青鸾接口过检.txt","size":34,"url":""}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/download":{"post":{"tags":["文件"],"summary":"下载媒体文件","description":"下载媒体文件，返回 base64。`fileType` **图片传 2**（传 1 会报资源不存在）；`fileId` / `aesKey` 取自上传接口的返回或消息回调。","operationId":"ql_api_cdn_download","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"fileId":{"type":"string","description":"媒体文件 ID。取自上传接口的返回，或消息回调里的媒体字段。","examples":["<sample-media-id>"],"title":"文件资源 ID"},"fileType":{"type":"integer","format":"int64","description":"取图规格：**`2` = 原图**（与上传字节一致）· **`3` = 缩略图**（服务端会转成 JPEG）。对图片传 `1` 会失败。","examples":[2]},"aesKey":{"type":"string","description":"媒体解密密钥。取自上传接口的返回，原样回传，不要改写。","examples":["8a8bbce1887ce81517b7fedac2bdfb17"],"title":"媒体解密密钥"}},"required":["appid","fileId","fileType","aesKey"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","aesKey":"<上传接口返回的 aesKey>","fileId":"10000000000000014f020100…<已截断>","fileType":2}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"base64":"<省略>","serverAddr":"<省略>"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/uploadBigFile":{"post":{"tags":["文件"],"summary":"上传大文件","description":"上传大文件。传入一个可公网访问的地址，由服务端拉取。\n\n⚠️ **异步接口**：本接口只返回任务状态（`status: \"uploading\"` 与任务标识），重复调用会新建任务，**不是轮询**。\n完成后通过回调事件 `BigFileUploadCompleted` 推送，其 `content.id` 是带 `*1*` 前缀的大文件 ID —— 「发送大文件」「大文件下载」「获取大文件下载地址」只接受这个 ID，普通「上传文件」返回的 ID 会被拒绝。**未配置回调地址时这几个接口无法使用。**","operationId":"ql_api_cdn_uploadBigFile","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"fileUrl":{"type":"string","description":"源文件地址。由**我方服务器主动拉取**，因此该地址必须能从公网访问到；文件名由源地址决定，不能自行指定。","examples":["https://example.com/sample-file.zip"]}},"required":["appid","fileUrl"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","fileUrl":"https://example.com/..."}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"fileMd5":"e6ef72147eef68be3be25d391380bc42","fileName":"qingluan-icon.svg","fileSize":8069,"status":"uploading"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/downloadBigFile":{"post":{"tags":["文件"],"summary":"下载大文件","description":"下载大文件。`fileId` 用 `BigFileUploadCompleted` 回调事件里的 `content.id`；**不需要 `aesKey`**，这点与普通媒体下载不同。","operationId":"ql_api_cdn_downloadBigFile","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"fileId":{"type":"string","description":"大文件 ID，取自 `BigFileUploadCompleted` 回调事件的 `content.id`（`*1*` 开头）。**大文件下载不需要 `aesKey`**，与普通媒体下载的方式不同。","examples":["*1*JeQaS7p9xyBzZDMi7cE4ERZgYE9WBxQSTWLkb3GTSI4KilH7vStlu8CZ7vWH4QgU6b0a02a/TtoXxh23J0nprjjHerhYvKajA32+HmrodhavWTB3lkR9W/UnN1r3tsoh93xR/BPdRyBdGo5LBIlB2AfN1qUVLAKoxuEBKS/86mP1C+MkUBtWITUzV1rCJ/SX7nHtW"],"title":"文件资源 ID"},"fileName":{"type":"string","description":"文件名，取自 `BigFileUploadCompleted` 回调事件的 `content.name`。","examples":["random_20mb_20260727.txt"],"title":"文件名"}},"required":["appid","fileId","fileName"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","fileId":"<media-file-id>","fileName":"示例名称"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"base64":{"type":"string","description":"文件内容的 Base64 编码，**不带 `data:` 前缀**\n\n**注意**：完整文件内容的 Base64（不带 `data:` 前缀）。58KB 文件返回 77,840 字符，与上传 `fileSize=58378` 吻合。**响应体是文件大小的 4/3**，只验证到 58KB 量级。"},"serverAddr":{"type":"string","description":"大文件所在的下载服务地址。\n\n**注意**：本次命中的 CDN 边缘节点 `ip:port`，随次变化，仅供排障，不要缓存。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"base64":"","serverAddr":""},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/cdn/getBigFileDownloadUrl":{"post":{"tags":["文件"],"summary":"获取大文件下载地址","description":"获取大文件的下载地址。`fileId` 同「下载大文件」，来自 `BigFileUploadCompleted` 回调事件。","operationId":"ql_api_cdn_getBigFileDownloadUrl","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"fileId":{"type":"string","description":"大文件 ID，取自 `BigFileUploadCompleted` 回调事件的 `content.id`（`*1*` 开头）。普通上传接口返回的十六进制 ID 在此不适用。","examples":["*1*u3W2k/2+7TigF3ieM2JYWY12fJ0m+w80zO84cIONH6ZKT8SyyK62oDObjIhtuywuEmdMMirU7/D2XDpybA3jNmL3Ws1EmotM0bI1Ydi3YtSwMZSy///4x9pbVL6h3f0kvoPtbEuaVJS6PnZ73MU76340FXYyWyj+6j7tXzPAIhv2KpA1WRW7E9U4ngmBx4imnfA24"],"title":"文件资源 ID"},"fileName":{"type":"string","description":"文件名，取自 `BigFileUploadCompleted` 回调事件的 `content.name`。","examples":["random_20mb_20260727.txt"],"title":"文件名"}},"required":["appid","fileId","fileName"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","fileId":"<media-file-id>","fileName":"示例名称"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"string","format":"uri","title":"业务数据","description":"服务端生成的大文件临时下载 URL；链接可能具有时效性，请勿长期缓存。\n\n**注意**：**`data` 直接是字符串 URL，不是对象**（本次 588 字符）。契约无响应说明，按对象解析会失败。URL 带签名参数，**属下载凭证，需打码处理**；**有效期未确认**。","examples":["https://example.com/download/sample.bin"]},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":"https://example.com/download/sample.bin","detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/personal/updateInfo":{"post":{"tags":["账号"],"summary":"修改账号资料","description":"更新个人资料。\n\n:::tip\n🔗 **调用关系**\n\n先调用 `personal/getInfo` 备份原资料 → 修改信息 → 再次查询确认结果。\n:::\n\n:::warning\n⚠️ **调用注意**\n\n**会真实修改账号昵称**，测试时务必先用 getInfo 备份原值。\n:::\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_personal_updateInfo","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"gender":{"type":"integer","format":"int64","description":"性别枚举：`0` 未知，`1` 男，`2` 女。","examples":[1],"enum":[0,1,2]},"name":{"type":"string","description":"名称/昵称\n\n**注意**：4 个字段全必填，等于每次都要整体提交一份完整资料。传原值无副作用；`gender` 同理（传原值 `1` 未产生变化）。","examples":["哈哈哈"],"title":"名称"},"alias":{"type":"string","description":"别名。传空串可清除\n\n**注意**：契约「传空串可清除」**已确认** —— 就是这样把账号上已有的别名清掉的。补充语义：本接口是**整体覆盖**，不想动 alias 时必须回填 `getInfo` 读到的当前值，不能省略也不能传空。","examples":["测试下"]},"phone":{"type":"string","description":"手机号。"},"email":{"type":"string","description":"邮箱。"},"xcxCorpAddress":{"type":"string","description":"企业地址。"}},"required":["appid","gender","name","alias"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx","alias":"示例别名","gender":1,"name":"示例昵称"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：契约写「成功时通常为空对象或省略 `data`」，**是 `null`**（不是 `{}`）。接口不回显改后的资料，要确认是否生效只能再调一次 `/api/personal/getInfo` —— 就是这么验的。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/personal/getQrcode":{"post":{"tags":["账号"],"summary":"获取本人二维码","description":"获取当前登录账号的个人二维码名片。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_personal_getQrcode","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"base64":{"type":"string","description":"文件内容的 Base64 编码，**不带 `data:` 前缀**\n\n**注意**：补充：内容是 **792×792 的 RGBA PNG**，无 `data:` 前缀，本次长度 31428 字符（约 23 KB）。返回体较大，不要放进高频轮询。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"base64":"<省略>"}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/personal/getInfo":{"post":{"tags":["账号"],"summary":"获取账号资料","description":"取当前登录账号资料。\n\n:::check\n✅ **成功判定**：HTTP 200 且响应体 `code = 0`。业务失败请查看 `message` 与 `detail`。\n:::","operationId":"ql_api_personal_getInfo","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]}},"required":["appid"],"description":"请求参数。字段名区分大小写，请按文档原样传递。"},"example":{"appid":"we_xxxxxxxxxxxxxxx"}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","properties":{"uin":{"type":"integer","format":"int64","description":"用户唯一数字 ID。外部联系人可从同步结果的 `userInfo.uin` 获取。\n\n**注意**：等于本账号 vid，与消息发送返回体 / 回调里的 `fromUserId` 是**同一个值**，可直接用来识别「自己发的消息」。前缀 `1688` 对应内部同事身份（外部联系人是 `7881`）。","title":"用户 UIN"},"name":{"type":"string","description":"名称/昵称","title":"名称"},"emailAddr":{"type":"string","description":"邮箱\n\n**注意**：为空串；该账号唯一有值的邮箱在 `bizMail`（企业邮箱）。要邮箱请优先读 `bizMail`，`emailAddr`/`phone` 都是空的。"},"birthday":{"type":"string","description":"生日\n\n**注意**：是**带时分的字符串**（采集打码后尾部残留 `0:00`），不是 `yyyy-MM-dd` 纯日期。确切格式因打码未确认，解析前请先做一次真机取样。"},"mobile":{"type":"string","description":"手机号"},"phone":{"type":"string","description":"手机号（11 位）","title":"手机号"},"job":{"type":"string","description":"职位信息。"},"number":{"type":"string","description":"工号"},"gender":{"type":"integer","format":"int64","description":"性别枚举：`0` 未知，`1` 男，`2` 女。","enum":[0,1,2]},"iconUrl":{"type":"string","description":"头像 URL\n\n**注意**：是一条长度 67 的 URL，采集按 `*url` 规则整体打码，因此**「是否带签名、是否会过期」未确认** —— 在验证前不要长期缓存这个地址。"},"corpId":{"type":"integer","format":"int64","description":"企业 ID。","title":"企业 ID"},"attr":{"type":"integer","format":"int64","description":"属性位"},"dispOrder":{"type":"integer","format":"int64","description":"显示排序"},"bizUin":{"type":"integer","format":"int64","description":"企业侧 uin\n\n**注意**：契约写「企业侧 uin」，但**恒为 `1`**，显然不是一个 uin。企业标识请用 `corpId`。真实含义未确认。"},"position":{"type":"string","description":"职位或位置说明。"},"alias":{"type":"string","description":"别名。传空串可清除"},"mainPartyId":{"type":"integer","format":"int64","description":"主部门 ID"},"gid":{"type":"integer","format":"int64","description":"分组 ID"},"isNameVerified":{"type":"boolean","description":"是否已实名\n\n**注意**：`true`，同时 `nameVerifyStatus=1`、`realName` 有值。只有一个样本，「`nameVerifyStatus=1` 是否就等于已实名」未确认。"},"internationCode":{"type":"string","description":"国际区号。"},"bindEmailStatus":{"type":"integer","format":"int64","description":"邮箱绑定状态"},"englishName":{"type":"string","description":"英文名"},"customInfo":{"type":"object","properties":{},"description":"自定义信息\n\n**注意**：为 `{}`；`tencentInfo` 同样为 `{}`。两者的内部结构都没拿到样本，不要按猜测写解析。"},"nameVerifyStatus":{"type":"integer","format":"int64","description":"实名校验状态"},"realName":{"type":"string","description":"真实姓名。"},"vCorpUseStatus":{"type":"integer","format":"int64","description":"虚拟企业使用状态"},"inviteVid":{"type":"integer","format":"int64","description":"邀请人 vid"},"holidayInfo":{"type":"object","properties":{"holidayStatus":{"type":"integer","format":"int64","description":"休假状态"},"holidayDesc":{"type":"string","description":"休假说明"},"oldHolidayIconIndex":{"type":"integer","format":"int64","description":"旧休假图标序号"},"createTime":{"type":"integer","format":"int64","description":"创建时间戳（秒）"},"holidayInfoId":{"type":"integer","format":"int64","description":"休假信息 ID"},"holidayIconIndex":{"type":"integer","format":"int64","description":"休假图标序号"},"holidayGenerateSrc":{"type":"integer","format":"int64","description":"休假来源"},"holidayStatusNew":{"type":"integer","format":"int64","description":"新版休假状态"},"vacationSyncType":{"type":"integer","format":"int64","description":"休假同步类型"}},"description":"休假信息"},"xcxStyle":{"type":"integer","format":"int64","description":"小程序样式配置"},"attr2":{"type":"integer","format":"int64","description":"属性位 2\n\n**注意**：随 `alias` 被清空而减少 512（bit9）。位含义未确认，仅记录该现象；`attr`(142606656) 与 `attr3`(0) 三次读取全程未变。"},"tencentInfo":{"type":"object","properties":{},"description":"腾讯侧扩展信息"},"isSyncInnerPosition":{"type":"boolean","description":"是否同步内部职位"},"unionId":{"type":"string","description":"微信生态下的 unionid。"},"vCode":{"type":"string","description":"校验码\n\n**注意**：**两次读取值不同**，且中间没有任何写操作 —— 会自行变化，不能当稳定标识。同时它是校验码性质的值，不要外发、不要落明文库。"},"personalWorkType":{"type":"integer","format":"int64","description":"个人工作类型"},"superiors":{"type":"array","items":{"type":"object","properties":{}},"description":"直属上级成员列表。\n\n**注意**：契约写「直属上级成员列表」。**返回 `[{}]`** —— 数组里是一个空对象，元素结构没取到样本。不要假定里面有 `vid`/`name`，取值前必须判空。"},"bizMail":{"type":"string","description":"企业邮箱"},"attr3":{"type":"integer","format":"int64","description":"属性位 3"},"collegeIdentity":{"type":"integer","format":"int64","description":"校园身份枚举值，由平台定义。"},"mobileAreaCode":{"type":"integer","format":"int64","description":"手机号国家码，如 86\n\n**注意**：契约写「手机号国家码，如 86」，**该账号返回 `0`**；同一份返回里真正带区号的是 `internationCode`（字符串 `\"86\"`）。取区号请用 `internationCode`。"}},"description":"业务返回数据；字段结构见下方定义。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{"alias":"示例别名","attr":142672192,"attr2":240779916,"attr3":0,"bindEmailStatus":1,"birthday":"2000-09-01 12:00:00","bizMail":"xiaoyi@taichuinfo.cn","bizUin":1,"collegeIdentity":0,"corpId":1000000000000002,"customInfo":{},"dispOrder":0,"emailAddr":"","englishName":"XiaoYi-FuWuZhiChi","gender":1,"gid":1000000000000004,"holidayInfo":{"createTime":0,"holidayDesc":"","holidayGenerateSrc":0,"holidayIconIndex":0,"holidayInfoId":0,"holidayStatus":0,"holidayStatusNew":0,"oldHolidayIconIndex":0,"vacationSyncType":0},"iconUrl":"<省略>","internationCode":"86","inviteVid":1000000000000005,"isNameVerified":true,"isSyncInnerPosition":true,"job":"","mainPartyId":1000000000000003,"mobile":"","mobileAreaCode":0,"name":"示例昵称","nameVerifyStatus":1,"number":"","personalWorkType":0,"phone":"","position":"","realName":"示例用户","superiors":[{}],"tencentInfo":{},"uin":1000000000000001,"unionId":"<省略>","vCode":"<省略>","vCorpUseStatus":1000,"xcxStyle":0}}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/label/sync":{"post":{"tags":["其他"],"summary":"同步标签","description":"同步标签。`syncType` **必须传**：`1` = 企业标签，`2` = 个人标签（传 `0` 返回 `-2003`）。\n\n⚠️ **已删除的标签仍会出现在结果里**，只是 `bDeleted` 为 `1` —— 消费时务必按它过滤。","operationId":"ql_api_label_sync","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"seq":{"type":"integer","examples":[0]},"syncType":{"type":"integer","examples":[2],"description":"**必传**：`1` 企业标签 · `2` 个人标签。传 `0` 返回 `-2003`。"}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","seq":0,"syncType":2}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/label/operate":{"post":{"tags":["其他"],"summary":"操作标签","description":"新增或删除标签 / 标签组。\n\n`operItems` 的元素形如 `{op, label:{...}}`，**不是** `{labelName}`。\n`op`：`1` 新增 · `2` 删除 · `3` 表示既有条目（同步接口返回的都是 `3`）。\n`labelType`：`1` 企业标签 · `2` 个人标签。`dataType`：`2` 标签组（`labelGroupId` 传 `0`）· `1` 组下的标签（`labelGroupId` 传父组 ID）。\n\n⚠️ 删除是**软删**：条目仍会出现在同步结果里，只是 `bDeleted` 变成 `1`。\n⚠️ 操作企业标签需要企业侧的标签管理权限，否则返回 `-1000888`；个人标签不受此限。","operationId":"ql_api_label_operate","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"opScene":{"type":"integer","examples":[2]},"labelType":{"type":"integer","examples":[1]},"operItems":{"type":"array","items":{"type":"object","properties":{"op":{"type":"integer","examples":[2]},"label":{"type":"object","properties":{"id":{"type":"integer","format":"int64","examples":[14073752025997020]},"name":{"type":"string","examples":["老王"]},"dataType":{"type":"integer","examples":[1]},"bDeleted":{"type":"integer","examples":[0]},"labelGroupId":{"type":"integer","format":"int64","examples":[14073751126007792]},"createTime":{"type":"integer","examples":[1787907966]},"labelType":{"type":"integer","examples":[1]},"businessType":{"type":"integer","examples":[0]},"order":{"type":"integer","examples":[0]},"serviceGroupId":{"type":"integer","examples":[0]}},"examples":[{"id":14073752025997020,"name":"老王","dataType":1,"bDeleted":0,"labelGroupId":14073751126007792,"createTime":1787907966,"labelType":1,"businessType":0,"order":0,"serviceGroupId":0}]}}},"examples":[[{"op":2,"label":{"id":14073752025997020,"name":"老王","dataType":1,"bDeleted":0,"labelGroupId":14073751126007792,"createTime":1787907966,"labelType":1,"businessType":0,"order":0,"serviceGroupId":0}}]]}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","opScene":2,"labelType":1,"operItems":[{"op":2,"label":{"id":14073752025997020,"name":"老王","dataType":1,"bDeleted":0,"labelGroupId":14073751126007792,"createTime":1787907966,"labelType":1,"businessType":0,"order":0,"serviceGroupId":0}}]}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/collection/add":{"post":{"tags":["其他"],"summary":"添加收藏","description":"把一条消息加入收藏。请求体就是**整条消息对象本身**（发送接口返回的 `data` 可直接使用），不要再包一层。成功返回 `data.ack`。","operationId":"ql_api_collection_add","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"id":{"type":"integer","description":"消息 ID。发送接口返回的 `data.id`。"},"syncKey":{"type":"integer","description":"分页游标。首次传 `0`，之后传上一页返回的 `syncKey`。"},"messageType":{"type":"integer","description":"消息类型枚举。"},"fromUserId":{"type":"integer","description":"发送方 ID。"},"toUserId":{"type":"integer","description":"接收方 ID。"},"roomId":{"type":"integer","description":"群 ID。取自「创建群聊」或「查询我的客户群」。注意查询接口返回的是字符串，回传时需转整数。"},"contentType":{"type":"integer","description":"内容类型码。"},"sendTime":{"type":"integer","description":"发送时间戳（秒）。"},"appInfo":{"type":"string","description":"消息指纹串，原样回填。"},"senderName":{"type":"string","description":"发送者显示名。"},"content":{"type":"array","description":"正文。结构随 `contentType` 变化，原样回填。"},"extraData":{"description":"随 `data` 一并回填，不需要自行构造。"},"flag":{"description":"随 `data` 一并回填，不需要自行构造。"},"devInfo":{"description":"随 `data` 一并回填，不需要自行构造。"},"summary":{"description":"随 `data` 一并回填，不需要自行构造。"}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","id":0,"syncKey":0,"messageType":0,"fromUserId":0,"toUserId":0,"roomId":0,"contentType":0,"sendTime":0,"appInfo":"","senderName":"","content":[],"extraData":"","flag":"","devInfo":"","summary":""}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/api/collection/sync":{"post":{"tags":["其他"],"summary":"同步收藏","description":"同步收藏列表。按 `seq` 增量拉取，`limit` 控制每页条数。","operationId":"ql_api_collection_sync","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"seq":{"type":"integer","examples":[15873457]},"limit":{"type":"integer","examples":[1000],"description":"单页条数。"}},"required":["appid"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","seq":15873457,"limit":1000}}}},"responses":{"200":{"description":"原样返回（`code = 0` 即成功）","content":{"application/json":{"schema":{"type":"object","description":"接口原样返回平台的业务响应。HTTP 状态码与业务状态码需分别判断：HTTP 200 只表示请求已送达，成功以 `code = 0` 为准。","properties":{"code":{"type":"integer","description":"业务状态码：`0` 表示成功，`-1` 表示失败；失败原因见 `message`。","examples":[0],"title":"业务状态码"},"data":{"type":"object","description":"接口无固定结构化返回数据；成功时通常为空对象或省略 `data`。\n\n**注意**：成功时恒为 `null`，没有任何回执内容。判断成功只能看 `code`；但本接口可以用回调里的 `1001` 载荷做二次确认。","title":"业务数据"},"detail":{"type":"string","description":"错误详情；无补充信息时通常为空字符串。","title":"错误详情"},"message":{"type":"string","description":"业务结果消息。成功通常为 `ok`；企微错误通常为 `错误码|错误信息`。","examples":["ok"],"title":"响应消息"},"time":{"type":"string","description":"服务端时间，格式为 `YYYY-MM-DD HH:mm:ss`。","examples":["2026-07-21 07:33:17"],"title":"服务端时间"}},"required":["code","message","time"]},"example":{"code":0,"data":{},"detail":"","message":"ok","time":"2026-07-21 07:33:17"}}}},"403":{"description":"受控接口，需通过控制台配置"},"404":{"description":"`appid` 不存在或无权访问"}}}},"/qingluan/instances/set-callback":{"post":{"tags":["实例与回调"],"summary":"配置回调地址","description":"登记接收事件的地址。青鸾**不会**把你的地址交给能力层：能力层只认我方接收器，事件到达后由我方转发给你，并附上青鸾签名。\n\n**验签**：用返回的 `callback_secret` 计算 `HMAC-SHA256(secret, \"{X-Qingluan-Timestamp}.\" + 原始请求体)`，与请求头 `X-Qingluan-Signature` 比对。\n\n**你会收到的包体**：`{appid, event_type, events}`；事件类型在 `event_type` 字段里，不在任何 HTTP 头上。\n\n⚠️ 本接口是青鸾自有接口，返回**青鸾信封** `{ok, code, message, request_id, data}`，与数据面透传接口的原样返回不同。","operationId":"ql_instances_set_callback","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"appid":{"type":"string","description":"青鸾实例 ID，形如 `we_xxxxxxxxxxxxxxx`。在开发者控制台「实例与回调」扫码上号后获得。","examples":["we_xxxxxxxxxxxxxxx"]},"callbackUrl":{"type":"string","description":"你的接收地址，必须是 http(s) 开头的公网地址。","examples":["https://your.app/qingluan/callback"]}},"required":["appid","callbackUrl"]},"example":{"appid":"we_xxxxxxxxxxxxxxx","callbackUrl":"https://your.app/qingluan/callback"}}}},"responses":{"200":{"description":"登记成功（青鸾信封）","content":{"application/json":{"schema":{"type":"object","properties":{"ok":{"type":"boolean","examples":[true]},"code":{"type":"integer","examples":[0]},"message":{"type":"string","examples":["success"]},"request_id":{"type":"string","description":"本次调用的追踪 ID，排查问题时提供它。","examples":["ql_7a44f0c1e2b34d56a8f9"]},"data":{"type":"object","properties":{"appid":{"type":"string"},"callback_url":{"type":"string"},"callback_secret":{"type":"string","description":"验签密钥，仅在此返回，请妥善保存。","examples":["whsec_xxxxxxxxxxxxxxxx"]}}}}},"example":{"ok":true,"code":0,"message":"success","request_id":"ql_7a44f0c1e2b34d56a8f9","data":{"appid":"we_xxxxxxxxxxxxxxx","callback_url":"https://your.app/qingluan/callback","callback_secret":"whsec_xxxxxxxxxxxxxxxx"}}}}},"400":{"description":"缺少 `appid`，或 `callbackUrl` 不是 http(s) 地址"},"404":{"description":"`appid` 不存在或无权访问"},"502":{"description":"登记失败，请稍后重试"}}}},"/healthz":{"get":{"tags":["系统"],"summary":"Healthz","description":"**存活**探针：进程还在就 200。\n\n⚠️ 审计 2026-09-06 · M30：这里原来只有一个恒定的 ok=true，\n而 lifespan 里 DB / 管理员初始化的异常是被整段吞掉的 —— 探针据此认为控制台就绪，\n它其实可能连库都没连上。现在照常 200（进程确实活着），但**如实报出**库的状态；\n要判\"能不能接流量\"请用 /readyz。","operationId":"healthz_healthz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}},"/readyz":{"get":{"tags":["系统"],"summary":"Readyz","description":"**就绪**探针：库连得上、迁移没失败才算就绪，否则 503。\n\n与 /healthz 的分工：进程活着但库没起来时，前者 200（别重启我）、\n后者 503（别给我发流量）。数据面 /qingluan/* 在降级模式下仍可用 .env key 工作，\n所以这里报的是\"控制台是否就绪\"，不是\"整个进程是否能用\"。","operationId":"readyz_readyz_get","responses":{"200":{"description":"Successful Response","content":{"application/json":{"schema":{}}}}}}}},"components":{"schemas":{"HTTPValidationError":{"properties":{"detail":{"items":{"$ref":"#/components/schemas/ValidationError"},"type":"array","title":"Detail"}},"type":"object","title":"HTTPValidationError"},"ValidationError":{"properties":{"loc":{"items":{"anyOf":[{"type":"string"},{"type":"integer"}]},"type":"array","title":"Location"},"msg":{"type":"string","title":"Message"},"type":{"type":"string","title":"Error Type"}},"type":"object","required":["loc","msg","type"],"title":"ValidationError"}},"securitySchemes":{"QLKey":{"type":"apiKey","in":"header","name":"QL-Key","description":"开发者控制台「API Key」页创建；也支持 Authorization: Bearer <key>"}}},"tags":[{"name":"登录与扫码"},{"name":"账号"},{"name":"消息"},{"name":"联系人"},{"name":"群聊"},{"name":"朋友圈"},{"name":"文件"},{"name":"长连接"},{"name":"实例与回调"},{"name":"其他"},{"name":"系统"}],"security":[{"QLKey":[]}],"servers":[{"url":"https://api.qingluanbot.com","description":"生产环境"}]}