请求与响应数据格式

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 中标记为幂等的接口如下;重复调用语义以各接口说明为准。

类型映射​

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。

相关说明​