Global mutes
Stop a user from sending messages in one kind of conversation, for example no one-to-one messages, or nothing in any group. While muted they sign in, receive messages and read history as usual; they just can't send there. Mutes can be permanent or timed, ending automatically.
For example, stop zhaoliu sending one-to-one messages for 1 day:
curl -X PUT "$IM_API/$ORG/$APP/users/zhaoliu/mutes/chat" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "duration_seconds": 86400, "reason": "发布广告" }'Mutes are set per scope (scope):
scope | Where | After muting |
|---|---|---|
chat | One-to-one | Can't send one-to-one messages |
group | Groups | Can't send in any group |
room | Chat rooms | Can't send in any chat room |
- What clients see: sending returns
403 user_muted, with the scope indetails.scopeand the end time indetails.expires_at(nullwhen permanent), so clients can show how long the mute lasts. The user's online devices are notified when a mute is set or lifted. - Your server isn't limited: sending messages as the user via OpenAPI ignores global mutes.
- Separate from group mutes: member mutes and mute-all set by group owners and admins are separate; either one stops the user posting in the group.
- Moderation sets them too: moderation automatic penalties and mutes your reviewers choose when confirming a violation set global mutes (automatic penalties have a reason like "Moderation: automatic penalty (3 violations within 24 hours)"), which you can query and lift as usual.
- Other: cleared when the user is deleted; banned users can be muted and unmuted without affecting the ban; works while the app is read-only.
The error a muted user gets when sending a one-to-one message from a client:
{
"error": {
"code": "user_muted",
"message": "你已被禁言",
"details": { "scope": "chat", "expires_at": "2026-10-03T19:09:20.771Z" },
"request_id": "M7DXC7YMRRYILTNTIYJZBMC3KQ"
}
}Get a user's mutes
Get a user's active mutes, at most one per scope, in the order chat, group, room. Expired mutes aren't returned.
/{org_name}/{app_name}/users/{username}/mutesPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username |
Request example
curl "$IM_API/$ORG/$APP/users/zhaoliu/mutes" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK. items holds the active mutes, each a mute object; empty when there are none. No paging.
{
"items": [
{ "scope": "chat", "expires_at": "2026-10-03T19:09:20.771Z", "reason": "发布广告" },
{ "scope": "group", "expires_at": null, "reason": "" }
]
}Errors
| HTTP status | code | Description |
|---|---|---|
| 404 | not_found | The user doesn't exist or was deleted |
Mute a user
Mute a user in a scope.
Setting it again replaces everything: muting a scope that's already muted with duration_seconds left out makes it permanent, with reason left out clears the reason, and timed mutes restart from this call.
/{org_name}/{app_name}/users/{username}/mutes/{scope}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username |
scope | String | The scope: chat, group or room |
Request body
The body is optional; without it the mute is permanent with no reason.
| Field | Type | Required | Description |
|---|---|---|---|
duration_seconds | Number | No | Mute length in seconds, 1 to 315360000 (10 years). Omit for a permanent mute |
reason | String | No | Why they're muted, up to 256 characters without control characters |
Request example
Stop the user sending one-to-one messages for 1 day:
curl -X PUT "$IM_API/$ORG/$APP/users/zhaoliu/mutes/chat" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"duration_seconds": 86400,
"reason": "发布广告"
}'Response
On success you get 200 OK with a mute object.
{
"scope": "chat",
"expires_at": "2026-10-03T19:09:20.771Z",
"reason": "发布广告"
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | scope isn't chat, group or room; 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 |
Unmute a user
Lift a user's mute in a scope. Succeeds even if they weren't muted there, so retries are safe.
/{org_name}/{app_name}/users/{username}/mutes/{scope}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
username | String | The username |
scope | String | The scope: chat, group or room |
Request example
curl -X DELETE "$IM_API/$ORG/$APP/users/zhaoliu/mutes/chat" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 204 No Content with no body.
Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | scope isn't chat, group or room |
| 404 | not_found | The user doesn't exist or was deleted |
List muted users
List the app's currently muted users page by page, excluding expired mutes. Each item is one user's mute in one scope, so a user muted in several scopes appears several times. Sorted by user and scope; for paging see Paging, and start from the first page after changing scope.
/{org_name}/{app_name}/mutesQuery parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
scope | String | No | Only mutes in this scope: chat, group or room. All scopes when omitted |
limit | Number | No | Page size, 1 to 100, default 20 |
cursor | String | No | Paging cursor, the previous page's next_cursor; omit for the first page |
Request example
curl "$IM_API/$ORG/$APP/mutes?scope=group" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK:
| Field | Type | Description |
|---|---|---|
items | Array<Object> | Mutes on this page, each a mute object with username |
next_cursor | String | The next page's cursor; null when there's no next page |
{
"items": [
{ "username": "zhaoliu", "scope": "group", "expires_at": null, "reason": "" },
{ "username": "sunqi", "scope": "group", "expires_at": "2026-10-02T20:09:20.839Z", "reason": "" }
],
"next_cursor": null
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | scope isn't chat, group or room; limit is out of range; the cursor is invalid |
Data structures
Mute object
| Field | Type | Description |
|---|---|---|
username | String | The username; only in List muted users |
scope | String | chat one-to-one, group groups, room chat rooms |
expires_at | String | When it ends automatically; null for a permanent mute |
reason | String | Why they're muted; empty string if none |
{
"scope": "chat",
"expires_at": "2026-10-03T19:09:20.771Z",
"reason": "发布广告"
}