请求与响应数据格式
Open API 的请求与响应都是 UTF-8 编码的 JSON。请求体直接按 JSON 解析;响应统一为 { code, msg?, data?, requestId? } 信封,code = 0 表示成功。
请求体格式
| 请求体格式 | 是否支持 | 说明 |
|---|---|---|
application/json | 支持(推荐) | 请求体为标准 JSON 对象;建议显式设置 Content-Type |
application/x-www-form-urlencoded | 不支持 | 当前服务端直接按 JSON 解析原始请求体,表单编码内容会被判为非法 JSON(错误码 1001) |
| 空请求体 | 支持 | 按 {} 处理;缺少必填参数时仍返回 1001 |
当前实现的 Open API 入口直接读取原始请求体并调用 JSON 解析器,不做 Content-Type 协商:JSON 文本在未设置 Content-Type 时也能解析,但表单编码不会。为保证兼容性,请始终发送 Content-Type: application/json 与合法 JSON。
与部分友商文档的差异
部分 IM PaaS 文档同时声明 application/x-www-form-urlencoded;本实现未提供表单解析,请勿按表单方式调用,否则会返回 1001(参数错误)。
请求示例
APP_KEY="demo"
APP_SECRET="YOUR_APP_SECRET"
BASE_URL="https://im.example.com"
NONCE="$(openssl rand -hex 16)"
TIMESTAMP="$(date +%s%3N)"
SIGNATURE="$(printf '%s' "$APP_SECRET$NONCE$TIMESTAMP" | openssl sha1 | awk '{print $2}')"
curl -sS -X POST "$BASE_URL/im/v2/user/register" \
-H "Content-Type: application/json" \
-H "App-Key: $APP_KEY" \
-H "Nonce: $NONCE" \
-H "Timestamp: $TIMESTAMP" \
-H "Signature: $SIGNATURE" \
-d '{"userId":"user1","name":"Alice","avatarUrl":"https://cdn.example.com/avatar/user1.png"}'import { createHash, randomBytes } from 'node:crypto';
const APP_KEY = 'demo';
const APP_SECRET = 'YOUR_APP_SECRET';
const BASE_URL = 'https://im.example.com';
const PATH = '/im/v2/user/register';
const nonce = randomBytes(16).toString('hex');
const timestamp = String(Date.now());
const signature = createHash('sha1')
.update(APP_SECRET + nonce + timestamp)
.digest('hex');
const res = await fetch(BASE_URL + PATH, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'App-Key': APP_KEY,
Nonce: nonce,
Timestamp: timestamp,
Signature: signature,
},
body: JSON.stringify({"userId":"user1","name":"Alice","avatarUrl":"https://cdn.example.com/avatar/user1.png"}),
});
const result = await res.json();
if (result.code !== 0) throw new Error(result.code + ': ' + result.msg);
console.log(result.data);JSON 请求体
{
"userId": "user1",
"name": "Alice",
"avatarUrl": "https://cdn.example.com/avatar/user1.png"
}响应格式
| 场景 | HTTP 状态 | 响应体 |
|---|---|---|
| 成功 | 200 | { "code": 0, "data": {...}, "requestId": "req_7f3a9c" } |
| 参数/签名/权限错误 | 4xx(与错误码 httpStatus 一致) | { "code": 1018, "msg": "invalid signature", "requestId": "req_7f3a9c" } |
| 服务端错误 | 5xx | { "code": 2001, "msg": "internal error", "requestId": "req_7f3a9c" } |
成功响应只保证 code = 0 且 data 存在;错误响应返回 code、msg、requestId,不返回 data。HTTP 状态码与 errors.json 的 httpStatus 一致,可同时按 HTTP 状态与业务错误码处理。
成功响应示例
{
"code": 0,
"data": {
"userId": "user1",
"name": "Alice",
"avatarUrl": "https://cdn.example.com/avatar/user1.png",
"createdAt": 1750000000000,
"banned": false
},
"requestId": "req_7f3a9c"
}错误响应示例
{
"code": 1018,
"msg": "invalid signature",
"requestId": "req_7f3a9c"
}分页
列表类接口使用 limit 与游标/偏移参数分页;IDL 统一约束单页上限为 100(openapi.common.pagination.limitMax),具体参数以各接口的请求体字段说明为准。
| 参数 | 说明 |
|---|---|
limit | 单页条数;上限 100,默认值随接口不同(如历史消息默认 20) |
offset | 偏移量分页,用于投递日志、封禁列表等管理类列表接口 |
beforeSeq(uint64,可选) | 游标分页:按会话内 seq 向前翻页(如历史消息) |
hasMore | 响应中的 hasMore 表示是否还有下一页;total 为总数(接口返回时) |
幂等
写操作可带 clientMsgId(消息)/requestId(幂等键,24h);非幂等接口重复调用语义在各 operation.desc 标注
IDL 中标记为幂等的接口如下;重复调用语义以各接口说明为准。
user.register注册用户friend.add直接建立双向好友关系(应用服务器代操作,不经过申请流程)friend.remove删除双向好友关系blacklist.add加入黑名单(幂等)blacklist.remove移出黑名单(幂等)group.admin.add设置群管理员(幂等)group.admin.remove取消群管理员chatroom.create创建聊天室(幂等:同 chatroomId 已存在则返回现有)conversation.unread.clear清空会话未读callback.config.set设置回调配置:URL、事件订阅、签名密钥、重试策略、启停service.activation.set设置应用服务开通项(关闭后相关接口返回 1021)group.join加入群:公开群/超级群(joinPolicy=open)直接加入chatroom.kv.set设置聊天室 KV(房间级键值,随房间销毁user.chat.mute设置/解除单聊禁言(mutedUntil=0 解除user.tag.set设置用户标签(全量覆盖,最多 20 个,每个 ≤32 字符)conversation.tag.set将会话归入标签(同一会话可属多个标签,最多 20 个)chatroom.mute-all设置/取消聊天室全体禁言(房主/管理员可操作group.mute-all设置/取消群组全员禁言(群主/管理员可操作user.subscription.set设置用户订阅关系(全量覆盖,最多 100 个)friend.permission.set设置添加好友验证等级(open=无需验证 / verify=需验证 / closed=禁止)friend.profile.set设置好友自定义属性(备注名/扩展字段,仅本人可见)group.member.update设置群成员资料(群昵称/扩展字段)message.reaction.add添加消息回应(reactionchatroom.message.priority.set设置聊天室低优先级消息类型(全量覆盖)user.push.period.set设置用户推送免打扰时段(startMinute/endMinute 为当天分钟数 0-1439)push.remark.set设置推送备注名(scope=user|groupgroup.member.follow.add设置用户对群成员的特别关注(仅本人视角,推送置顶提示)group.remark.set设置用户对群名称的备注名(仅本人视角)bot.update更新机器人资料agent.update更新 Agent 配置agent.restriction.set设置用户对 Agent 的使用限制(level=blocked|limited)chatroom.rtc.bind绑定聊天室与音视频房间(RTC 房间号仅存储,音视频能力需外部服务)user.proxychat.start开启用户代聊(绑定 Agent,收到私聊时由 Agent 自动回复chatroom.keepalive.remove移除聊天室保活状态并恢复空闲销毁计时chatroom.globalMute.set全局禁言用户:应用下所有聊天室生效,仅约束客户端发送chatroom.globalMute.remove解除用户全局禁言(单次 <=20 用户chatroom.messageWhitelist.add添加消息类型到聊天室消息白名单(应用级共享,<=20 种,标识 <=32 字符chatroom.messageWhitelist.remove从聊天室消息白名单移除消息类型(幂等)sensitiveword.add增量添加敏感词(不覆盖既有词,重复添加幂等sensitiveword.batch.add批量增量添加敏感词(1..=50 条,合并既有列表,总数 <=500)sensitiveword.delete移除单个敏感词(幂等sensitiveword.batch.delete批量移除敏感词(1..=50 条,幂等)message.history.delete按时间区间删除历史消息审计记录(from/to 至少传一个,epoch 毫秒闭区间chatroom.entry.batch.set批量设置聊天室自定义属性(按 entryOwnerId 隔离,单次 <=100 对chatroom.entry.batch.remove批量移除聊天室自定义属性(<=100 个 key,按 entryOwnerId 隔离,幂等)group.sync全量同步用户所在群组:groups 内缺失群自动创建(用户为群主),已存在群幂等加入并可按 name 更新群名ultragroup.notdisturb.set设置超级群(或频道)默认免打扰,对全体成员生效ultragroup.globalbanned.set设置/取消超级群全体禁言(status=true/false,duration 秒可选,缺省为永久)ultragroup.banned.whitelist.add把用户加入超级群全体禁言白名单(userIds 支持数组或逗号分隔字符串,单次 <=20,幂等,白名单总人数 <=1000)ultragroup.banned.whitelist.del把用户移出超级群全体禁言白名单(单次 <=20,幂等ultragroup.userbanned.add禁言指定超级群成员(userIds 单次 <=20,duration 秒可选,缺省永久ultragroup.userbanned.del解除指定超级群成员禁言(单次 <=20,幂等conversation.type.notification.set设置用户按会话类型的默认通知级别(0 全部 / 1 仅 @ / 2 免打扰),按 {app}:{user}:{conversationType} 持久化bot.integration.update更新机器人 Webhook 集成(name / webhookUrl / secret / events / enabled 均可选,只覆盖传入字段)
类型映射
| IDL 类型 | JSON 表示 | 示例 |
|---|---|---|
string | 字符串 | "user1" |
int / int32 / int64 / uint32 / uint64 | 数字(整数) | 1024 |
double / float | 数字(浮点) | 31.2304 |
bool | 布尔 | false |
枚举(如 ConversationType) | 数字或字符串(按枚举定义) | 1 |
T[] | 数组 | ["user2"] |
map<K,V> | 对象 | { "key": 1 } |
Content | 按 type 取字段的消息内容联合体 | { "type": "text", "text": "你好" } |
| 命名 schema(如 Message、Group) | 对象;字段见接口页“返回结果” | — |
时间与编码
- 时间戳统一使用 epoch 毫秒(
int64),例如1750000000000。 - 所有字符串均为 UTF-8;中文、emoji 按 UTF-8 字节参与长度校验(如消息体上限按字节计)。
- 请求与响应都建议设置
Content-Type: application/json; charset=utf-8。
相关说明
- 鉴权与签名:请求头、签名算法与鉴权失败错误码
- 请求与响应数据格式:JSON 请求体、响应信封与分页
- 状态码与错误码:全部错误码、HTTP 状态与重试建议
- 限频、配额与容量限制:协议限制与分页上限
- API 接口列表:每个接口的请求体与返回结构