Skip to content

API 格式规范 ​

Last Updated: 2026-08-20
Status: 长期接口规范文档
Scope: HTTP/REST 与 WebSocket 的通用消息格式约定
Source of truth: src/lib/elib_response.erl, docs/api/envelope.schema.json, docs/reference/websocket-api-2.md Related docs: docs/reference/rest-api.md, docs/api/envelope.schema.json, docs/reference/websocket-api-2.md

HTTP API 响应格式 ​

标准响应结构 ​

json
{
  "code": 0,
  "msg": "success.",
  "payload": {}
}

字段说明 ​

字段类型必需说明
codeinteger✅响应状态码
msgbinary✅响应消息
payloadmap⚪响应数据,可选

状态码分类 ​

code类型说明
0成功操作成功
4xx客户端错误参数、认证、资源等错误
5xx服务端错误服务器内部问题
9xx业务错误IM 业务特定错误

成功响应 ​

json
{
  "code": 0,
  "msg": "success.",
  "payload": {
    "id": "XyZ9aBcDeF",
    "name": "张三",
    "avatar": "https://example.com/avatar.jpg"
  }
}

错误响应 ​

json
{
  "code": 404,
  "msg": "用户不存在",
  "payload": {}
}

WebSocket 消息格式 ​

详细规范: 请参阅 websocket-api.md - 完整的 WebSocket API 规范文档

基础消息结构 ​

json
{
  "id": "msg_id",
  "type": "C2C",
  "from": "encoded_user_id",
  "to": "encoded_user_id",
  "payload": {
    "msg_type": "text",
    "text": "message content"
  },
  "created_at": 1650118822382,
  "server_ts": 1650118823376
}

字段说明 ​

字段类型必需说明
idbinary✅消息唯一标识符,格式:<type>.<tsid>.<timestamp>.<random>
typebinary✅消息类型:C2C|C2G|C2S|S2C
frombinary✅发送方 ID (TSID integer)
tobinary✅接收方 ID (TSID integer)
payloadmap✅消息载荷
created_atinteger⚪客户端创建时间(毫秒时间戳,UTC+0),可选
server_tsinteger✅服务端时间戳 (毫秒,UTC+0)

消息类型 ​

类型说明
C2C单聊消息
C2G群聊消息
C2S客户端请求(如 AI 机器人)
S2C服务端通知(如系统消息)

响应处理建议 ​

客户端处理流程 ​

javascript
// 伪代码
handleResponse(response) {
    if (response.code === 0) {
        // 成功
        onSuccess(response.payload);
    } else if (response.code >= 400 && response.code < 500) {
        // 客户端错误
        handleClientError(response.code, response.msg);
    } else if (response.code >= 500 && response.code < 600) {
        // 服务端错误
        handleServerError(response.code, response.msg);
    } else if (response.code >= 900 && response.code < 1000) {
        // 业务错误
        handleBusinessError(response.code, response.msg);
    } else {
        // 未知错误
        handleUnknownError(response);
    }
}

错误提示策略 ​

code弹窗类型说明
0无弹窗成功,正常处理
4xxToast/提示客户端错误,轻提示
5xxAlert服务端错误,需要用户知晓
9xxToast业务错误,轻提示

数据编码规范 ​

ID 字段编码 ​

所有 ID 字段使用 TSID(64-bit BIGINT integer)直接返回:

json
{
  "code": 0,
  "msg": "success.",
  "payload": {
    "id": 1838294017982464,
    "uid": 1838294017982465,
    "from": 1838294017982464,
    "to": 1838294017982466
  }
}

详细规范: elib_tsid 文档

时间戳格式 ​

时间字段的格式取决于出现位置,共两种:

出现位置格式说明
REST 响应(HTTP)毫秒时间戳 (integer, UTC+0)elib_response:success 统一经 elib_cnv:convert_at_timestamps,所有以 _at / _ts 结尾的字段(DB 中为 RFC3339 串或 tuple)一律转为毫秒整数
WebSocket 消息信封毫秒时间戳 (integer, UTC+0)server_ts / created_at 等信封级字段
WebSocket 业务 payload 内部RFC3339 字符串(微秒精度)部分业务通知字段(如 channel_message_edited 的 edited_at、channel_message_revoked 的 revoked_at)为服务端 elib_dt:now() 生成的 RFC3339 微秒串(如 "2026-08-20T19:30:00.123456+08:00"),不经过 convert_at_timestamps 转换
json
{
  "server_ts": 1736141700000,
  "created_at": 1736141700000
}

