使用者管理
從你的服務端建立、查詢、修改和刪除 IM 使用者。使用者屬於一個應用,不同應用的使用者完全隔離。
| 要做什麼 | 介面 |
|---|---|
| 使用者在你的系統註冊時,建對應的 IM 使用者 | 建立使用者;或者省掉這一步,在簽發登入憑證時自動建立 |
| 從其他系統匯入使用者 | 批次建立使用者,每次最多 100 個 |
| 在你的後臺列出、搜尋使用者 | 查詢使用者列表(可按字首搜尋) |
| 顯示一批使用者的暱稱和頭像 | 按使用者名稱批次查詢 |
| 同步暱稱、頭像、自定義資料 | 修改使用者資料,頭像見頭像 |
| 使用者登出賬號 | 刪除使用者 |
例如,建立使用者 zhangsan:
curl -X POST "$IM_API/$ORG/$APP/users" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "username": "zhangsan", "nickname": "张三" }'設定密碼、封禁和解封見密碼與封禁,登入和登入裝置見登入與登入裝置。
使用者名稱與資料
| 項 | 規則 |
|---|---|
使用者名稱 username | 1 到 64 個字元,由字母、數字、_、-、. 組成,不能是 . 或 ..。不區分大小寫:大寫字母自動轉為小寫,Tom 和 tom 是同一個使用者,響應中的使用者名稱一律為小寫。建立後不能修改 |
密碼 password | 可選,1 到 64 個字元,不限制複雜度,原樣儲存(不去除首尾空格)。沒有密碼的使用者只能用登入憑證登入 |
暱稱 nickname | 最長 64 個字元,不能包含控制字元,首尾空白自動去除,可以為空 |
頭像 avatar_url | http 或 https 地址,最長 512 個字元,不能包含空白,可以為空。可以是本服務的頭像地址,也可以是你自己的地址,見頭像。服務端不會訪問它 |
自定義屬性 attributes | 字串鍵值對,用於存放性別、簽名等你自定義的資料。鍵 1 到 32 個字元,由字母、數字、_、-、. 組成,區分大小寫;值為任意文字;最多 32 項,按 JSON 編碼後合計不超過 4 KB(4096 位元組) |
所有介面都用使用者名稱錶示使用者,路徑中的使用者名稱同樣不區分大小寫。
使用者名稱的選擇
建議直接使用業務系統中的使用者 ID 作為使用者名稱。不要使用手機號、郵箱等個人資訊:使用者名稱會展示給同一應用的其他使用者,客戶端也能據此判斷某個使用者名稱是否已註冊。
資料對所有使用者可見
暱稱、頭像和自定義屬性對同一應用的所有使用者可見(客戶端可以查詢任意使用者的資料用於展示),不要在其中存放手機號、證件號等敏感資訊。
內容安全:建立使用者和修改資料時,暱稱和頭像要經過內容安全檢查(你的服務端提交的預設只按平臺規則,見服務端提交的內容)。修改資料時只檢查變了的欄位;清空欄位和自定義屬性不檢查。
| 情況 | 結果 |
|---|---|
| 沒透過 | 不寫入,返回 403 content_rejected,details.field 為 nickname 或 avatar_url,見呼叫方看到的錯誤 |
| 暱稱命中替換規則 | 寫入替換後的內容(命中的文字變成 *),以響應為準 |
| 應用開啟了頭像稽核 | 頭像必須是能公開訪問的 http、https 地址;內網地址、解析不了的域名也會被拒絕 |
| 之後被判定違規 | 暱稱、頭像可能被清除,並像修改資料一樣通知客戶端,見發出之後的處置 |
應用中未刪除的使用者數(含已封禁的使用者)不能超過應用套餐的註冊使用者數額度,見套餐與賬單。
頭像
頭像可以放在本服務,也可以用你自己的圖片地址。
用本服務的頭像(匯入帶頭像的使用者時也按這個順序):
- 建立使用者。
- 以用途
user_avatar上傳圖片,owner填這個使用者(必須已存在)。圖片會縮放到長邊不超過 640 畫素,得到一個任何人都能直接訪問的公開地址(檔案物件的url),如https://cdn.example.com/t99604914749046784/a99604957400924160/u/99606512787259392_i13hkkg3.jpg。 - 修改使用者資料,把地址填進
avatar_url。
本服務的頭像檔案按“是否正在被用作 owner 的頭像”保留:
| 情況 | 檔案 |
|---|---|
| 上傳後 24 小時內沒設為頭像 | 刪除,地址失效 |
| 被替換(改成其他地址或清空) | 7 天后刪除,地址失效 |
填進了其他使用者(不是 owner)的資料 | 不算在使用;owner 換頭像 7 天后同樣失效 |
用你自己的地址:服務端介面寫入的 avatar_url 只檢查格式,任意主機都可以,這樣的頭像不經過本服務。但使用者在客戶端改本人頭像時,如果應用在執行策略中開啟了 media_url_only,只能用本應用的頭像地址或 media_allowed_hosts 中主機的 https 地址,否則返回 400 invalid_argument(url_not_allowed)。
建立使用者
建立一個使用者。使用者名稱已被佔用時返回 409 already_exists;請求超時後重試時,收到 already_exists 可以視為上次已經建立成功。
/{org_name}/{app_name}/users路徑引數
org_name、app_name 見接入概述。
請求體
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
username | String | 是 | 使用者名稱,規則見使用者名稱與資料 |
password | String | 否 | 密碼,1 到 64 個字元。省略或為空字串表示不設密碼 |
nickname | String | 否 | 暱稱,最長 64 個字元 |
avatar_url | String | 否 | 頭像地址,http 或 https 地址,最長 512 個字元 |
attributes | Object | 否 | 自定義屬性,鍵和值都是字串,最多 32 項 |
請求示例
curl -X POST "$IM_API/$ORG/$APP/users" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "zhangsan",
"password": "Passw0rd!",
"nickname": "张三",
"avatar_url": "https://cdn.example.com/avatar/zhangsan.png",
"attributes": { "gender": "1", "sign": "你好" }
}'響應
成功返回 201 Created,響應體為使用者物件。
{
"username": "zhangsan",
"nickname": "张三",
"avatar_url": "https://cdn.example.com/avatar/zhangsan.png",
"attributes": { "gender": "1", "sign": "你好" },
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.167Z",
"last_login_at": null,
"version": 1
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 400 | invalid_argument | 引數不符合使用者名稱與資料中的規則,message 說明了具體原因 |
| 403 | app_unavailable | 應用處於只讀狀態,不能建立使用者,見限流與應用狀態 |
| 403 | content_rejected | 暱稱或頭像未透過內容安全檢查,details.field 為 nickname 或 avatar_url,details.reason 說明原因 |
| 409 | already_exists | 使用者名稱已被佔用 |
| 409 | limit_exceeded | 應用的註冊使用者數已達上限 |
| 429 | rate_limited | 帶密碼建立時超出了應用計算密碼雜湊的額度(每個應用每秒 100 次,與設定密碼共用),按 Retry-After 稍後重試 |
批次建立使用者
一次建立 1 到 100 個使用者,按順序逐個建立,某個使用者失敗不影響其他使用者。適合從其他系統匯入使用者,響應格式見批次介面。
- 限流:按使用者數計入應用每秒的 OpenAPI 呼叫次數,100 個使用者算 100 次;額度不夠時整個請求返回
429 rate_limited。帶密碼的使用者還計入密碼雜湊的額度(每秒 100 次),超出的使用者出現在failed中(rate_limited),稍後單獨重試即可。 - 內容安全:只按詞庫檢查暱稱;需要第三方稽核的暱稱和頭像改為建立後再審,違規的從資料中清除。被拒絕的使用者出現在
failed中(content_rejected)。
/{org_name}/{app_name}/users/batch請求體
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
users | Array<Object> | 是 | 要建立的使用者,1 到 100 個,每項的欄位與建立使用者的請求體相同 |
請求示例
curl -X POST "$IM_API/$ORG/$APP/users/batch" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"users": [
{ "username": "wangwu", "nickname": "王五" },
{ "username": "zhaoliu", "password": "123456" },
{ "username": "ZhangSan" },
{ "username": "bad name" }
]
}'響應
成功返回 200 OK。即使全部使用者都建立失敗,也返回 200,請檢查 failed。
| 欄位 | 型別 | 說明 |
|---|---|---|
created | Array<Object> | 建立成功的使用者,每項為使用者物件,按請求中的順序 |
failed | Array<Object> | 建立失敗的使用者,按請求中的順序 |
failed[].username | String | 請求中的使用者名稱(轉為小寫) |
failed[].code | String | 錯誤碼,與建立使用者的錯誤碼相同,如 already_exists、invalid_argument、content_rejected、limit_exceeded、rate_limited |
failed[].message | String | 錯誤說明 |
{
"created": [
{
"username": "wangwu",
"nickname": "王五",
"avatar_url": "",
"attributes": {},
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": false,
"created_via": "openapi",
"created_at": "2026-10-02T19:06:04.505Z",
"last_login_at": null,
"version": 1
},
{
"username": "zhaoliu",
"nickname": "",
"avatar_url": "",
"attributes": {},
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:06:04.563Z",
"last_login_at": null,
"version": 1
}
],
"failed": [
{ "username": "zhangsan", "code": "already_exists", "message": "用户名已被占用" },
{ "username": "bad name", "code": "invalid_argument", "message": "用户名应为 1 到 64 位,由字母、数字、_、-、. 组成,且不能是 . 或 .." }
]
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 400 | invalid_argument | users 為空或超過 100 個 |
| 403 | app_unavailable | 應用處於只讀狀態,不能建立使用者 |
| 429 | rate_limited | 應用的 OpenAPI 呼叫額度不足以處理這麼多使用者,整個請求沒有執行 |
查詢使用者列表
分頁列出應用中的使用者,不含已刪除的使用者。預設按建立順序排列;帶 username_prefix 時按使用者名稱排序。分頁方式見分頁,換了篩選條件後請從第一頁開始查詢。
/{org_name}/{app_name}/users查詢引數
| 引數 | 型別 | 必填 | 說明 |
|---|---|---|---|
status | String | 否 | 按狀態篩選:active 正常,disabled 已封禁。省略時兩者都列出 |
username_prefix | String | 否 | 按使用者名稱字首搜尋,1 到 64 個使用者名稱字元,不區分大小寫,按字面匹配(_ 不是萬用字元) |
limit | Number | 否 | 每頁數量,1 到 100,預設 20 |
cursor | String | 否 | 分頁遊標,取上一頁響應中的 next_cursor;省略時從第一頁開始 |
請求示例
curl "$IM_API/$ORG/$APP/users?status=active&limit=2" \
-H "Authorization: Bearer $APP_TOKEN"響應
成功返回 200 OK:
| 欄位 | 型別 | 說明 |
|---|---|---|
items | Array<Object> | 本頁的使用者,每項為使用者物件 |
next_cursor | String | 下一頁的遊標,可為 null(沒有下一頁) |
{
"items": [
{
"username": "zhangsan",
"nickname": "张三",
"avatar_url": "https://cdn.example.com/avatar/zhangsan.png",
"attributes": { "gender": "1", "sign": "你好" },
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.167Z",
"last_login_at": null,
"version": 1
},
{
"username": "lisi",
"nickname": "",
"avatar_url": "",
"attributes": {},
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": false,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.203Z",
"last_login_at": null,
"version": 1
}
],
"next_cursor": "Rq65HvagQGJhPXM4qOLjuRBLiQjV-J2USEzW9r0fve4kz850Z89l..."
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 400 | invalid_argument | status 不是 active 或 disabled;username_prefix 包含使用者名稱以外的字元或超過 64 個字元;limit 超出範圍;遊標無效或不屬於這種查詢 |
按使用者名稱批次查詢
一次查詢 1 到 100 個使用者。結果按請求中的順序排列;不存在或已刪除的使用者不出現在結果中,重複的和格式不對的使用者名稱會被忽略。
/{org_name}/{app_name}/users/lookup請求體
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
usernames | Array<String> | 是 | 要查詢的使用者名稱,1 到 100 個,不區分大小寫 |
請求示例
curl -X POST "$IM_API/$ORG/$APP/users/lookup" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"usernames": ["LISI", "nobody", "zhangsan", "lisi"]
}'響應
成功返回 200 OK。items 為找到的使用者,每項為使用者物件。示例中 nobody 不存在,重複的 lisi 只返回一次。
{
"items": [
{
"username": "lisi",
"nickname": "",
"avatar_url": "",
"attributes": {},
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": false,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.203Z",
"last_login_at": null,
"version": 1
},
{
"username": "zhangsan",
"nickname": "张三",
"avatar_url": "https://cdn.example.com/avatar/zhangsan.png",
"attributes": { "gender": "1", "sign": "你好" },
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.167Z",
"last_login_at": null,
"version": 1
}
]
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 400 | invalid_argument | usernames 為空或超過 100 個 |
查詢使用者
查詢一個使用者的詳細資訊,包括封禁狀態。
/{org_name}/{app_name}/users/{username}路徑引數
org_name、app_name 見接入概述。
| 引數 | 型別 | 說明 |
|---|---|---|
username | String | 使用者名稱,不區分大小寫 |
請求示例
curl "$IM_API/$ORG/$APP/users/zhangsan" \
-H "Authorization: Bearer $APP_TOKEN"響應
成功返回 200 OK,響應體為使用者物件。
{
"username": "zhangsan",
"nickname": "张三",
"avatar_url": "https://cdn.example.com/avatar/zhangsan.png",
"attributes": { "gender": "1", "sign": "你好" },
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.167Z",
"last_login_at": null,
"version": 1
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 404 | not_found | 使用者不存在或已刪除。格式不對的使用者名稱同樣返回 not_found |
修改使用者資料
修改使用者的暱稱、頭像和自定義屬性,只傳需要修改的欄位,至少傳一個。修改後,該使用者線上的裝置會收到資料變更的通知。
暱稱或頭像傳空字串表示清空。自定義屬性按項合併,不會整體替換:
attributes 中傳 | 結果 |
|---|---|
"key": "值" | 新增或覆蓋這一項 |
"key": null | 刪除這一項 |
| 沒出現的鍵 | 不變 |
整個 attributes 為 null | 清空全部 |
合併後同樣不能超過 32 項、4 KB。兩個請求同時改不同的項不會互相覆蓋。
- 併發修改:
version可選。傳了就必須與使用者當前的version一致,否則返回409 version_conflict,見併發修改。 - 內容沒變:提交的內容與當前資料相同時,不遞增
version,也不發通知。
/{org_name}/{app_name}/users/{username}路徑引數
org_name、app_name 見接入概述。
| 引數 | 型別 | 說明 |
|---|---|---|
username | String | 使用者名稱 |
請求體
| 欄位 | 型別 | 必填 | 說明 |
|---|---|---|---|
nickname | String | 否 | 新的暱稱,空字串表示清空 |
avatar_url | String | 否 | 新的頭像地址,空字串表示清空,規則見頭像。替換或清空本服務的頭像後,原來的頭像檔案在 7 天后刪除 |
attributes | Object | 否 | 要修改的自定義屬性,按上文的規則合併。值為 null 表示刪除該項,整體為 null 表示清空 |
version | Number | 否 | 讀取到的使用者 version,傳入時用於檢查併發修改 |
請求示例
把暱稱改為“張三丰”,刪除屬性 sign,新增屬性 level,保留其他屬性:
curl -X PATCH "$IM_API/$ORG/$APP/users/zhangsan" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"nickname": "张三丰",
"attributes": { "sign": null, "level": "vip" }
}'把頭像改為以用途 user_avatar 上傳後得到的公開地址:
curl -X PATCH "$IM_API/$ORG/$APP/users/zhangsan" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"avatar_url": "https://cdn.example.com/t99604914749046784/a99604957400924160/u/99606512787259392_i13hkkg3.jpg"
}'響應
成功返回 200 OK,響應體為修改後的使用者物件。
{
"username": "zhangsan",
"nickname": "张三丰",
"avatar_url": "https://cdn.example.com/avatar/zhangsan.png",
"attributes": { "gender": "1", "level": "vip" },
"status": "active",
"status_reason": null,
"disabled_by": null,
"disabled_until": null,
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.167Z",
"last_login_at": null,
"version": 2
}錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 400 | invalid_argument | 沒有傳任何需要修改的欄位;欄位不符合使用者名稱與資料中的規則;合併後的自定義屬性超過 32 項或 4 KB |
| 403 | app_unavailable | 應用處於只讀狀態,不能修改資料 |
| 403 | content_rejected | 修改的暱稱或頭像未透過內容安全檢查,details.field 為 nickname 或 avatar_url,details.reason 說明原因 |
| 404 | not_found | 使用者不存在或已刪除 |
| 409 | version_conflict | version 與使用者當前的不一致,請重新查詢後再修改 |
刪除使用者
刪除一個使用者。刪除不可撤銷,影響如下:
| 方面 | 刪除後 |
|---|---|
| 登入 | 所有裝置立即下線,線上裝置收到賬號已刪除的通知;簽發了還沒用的登入憑證作廢 |
| 資料 | 清空密碼、暱稱、頭像、自定義屬性和全域性禁言;查詢返回 404 not_found,不再計入應用的使用者數 |
| 使用者名稱 | 釋放,可以重新建立同名使用者。新使用者是另一個人,不繼承舊使用者的好友、群和會話 |
| 好友 | 好友關係、好友申請和黑名單被清除,他的好友收到好友已刪除的通知 |
| 群組 | 被移出全部群;以他為物件的入群申請、邀請和群黑名單記錄被刪除。他是群主的,轉給最早加入的管理員,沒有管理員時轉給最早加入的成員;群裡沒有其他人時解散 |
| 訊息與會話 | 發過的訊息預設保留,傳送者顯示為已刪除的使用者;應用開啟了 erase_messages_on_user_delete(執行策略)時擦除。對方那裡的單聊會話保留,能看歷史,但不能再給他發訊息 |
| 推送 | 推送設定、會話免打擾和推送裝置一併刪除,見推送裝置與設定 |
| 內容安全 | 違規記錄一併刪除 |
檔案(他是 owner 的) | 使用者頭像被刪除,公開地址約 10 分鐘後失效(已快取的最長 1 天);開啟了 erase_messages_on_user_delete 時附件和群檔案也刪除,否則附件按保留期刪除、群檔案留在群裡。群頭像不刪除。使用者在客戶端上傳的檔案,owner 就是他本人 |
- 清理時間:好友、群組和檔案在後臺非同步清理,通常 1 分鐘左右;訊息和會話約 10 分鐘後清理。
- 平臺封禁的使用者不能刪除,見密碼與封禁。
- 重試:收到
404 not_found可以視為上次已經刪除成功。
使用者登出賬號
客戶端沒有刪除本人賬號的介面。App 需要提供登出賬號功能時,由 App 呼叫你的業務系統,業務系統驗證使用者身份後呼叫本介面刪除 IM 使用者。
/{org_name}/{app_name}/users/{username}路徑引數
org_name、app_name 見接入概述。
| 引數 | 型別 | 說明 |
|---|---|---|
username | String | 使用者名稱 |
請求示例
curl -X DELETE "$IM_API/$ORG/$APP/users/wangwu" \
-H "Authorization: Bearer $APP_TOKEN"響應
成功返回 204 No Content,沒有響應體。
錯誤
| HTTP 狀態碼 | code | 說明 |
|---|---|---|
| 403 | permission_denied | 該使用者被平臺封禁,不能刪除 |
| 404 | not_found | 使用者不存在或已刪除 |
資料結構
使用者物件
| 欄位 | 型別 | 說明 |
|---|---|---|
username | String | 使用者名稱,小寫 |
nickname | String | 暱稱,沒有時為空字串 |
avatar_url | String | 頭像地址,沒有時為空字串 |
attributes | Object | 自定義屬性,鍵和值都是字串,沒有時為 {} |
status | String | 使用者狀態:active 正常,disabled 已封禁 |
status_reason | String | 封禁原因,可為 null(沒有封禁,或封禁時沒有填寫原因) |
disabled_by | String | 封禁方:tenant 由你的業務服務端或控制檯封禁,platform 由平臺封禁。沒有封禁時為 null |
disabled_until | String | 封禁的到期時間,到期後自動解封。沒有封禁或永久封禁時為 null |
has_password | Boolean | 是否設定了密碼 |
created_via | String | 建立方式:openapi 由 OpenAPI 建立(包括簽發登入憑證時自動建立),console 在控制檯建立,client 客戶端自注冊 |
created_at | String | 建立時間 |
last_login_at | String | 最近一次登入的時間,可為 null(從未登入) |
version | Number | 版本號。資料、密碼或封禁狀態變化時遞增,修改資料時可用於檢查併發修改 |
時間格式見資料格式。
{
"username": "lisi",
"nickname": "李四",
"avatar_url": "",
"attributes": { "gender": "2" },
"status": "disabled",
"status_reason": "发布违规内容",
"disabled_by": "tenant",
"disabled_until": "2026-10-03T19:08:44.477Z",
"has_password": true,
"created_via": "openapi",
"created_at": "2026-10-02T19:05:46.203Z",
"last_login_at": "2026-10-02T19:08:44.402Z",
"version": 5
}