Passwords and bans
Set users' passwords, or ban and unban users, from your server. When dealing with a user who breaks the rules, pick by the effect you want:
| You want to | Use | Can sign in | Receives messages | Can send | Data |
|---|---|---|---|---|---|
| Only stop them posting | Global mute | Yes | Yes | No | Kept |
| Block them temporarily or permanently | Ban the user | No, all devices signed out | Catches up after unban | No | Kept |
| Remove them completely | Delete the user | No | No | No | Cleared |
| Make them sign in again once | Sign out all devices | Yes, by signing in again | Yes | Yes | Kept |
For example, ban lisi for 1 day:
curl -X POST "$IM_API/$ORG/$APP/users/lisi/disable" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "reason": "发布违规内容", "duration_seconds": 86400 }'Passwords are optional. This service doesn't store users' phone numbers or email addresses and has no password recovery; when a user forgets their password, your system verifies them and calls Set a password to reset it.
Set a password
Set or reset a user's password; users without one can then sign in with a password too.
All devices are signed out
- Online devices are disconnected, told the password changed, and must sign in with the new password.
- Their push tokens are unregistered with the sign-in; the app registers again after signing in, see Offline push.
- Issued but unused sign-in tickets become invalid.
A retry after a timeout also signs out devices that signed in between the two calls.
Users can change their own password from a client, but must provide the current one; users who never had a password can only get one from the server.
/{org_name}/{app_name}/users/{username}/passwordPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
password | String | Yes | The new password, 1 to 64 characters, no complexity rules, stored as is (leading and trailing spaces kept) |
Request example
curl -X PUT "$IM_API/$ORG/$APP/users/zhangsan/password" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"password": "N3wPassw0rd"
}'Response
On success you get 204 No Content with no body.
Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | The password is empty or longer than 64 characters |
| 404 | not_found | The user doesn't exist or was deleted |
| 429 | rate_limited | Exceeded the app's password-hashing quota (100 per second per app, shared with creating users with passwords); retry after Retry-After |
Ban a user
After a ban:
| Area | Result |
|---|---|
| Devices | All signed out immediately; online devices are told the account is banned |
| Sign-in | Blocked: with a correct password or valid ticket, sign-in returns 403 user_disabled, so clients can show "Account banned". You can't issue sign-in tickets for them, and issued ones become invalid |
| Push | Push tokens are unregistered with the sign-in, so no pushes during the ban; push settings and conversation Do Not Disturb are kept |
| Data | Kept: friendships and group memberships are unchanged, others can still see their profile, and messages to them are stored and delivered after they're unbanned and sign in again |
| Your server | Can still update their profile, set their password and mute them, without changing the ban |
| User count | Banned users still count toward the app's users |
- Timed bans: with
duration_seconds, the user is unbanned automatically within about a minute of it ending. Without it the ban is permanent until you unban. - Banning again replaces everything: leaving out
reasonclears the reason, leaving outduration_secondsmakes it permanent, and timed bans restart from this call. Send the same parameters as the first call when retrying after a timeout. Users banned by the platform aren't affected, see Platform bans. - Read-only apps can still ban users, so violations can be handled.
Bans from moderation: moderation automatic penalties, and bans your reviewers choose when confirming a violation, ban the user as your app, exactly like this API: disabled_by is tenant, automatic penalties have a status_reason like "Moderation: automatic penalty (3 violations within 24 hours)", and you can unban as usual. Bans by platform reviewers are platform bans.
/{org_name}/{app_name}/users/{username}/disablePath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username |
Request body
The body is optional; without it the ban is permanent with no reason.
| Field | Type | Required | Description |
|---|---|---|---|
reason | String | No | Why they're banned, up to 256 characters without control characters. Saved in the user object's status_reason for your reference and never shown to the banned user |
duration_seconds | Number | No | Ban length in seconds, 1 to 315360000 (10 years). Omit for a permanent ban |
Request example
Ban for 1 day:
curl -X POST "$IM_API/$ORG/$APP/users/lisi/disable" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "发布违规内容",
"duration_seconds": 86400
}'Response
On success you get 200 OK with the banned user object: status is disabled, disabled_by is tenant and disabled_until is when it ends.
{
"username": "lisi",
"nickname": "",
"avatar_url": "",
"attributes": {},
"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
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | duration_seconds isn't between 1 and 315360000; reason is longer than 256 characters or has control characters |
| 404 | not_found | The user doesn't exist or was deleted |
Unban a user
Lift a ban so the user can sign in again. All their sessions ended with the ban, so they need to sign in again.
Calling it for a user who isn't banned just returns their current info, so retries are safe. Users banned by the platform can't be unbanned by you (403 permission_denied).
/{org_name}/{app_name}/users/{username}/enablePath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username |
Request example
curl -X POST "$IM_API/$ORG/$APP/users/lisi/enable" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with the unbanned user object.
{
"username": "lisi",
"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:05:46.203Z",
"last_login_at": "2026-10-02T19:08:44.402Z",
"version": 7
}Errors
| HTTP status | code | Description |
|---|---|---|
| 403 | permission_denied | The user is banned by the platform, and only the platform can unban them |
| 404 | not_found | The user doesn't exist or was deleted |
Platform bans
When handling illegal or violating content (including when platform reviewers process moderation records), the platform may ban your users. Their user object then has disabled_by platform and the platform's reason in status_reason. The platform can also turn a ban you made into a platform ban. Platform-banned users can't sign in, just like users you ban, but you can't undo the platform's action:
| Operation | Result |
|---|---|
| Ban the user | Nothing changes; you get 200 with the current user info and disabled_by stays platform |
| Unban the user | 403 permission_denied |
| Delete the user | 403 permission_denied, so the ban can't be dodged by deleting and recreating the same username |
| Update profile, set password, global mute, sign out devices | Work as usual |
| Send messages as them | 403 user_disabled with details.disabled_by platform. Users you banned aren't limited this way; your server can still send as them |
Timed platform bans also end automatically. If a user wants to close their account while banned by the platform, contact the platform.