客户端注意:消费 WS 业务 payload 内的时间字段时,需按 RFC3339(含微秒)解析, 不能假设所有时间字段都是整数毫秒。

字符串编码 ​

所有包含中文的字符串必须使用 UTF-8 编码:

erlang
% Erlang 示例
Msg = <<"操作成功"/utf8>>,

详细规范: utf8-encoding.md

用户 ID 键名规范(BE-17) ​

Last Updated: 2026-06-13 | Status: 定标(阶段 0,新端点强制;存量迁移按 T22 三阶段推进)

规则 ​

场景规范键名说明
所有新端点(请求 + 响应)user_id强制,不得使用 uid
存量端点(已发布)uid → 双写过渡按 T22 阶段 1 加双写后再迁移

背景 ​

历史原因导致 uid(11 处端点)与 user_id(20 处端点)并存,客户端须逐端点记忆。channel_handler_admin.erl 已做双键兼容解析,是存量状态的体现,不是目标模式。

迁移计划(T22,不在此文档展开) ​

阶段操作关键点
Stage 0(当前)本文档定标新端点即日起只用 user_id
Stage 111 个 uid 端点双写(响应同时输出 uid+user_id,请求两键皆收)OpenAPI 标 uid: deprecated
Stage 2三端(imboyapp/imboy-sdk-js/admin)切换读写 user_id借 OpenAPI 对账 CI 验证
Stage 3旧版客户端发版覆盖后删 uid 键确认线上旧版占比后执行

违规示例 vs 正确示例 ​

erlang
%% ❌ 新端点禁止
elib_response:success(Req, #{<<"uid">> => Uid, ...})

%% ✅ 新端点必须
elib_response:success(Req, #{<<"user_id">> => Uid, ...})

错误码使用 ​

错误码定义 ​

所有错误码定义在 include/error_code.hrl 中:

erlang
-define(ERR_OK, 0).
-define(ERR_BAD_REQUEST, 400).
-define(ERR_UNAUTHORIZED, 401).
-define(ERR_NOT_FOUND, 404).
-define(ERR_USER_NOT_FOUND, 940).

错误响应示例 ​

erlang
% 使用宏定义
elib_response:error(Req, <<"用户不存在"/utf8>>, ?ERR_USER_NOT_FOUND).

% 使用辅助函数
elib_response:error(Req, error_msg(?ERR_USER_NOT_FOUND), ?ERR_USER_NOT_FOUND).

详细规范: error-codes.md

分页格式 ​

请求参数 ​

GET /api/messages?page=1&size=20
  • page:页码,从 1 开始;缺省或 < 1 时按 1 处理
  • size:每页数量,默认 20,上限 1000(超出按上限截断)

响应格式 ​

json
{
  "code": 0,
  "msg": "success.",
  "payload": {
    "total": 100,
    "page": 1,
    "size": 20,
    "list": [...]
  }
}

字段说明 ​

字段类型说明
totalinteger总记录数
pageinteger当前页码
sizeinteger每页数量
listarray数据列表

注:响应无信封级 has_more 字段,客户端按 page * size < total 自行判断是否还有下一页。 分页参数名是 page / size(非 limit),与 elib_param:page/1 及 elib_pg:page_with_total 的返回形状对应。

批量操作格式 ​

批量请求 ​

json
{
  "ids": ["XyZ9aBcDeF", "GhI8jKlMnO", "AbCdEfGhIj"]
}

批量响应 ​

json
{
  "code": 0,
  "msg": "success.",
  "payload": {
    "success": ["XyZ9aBcDeF", "GhI8jKlMnO"],
    "failed": [
      {
        "id": "AbCdEfGhIj",
        "error": "用户不存在"
      }
    ]
  }
}

相关文档 ​

IMBoy — 企业私有化即时通讯平台