Chat room management
Chat rooms suit live streams, voice rooms and interactive areas at large events: there are no fixed members, offline messages aren't kept, and a room can hold hundreds of thousands of people. For how they differ from groups, see Chat rooms vs groups.
A typical live stream:
- When the stream starts, your server creates a chat room and links its
room_idto the stream. - Users enter with the client SDK when they open the stream page, and leave when they leave the page.
- During the stream, your server sends system messages and deals with users who break the rules.
- When the stream ends, your server dissolves the chat room.
For example, create a chat room for stream L-8812 with streamer zhangsan as owner:
curl -X POST "$IM_API/$ORG/$APP/chatrooms" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "name": "周五晚间直播", "owner": "zhangsan", "attributes": { "live_id": "L-8812" } }'| You want to | See |
|---|---|
| Create, query, update and dissolve chat rooms, check online counts | This page |
| Mute everyone, set admins, attributes such as voice room seats, ban a chat room | This page: Turn on mute-all, Set an admin, Chat room attributes, Ban a chat room |
| See online members; remove, mute or ban users; the allowlist | Chat room members |
| Send system messages, read recent messages, recall | Chat room messages |
The server isn't bound by chat room roles
With the App Token you act as the app's administrator and can do every management action regardless of owner or admin roles. Only one rule applies to the server too: the owner can't be muted, removed or banned; to deal with the owner, transfer or clear ownership first.
Creating chat rooms isn't idempotent
Retrying a create request after a timeout may create two chat rooms. Store the mapping by the returned room_id; before retrying, list chat rooms by owner or name prefix to confirm the earlier attempt didn't succeed, and dissolve any extra one.
When a chat room doesn't exist, APIs return 404 not_found. A dissolved chat room can still be queried for 30 days; other APIs return 404 not_found with details.reason chatroom_dismissed, so you can tell "dissolved" from "doesn't exist":
{
"error": {
"code": "not_found",
"message": "聊天室已解散",
"details": { "reason": "chatroom_dismissed" },
"request_id": "BTIXR6TUFAL7HHCQWG6UXBTJEN"
}
}While the app is read-only (see Rate limits and app status), creating chat rooms, changing profiles, setting attributes, adding to the allowlist and sending messages return 403 app_unavailable; dissolving, banning and unbanning, transferring ownership, mute-all, setting admins, removing, muting and banning users, removing from the allowlist, deleting attributes and recalling messages still work, and users can still enter, leave and read.
Concepts
Chat rooms vs groups
| Groups | Chat rooms | |
|---|---|---|
| Members | Fixed members who stay members once joined, even offline | Whoever is in the room right now, coming and going with their connection; membership isn't stored |
| Size | 500 by default, up to 5000 | 100,000 by default, up to 500,000 |
| Messages | Stored, filled in after being offline, counted as unread, with offline push | Not stored, only pushed to connections in the room right now; people who just entered can only see the last few dozen |
| Delivery | Every message is delivered | Merged and throttled when busy, dropped by priority |
| Who can join | Added by the server, or by invitation or application | Any user in the app who knows the room ID, unless banned |
| Good for | Class, project and interest groups | Live streams, voice rooms, event interaction |
Although membership isn't stored, a chat room's management data is: owner, admins, mutes, bans, the allowlist, the announcement and attributes are all kept on the server, regardless of who's in the room. A muted user who leaves and comes back is still muted; an admin who leaves and comes back is still an admin.
Chat room messages don't go into users' conversations, aren't counted as unread, don't trigger offline push and don't appear in message export.
Entering and leaving
After signing in, users enter a chat room over their long-lived connection (the client SDK does this), and that connection starts receiving the room's messages and notifications. There's no server API to "pull" a user into a room; you can check whether a user is in a room or remove them.
Conditions for entering:
- The chat room exists and is normal (not banned or dissolved).
- The user isn't banned from this room.
- The room isn't full (owners and admins aren't subject to the size limit).
- One connection can be in at most 10 chat rooms at once.
Users can enter with an ext of up to 512 bytes (such as "VIP3"), which appears in the member-entered notification.
- Multiple devices: a user can enter from several devices at once and is in the room while any one of them is; online counts and member lists count users, not devices.
- Leaving: leaving explicitly takes effect immediately; a dropped connection (network loss, app closed) counts as leaving after 15 seconds, so switching networks and reconnecting within 15 seconds doesn't cause a leave and re-enter. Owners and admins keep their roles after leaving.
- Entry rate: each connection can enter at most 10 times a minute, and each room admits at most 2000 people per second. Over that, the client gets a rate-limit error and retries after a random 1 to 3 seconds, so a rush at the start of a stream is spread over a dozen or so seconds.
When removed, the user's connection gets a removal notice with a reason, and clients shouldn't re-enter automatically:
| Reason | When |
|---|---|
kicked | Removed |
banned | Banned |
disabled | The chat room was banned |
dismissed | The chat room was dissolved |
In rooms with at most chatroom_member_notify_limit people online (runtime policy, 100 by default), other online members are notified when someone enters or leaves; busier rooms don't push enter and leave notices. To show "X entered the stream", send your own low-priority custom messages at a rate you control.
Roles
| Role | role | Description |
|---|---|---|
| Owner | owner | At most one per room, or none (managed by your server). In clients can do every management action, including changing the size limit, setting admins, transferring ownership and dissolving the room. Nobody can mute, remove or ban the owner |
| Admin | admin | Up to 99 per room, set by the owner or the server. In clients can change the name, description, cover and announcement, turn on mute-all, mute, remove and ban regular users, manage the allowlist, send high-priority messages and recall regular users' messages |
| Regular user | member | Everyone else. Can enter, send normal and low-priority messages, see members and recent messages, and recall their own messages within recall_window_seconds (runtime policy, 120 seconds by default) |
- Roles don't depend on being in the room: owners and admins keep their roles while away.
- In clients, admins can't act on other admins, and when lifting mutes and bans, admins can only lift ones set by admins; ones set by the owner or your server can only be lifted by the owner or the server.
- These are permissions in clients; server APIs aren't bound by them.
- When a user is deleted, their admin roles, mutes, bans and allowlist entries in every chat room are cleared; if they were an owner, the owner is cleared and not passed to anyone.
Online count
member_count in the chat room info is how many users are in the room right now, counting each user once across devices and including users disconnected for under 15 seconds. It's cached for up to 5 seconds, so it's approximate and suited to displays like "123K online". Banned and dissolved rooms show 0. To show counts for several rooms at once, use Get online counts in batches.
Message priority and delivery
Every chat room message has a priority that decides whether it can be throttled or dropped when things get busy:
| Priority | priority | Use | Who can send |
|---|---|---|---|
| High | high | System notices, admin announcements, gift settlements and other messages that mustn't be lost | Owners, admins and your server |
| Normal | normal | Regular chat; the default | Everyone |
| Low | low | Likes, bullet-comment effects, entrance effects and other high-frequency messages that can be lost | Everyone |
Rate limits when sending:
| Quota | Counts | Over the limit |
|---|---|---|
chatroom_msg_per_second per room per second (runtime policy, 40 by default) | Normal and low priority | Normal messages get 429 rate_limited; low-priority ones are silently dropped (the send still succeeds, with dropped true in the response) |
| 20 per room per second | High priority | 429 rate_limited |
chatroom_msg_per_sec_limit per second across all the app's rooms (quota, 2000 by default) | All three priorities | 429 rate_limited |
When delivering:
- Merging and throttling: in busy rooms, messages are merged into a batch every 200 milliseconds. Each connection receives at most 50 normal and low-priority items and 128 KB per second from one room; beyond that low-priority items are dropped first, then normal ones, and anything waiting more than a second is dropped too. High-priority content goes ahead of everything else and normally isn't dropped. Connections with very poor networks and large backlogs only receive high-priority content. Clients are told how many items were dropped and can show "Busy; some messages omitted".
- No delivery or ordering guarantee: chat room messages only go to connections in the room right now and can be lost on network trouble, and messages from different users may arrive in slightly different orders. For content that must arrive reliably (such as gift settlements), send it at high priority and make sure of it in your own business logic.
Among the room's own notifications, profile, mute, allowlist and attribute changes and message recalls are high priority; enter and leave notices are low priority.
Recent messages
The latest chatroom_history_size normal and high-priority messages are kept (runtime policy, 50 by default, 0 to 200, 0 meaning none), for 24 hours at most; low-priority messages aren't kept. Users who just entered can fetch them to show the recent chat, and your server can query recent messages.
Recent messages aren't history: you can't page back, and they aren't guaranteed complete. They're cleared when the room is banned or dissolved. To keep chat room messages, use the chat room message delivery in event callbacks.
Profile and announcement
| Field | Description |
|---|---|
name | Name, 1 to 128 characters, required, no control characters; leading and trailing whitespace trimmed |
description | Description, up to 512 characters; line breaks allowed |
announcement | Announcement, up to 2048 characters; line breaks allowed. Each change records the time in announcement_updated_at and the client user who changed it in announcement_updated_by, so clients can show "Announcement updated" |
avatar_url | Cover address, see Covers |
max_members | Size limit, see below |
listed | Whether it appears in clients' chat room lists; default true. Rooms set to false can only be entered by ID |
Size limit: the limit in effect (max_members in the chat room object) is the smaller of the room's own limit (1 to 500000, max_members_setting) and max_chatroom_members in the runtime policy (100000 by default, 10 to 500000); rooms without their own limit follow the runtime policy. Lowering it below the current count doesn't remove anyone; it just stops new people entering. Owners and admins aren't subject to it.
When the profile changes (including mute-all, owner and admin changes), online members are notified in real time with only the changed fields. Profiles are visible to every user of the app; the ban reason status_reason is only returned by server APIs and the console, never to clients.
When creating and updating chat rooms, the name, description and announcement go through moderation (content from your server is checked against platform rules only by default), only for fields actually changed: failing fields aren't written and you get 403 content_rejected with the field in details.field; text matching replacement rules is saved with the replacement.
Covers
The cover avatar_url is an http or https address of up to 512 characters, stored by this service or your own.
Using this service's covers: upload an image with purpose chatroom_avatar and type image (you can do this before creating the room) to get a public address anyone can open (long edge scaled to at most 640 pixels), and put it in avatar_url when creating or updating the room.
| Case | Cover file |
|---|---|
| No room used it within 24 hours of upload | Deleted |
| Replaced (changed to another address or cleared) | Deleted after 7 days |
| The room is dissolved | Deleted after 7 days |
Using your own addresses: avatar_url written through server APIs only has its format checked and is never fetched. But when users create a room or change its cover from a client and the app enables media_url_only in its runtime policy, only this app's cover addresses or https addresses on hosts in media_allowed_hosts are allowed; otherwise you get 400 invalid_argument (url_not_allowed).
Chat room attributes
Attributes are custom key-value pairs on a room, visible to all members, often used for voice room seats (such as seat_1 = zhangsan), game state in a stream, or your own stream ID. Every change is pushed to online members in real time and increments attributes_version.
- Format: up to 100 keys per room. Keys are 1 to 128 characters of letters, digits and
_,-,.,:; values are strings of up to 4096 bytes without control characters other than line feeds, carriage returns and tabs; all keys and values together at most 16 KB. Up to 20 keys per set or delete, and at most 16 KB of keys and values per set. - Who can change them: users in the room can set and delete attributes from clients, but only keys nobody set or that they set themselves; owners and admins can overwrite and delete keys set by others (including your server). Muted users, and regular users not on the allowlist during mute-all, can't set attributes. Your server can set and delete any key.
- Deleted when the setter leaves: users setting attributes from clients can mark them
auto_delete, so those keys are removed when they leave and a seat isn't held forever by someone who dropped off. Leaving only counts after 15 seconds of disconnection, so switching networks doesn't lose the seat. Attributes set by the server can't beauto_delete. - Content checks: attribute values aren't reviewed before being set; they go through moderation afterwards, and violating attributes are deleted.
- Rate: at most 20 attribute writes per room per second (clients and server combined); over that you get
429 rate_limitedwithdetails.reasonroom_attribute_rate. State that changes several times a second (such as a live like count) doesn't belong in attributes; use low-priority custom messages.
Status
status | Description |
|---|---|
active | Normal |
disabled | Banned: everyone online is removed and nobody can enter or send messages; management data is kept, see Ban a chat room |
dismissed | Dissolved, permanently, see Dissolve a chat room |
Versions
Chat rooms have two versions, each incremented on change:
info_version: the version of the profile and settings. Changing the profile, turning mute-all on or off, transferring ownership, setting and removing admins, banning and unbanning all increment it. When updating the profile, send theinfo_versionyou read (asversion) to avoid overwriting someone else's simultaneous change, see Concurrent changes.attributes_version: the attributes version, incremented on every attribute change.
Create a chat room
Create a chat room, with an owner or without one so your server manages it. You can set initial attributes at the same time, such as your stream ID. Users can enter as soon as it's created; it's open to every user in the app.
The number of non-dissolved chat rooms (banned ones included) is limited by the smaller of the platform's quota for the app (10,000 by default) and the app's plan; dissolved rooms stop counting.
/{org_name}/{app_name}/chatroomsPath parameters
For org_name and app_name, see the server overview.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
name | String | Yes | Name, 1 to 128 characters, no control characters; leading and trailing whitespace trimmed |
owner | String | No | The owner's username; must be an existing user but needn't be in the room. No owner when omitted |
description | String | No | Description, up to 512 characters; line breaks allowed. Defaults to an empty string |
avatar_url | String | No | Cover address, http or https, up to 512 characters, no whitespace, see Covers |
announcement | String | No | Announcement, up to 2048 characters; line breaks allowed |
max_members | Number | No | The room's own size limit, 1 to 500000; omitted or null follows the runtime policy, see Profile and announcement |
listed | Boolean | No | Whether it appears in clients' chat room lists; default true |
attributes | Object | No | Initial attributes, keys to string values, up to 100 keys and 16 KB in total; format in Chat room attributes |
Request example
curl -X POST "$IM_API/$ORG/$APP/chatrooms" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "周末音乐会",
"owner": "zhangsan",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/room/concert.png",
"announcement": "欢迎来到直播间,请文明发言",
"max_members": 50000,
"attributes": { "live_id": "L-20261004", "theme": "night" }
}'Response
On success you get 201 Created with a chat room object.
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/room/concert.png",
"announcement": "欢迎来到直播间,请文明发言",
"announcement_updated_at": "2026-10-04T19:19:52.149Z",
"announcement_updated_by": null,
"owner": "zhangsan",
"admins": [],
"max_members": 50000,
"mute_all": false,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 0,
"info_version": 1,
"attributes_version": 1,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": 50000,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 2
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | name is missing or a field is invalid; invalid attribute keys or values give details.reason invalid_attribute_key or invalid_attribute_value with the key in details.key; attributes over 16 KB give attributes_too_large |
| 403 | content_rejected | The name, description or announcement failed moderation; details.field names the field |
| 403 | app_unavailable | The app is read-only and can't create chat rooms |
| 404 | not_found | The owner user doesn't exist |
| 409 | limit_exceeded | details.reason chatroom_limit: the app has reached its limit of non-dissolved chat rooms |
List chat rooms
List the app's chat rooms page by page, optionally filtered by status and owner, or searched by name prefix. By default only non-dissolved rooms (banned ones included) are listed, newest first; name-prefix searches are sorted by name. Each item includes the current online count.
/{org_name}/{app_name}/chatroomsPath parameters
For org_name and app_name, see the server overview.
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
status | String | No | Only this status: active, disabled or dismissed. Omitted lists active and disabled; dissolved rooms disappear 30 days after dissolution |
owner | String | No | Only rooms owned by this user; an empty list if the user doesn't exist |
name_prefix | String | No | Search by name prefix, up to 128 characters; % and _ match literally |
limit | Number | No | Page size, default 20, 1 to 100 |
cursor | String | No | The cursor for the next page, see Paging |
Request example
curl -X GET "$IM_API/$ORG/$APP/chatrooms?owner=zhangsan&limit=20" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK, with each item in items a chat room object and the next page's cursor in next_cursor (null when there's no next page).
{
"items": [
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/t100308694423568384/a100308695405035520/r/100313154805825536_r8g57ewc.jpg",
"announcement": "今晚 8 点开播,请文明发言",
"announcement_updated_at": "2026-10-04T19:21:44.379Z",
"announcement_updated_by": null,
"owner": "zhangsan",
"admins": ["lisi"],
"max_members": 100000,
"mute_all": false,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 4,
"info_version": 21,
"attributes_version": 8,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 3
}
],
"next_cursor": null
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | status has an invalid value, name_prefix is longer than 128 characters, limit is out of range, or cursor is invalid |
Get a chat room
Return everything about a chat room, including the current online count. Dissolved rooms can be queried for 30 days after dissolution, with status dismissed.
/{org_name}/{app_name}/chatrooms/{room_id}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request example
curl -X GET "$IM_API/$ORG/$APP/chatrooms/100310941534519296" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with a chat room object.
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/t100308694423568384/a100308695405035520/r/100313154805825536_r8g57ewc.jpg",
"announcement": "今晚 8 点开播,请文明发言",
"announcement_updated_at": "2026-10-04T19:21:44.379Z",
"announcement_updated_by": null,
"owner": "zhangsan",
"admins": ["lisi"],
"max_members": 100000,
"mute_all": false,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 4,
"info_version": 21,
"attributes_version": 8,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 3
}Errors
| HTTP status | code | Description |
|---|---|---|
| 404 | not_found | The chat room doesn't exist, or room_id is malformed |
Get online counts in batches
Get online counts for up to 100 chat rooms at once, for showing counts on a room list page. For what the count means, see Online count.
/{org_name}/{app_name}/chatrooms/online-countsPath parameters
For org_name and app_name, see the server overview.
Request body
| Field | Type | Required | Description |
|---|---|---|---|
room_ids | Array<String> | Yes | Chat room IDs, up to 100; duplicates are returned once. Malformed IDs are ignored; an empty array returns empty items |
Request example
curl -X POST "$IM_API/$ORG/$APP/chatrooms/online-counts" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"room_ids": ["100310941534519296", "100311027031212032", "123"]
}'Response
On success you get 200 OK, with each item in items one room's online count, in request order. Nonexistent and dissolved rooms aren't included; banned rooms show 0.
| Field | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
member_count | Number | The online count |
{
"items": [
{ "room_id": "100310941534519296", "member_count": 6 },
{ "room_id": "100311027031212032", "member_count": 0 }
]
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | room_ids has more than 100 entries |
Update a chat room's profile
Change the room's name, description, cover, announcement, size limit and whether it's listed. Only fields in the request change; when every value equals the old one (or nothing is given), nothing changes and changed is false. Online members are notified in real time.
Banned rooms can be updated too, so violating names, announcements and covers can be cleared. Change the owner with Transfer ownership and attributes with Set chat room attributes; this API doesn't accept owner or attributes.
/{org_name}/{app_name}/chatrooms/{room_id}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request body
Formats are the same as in Create a chat room.
| Field | Type | Required | Description |
|---|---|---|---|
name | String | No | Name, 1 to 128 characters; can't be cleared |
description | String | No | Description, up to 512 characters; an empty string clears it |
avatar_url | String | No | Cover address; an empty string clears it. After replacing or clearing a cover from this service, the old file is deleted after 7 days |
announcement | String | No | Announcement, up to 2048 characters; an empty string clears it. announcement_updated_at becomes the current time when it changes |
max_members | Number | No | The room's own size limit, 1 to 500000; null clears it so the runtime policy applies |
listed | Boolean | No | Whether it appears in clients' chat room lists |
version | Number | No | The info_version you read. If given and it doesn't match the current info_version, you get 409 version_conflict and nothing changes |
Request example
curl -X PATCH "$IM_API/$ORG/$APP/chatrooms/100310941534519296" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"announcement": "今晚 8 点开播,请文明发言",
"max_members": null,
"version": 2
}'Response
On success you get 200 OK with the updated chat room object plus one field:
| Field | Type | Description |
|---|---|---|
changed | Boolean | Whether this request changed the room. When false, info_version doesn't change and members aren't notified |
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/room/concert.png",
"announcement": "今晚 8 点开播,请文明发言",
"announcement_updated_at": "2026-10-04T19:21:44.379Z",
"announcement_updated_by": null,
"owner": "zhangsan",
"admins": ["lisi"],
"max_members": 100000,
"mute_all": false,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 6,
"info_version": 3,
"attributes_version": 1,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 2,
"changed": true
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | A field has an invalid value, such as an empty name; the request contains a field that can't be changed (such as owner or attributes) |
| 403 | content_rejected | The name, description or announcement failed moderation; details.field names the field |
| 403 | app_unavailable | The app is read-only and profiles can't be changed |
| 404 | not_found | The chat room doesn't exist or was dissolved |
| 409 | version_conflict | version doesn't match the current info_version, which is in details.info_version; query again before deciding whether to change it |
Transfer ownership
Give ownership to any user in the app; they needn't be in the room or agree. You can also clear the owner so your server manages the room. Afterwards:
| Who | What changes |
|---|---|
| The old owner | Becomes a regular user |
| The new owner | No longer uses an admin slot if they were an admin; any mute or ban on them is lifted (nobody can mute or ban the owner) |
| The room | info_version increases by one and online members are notified in real time |
If it's the current owner, nothing changes and changed is false. Banned rooms can transfer ownership too, so you can deal with an owner who broke the rules.
/{org_name}/{app_name}/chatrooms/{room_id}/ownerPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
username | String | Yes | The new owner's username; must be an existing user. null clears the owner |
Request example
curl -X PUT "$IM_API/$ORG/$APP/chatrooms/100310941534519296/owner" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"username": "zhaoliu"
}'Response
On success you get 200 OK with the chat room object after the transfer, plus changed with the same meaning as in Update a chat room's profile.
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/room/concert.png",
"announcement": "今晚 8 点开播,请文明发言",
"announcement_updated_at": "2026-10-04T19:21:44.379Z",
"announcement_updated_by": null,
"owner": "zhaoliu",
"admins": ["lisi"],
"max_members": 100000,
"mute_all": false,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 4,
"info_version": 12,
"attributes_version": 8,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 3,
"changed": true
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | The body has no username field |
| 404 | not_found | The chat room doesn't exist or was dissolved; the username user doesn't exist |
Turn on mute-all
With mute-all on, only the owner, admins and users on the allowlist can send messages and set attributes from clients; anyone else sending gets 403 chatroom_muted with details.reason all. Users who are individually muted can't post even if they're admins or on the allowlist.
Online members are notified in real time. If it's already on, nothing changes and changed is false. Banned rooms can set it too.
提示
Mutes only limit posting from clients. Your server sending messages isn't limited by mutes or mute-all.
/{org_name}/{app_name}/chatrooms/{room_id}/mute-allPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request example
curl -X PUT "$IM_API/$ORG/$APP/chatrooms/100310941534519296/mute-all" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with a chat room object plus changed with the same meaning as in Update a chat room's profile.
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/room/concert.png",
"announcement": "今晚 8 点开播,请文明发言",
"announcement_updated_at": "2026-10-04T19:21:44.379Z",
"announcement_updated_by": null,
"owner": "zhangsan",
"admins": ["lisi"],
"max_members": 100000,
"mute_all": true,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 6,
"info_version": 8,
"attributes_version": 1,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 2,
"changed": true
}Errors
| HTTP status | code | Description |
|---|---|---|
| 404 | not_found | The chat room doesn't exist or was dissolved |
Turn off mute-all
Turn off mute-all so everyone can post again. Individually muted users still can't post; unmute them separately. If it's not on, nothing changes and changed is false.
/{org_name}/{app_name}/chatrooms/{room_id}/mute-allPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request example
curl -X DELETE "$IM_API/$ORG/$APP/chatrooms/100310941534519296/mute-all" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with the same response as Turn on mute-all, with mute_all false.
Errors
| HTTP status | code | Description |
|---|---|---|
| 404 | not_found | The chat room doesn't exist or was dissolved |
Set an admin
Make a user an admin of the room; they needn't be in it. Each room has at most 99 admins. If they're already an admin or the owner, nothing changes and changed is false. Muted users can be made admins and their mute still applies; users currently banned from the room can't, so lift the ban first.
Afterwards info_version increases by one and online members are notified in real time with the full admin list.
/{org_name}/{app_name}/chatrooms/{room_id}/admins/{username}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
username | String | The user to make an admin |
Request example
curl -X PUT "$IM_API/$ORG/$APP/chatrooms/100310941534519296/admins/lisi" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK:
| Field | Type | Description |
|---|---|---|
changed | Boolean | Whether this request changed the admins |
info_version | Number | The room's current info_version |
{
"changed": true,
"info_version": 2
}Errors
| HTTP status | code | Description |
|---|---|---|
| 403 | permission_denied | details.reason target_banned: the user is currently banned from the room |
| 404 | not_found | The chat room doesn't exist or was dissolved, or the user doesn't exist |
| 409 | limit_exceeded | details.reason admin_limit: the room already has 99 admins |
Remove an admin
Remove a user's admin role so they become a regular user. If they aren't an admin, nothing changes and changed is false. Banning an admin removes their admin role automatically, so you don't need this first.
/{org_name}/{app_name}/chatrooms/{room_id}/admins/{username}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
username | String | The admin's username |
Request example
curl -X DELETE "$IM_API/$ORG/$APP/chatrooms/100310941534519296/admins/lisi" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with the same fields as Set an admin.
{
"changed": true,
"info_version": 17
}Errors
| HTTP status | code | Description |
|---|---|---|
| 404 | not_found | The chat room doesn't exist or was dissolved, or the user doesn't exist |
Get chat room attributes
Return all of a room's attributes, or only some keys.
/{org_name}/{app_name}/chatrooms/{room_id}/attributesPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Query parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
keys | String | No | Only these keys, comma-separated, up to 100; nonexistent keys are left out. All attributes when omitted |
Request example
curl -X GET "$IM_API/$ORG/$APP/chatrooms/100310941534519296/attributes" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK:
| Field | Type | Description |
|---|---|---|
attributes | Object | Keys to attributes; an empty object when there are none. Each attribute's fields are below |
attributes_version | Number | The attributes version |
| Attribute field | Type | Description |
|---|---|---|
value | String | The value |
owner | String | Who last set this key; null when set by your server or the console, or when that person was deleted |
auto_delete | Boolean | Whether it's deleted automatically when the setter leaves the room |
updated_at | String | When it was last set |
{
"attributes": {
"game_state": {
"value": "round-2",
"owner": null,
"auto_delete": false,
"updated_at": "2026-10-04T19:24:10.996Z"
},
"live_id": {
"value": "L-20261004",
"owner": null,
"auto_delete": false,
"updated_at": "2026-10-04T19:19:52.149Z"
},
"seat_1": {
"value": "wangwu",
"owner": null,
"auto_delete": false,
"updated_at": "2026-10-04T19:24:10.996Z"
},
"seat_2": {
"value": "zhengshi",
"owner": "zhengshi",
"auto_delete": true,
"updated_at": "2026-10-04T19:24:35.088Z"
},
"theme": {
"value": "day",
"owner": null,
"auto_delete": false,
"updated_at": "2026-10-04T19:24:10.996Z"
}
},
"attributes_version": 3
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | keys contains an invalid key (details.reason invalid_attribute_key) or more than 100 keys |
| 404 | not_found | The chat room doesn't exist or was dissolved |
Set chat room attributes
Add or overwrite attributes, up to 20 keys at a time. The server can overwrite keys set by anyone; overwritten keys get owner null and auto_delete false. A key with the same value that was already set by the server doesn't count as a change. When any key is written, attributes_version increases by one and online members are notified in real time.
Keys that would push the room over 100 attributes or 16 KB aren't written and come back in failed; the others are written as usual. Banned rooms can set attributes too.
/{org_name}/{app_name}/chatrooms/{room_id}/attributesPath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
attributes | Object | Yes | Attributes to set, keys to string values, 1 to 20 keys and at most 16 KB in total; format in Chat room attributes |
auto_delete | Boolean | No | Can only be false (default). Server-set attributes can't be deleted when a setter leaves; true returns 400 invalid_argument with details.reason auto_delete_not_allowed |
Request example
curl -X PUT "$IM_API/$ORG/$APP/chatrooms/100310941534519296/attributes" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"attributes": {
"theme": "day",
"seat_1": "wangwu",
"game_state": "round-2"
}
}'Response
On success you get 200 OK:
| Field | Type | Description |
|---|---|---|
changed | Boolean | Whether any key was written |
attributes_version | Number | The attributes version: the new one if anything changed, otherwise the current one |
failed | Object | Keys not written, mapped to the reason (code and details); an empty object when all were written. Currently only limit_exceeded (details.reason attribute_limit): writing would exceed the count or size limit |
{
"changed": true,
"attributes_version": 2,
"failed": {}
}When some keys are over the limit:
{
"changed": true,
"attributes_version": 5,
"failed": {
"big4": {
"code": "limit_exceeded",
"details": { "reason": "attribute_limit" }
}
}
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | attributes is empty or has more than 20 keys; a key or value is invalid (details.reason invalid_attribute_key or invalid_attribute_value, with the key in details.key); keys and values exceed 16 KB (attributes_too_large, details.max_bytes 16384); auto_delete is true (auto_delete_not_allowed) |
| 403 | app_unavailable | The app is read-only and attributes can't be set |
| 404 | not_found | The chat room doesn't exist or was dissolved |
| 429 | rate_limited | details.reason room_attribute_rate: the room has reached 20 attribute writes this second |
Delete chat room attributes
Delete attributes, up to 20 keys at a time. The server can delete keys set by anyone, and nonexistent keys are ignored. When any key is deleted, attributes_version increases by one and online members are notified in real time. Deleting works while the app is read-only.
/{org_name}/{app_name}/chatrooms/{room_id}/attributes/batch-deletePath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
keys | Array<String> | Yes | Keys to delete, 1 to 20; duplicates handled once |
Request example
curl -X POST "$IM_API/$ORG/$APP/chatrooms/100310941534519296/attributes/batch-delete" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"keys": ["game_state", "seat_2"]
}'Response
On success you get 200 OK with the same fields as Set chat room attributes, where changed means whether any key was deleted.
{
"changed": true,
"attributes_version": 8,
"failed": {}
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | keys is empty, has more than 20 entries, or contains an invalid key |
| 404 | not_found | The chat room doesn't exist or was dissolved |
| 429 | rate_limited | details.reason room_attribute_rate: the room has reached 20 attribute writes this second |
Ban a chat room
Temporarily disable a room that breaks the rules, such as a violating live stream; you can unban it later. When banned:
| Result | |
|---|---|
| Online users | All removed (reason disabled); entering while banned returns 403 chatroom_disabled |
| Messages | Recent messages are cleared; nobody can send, including your server (403 chatroom_disabled) |
| Client management actions | All unavailable |
| Your server | Can still change the profile and announcement, transfer ownership, set admins, mute, ban and manage the allowlist, set and delete attributes (to clear violations), and dissolve the room |
After banning, status becomes disabled, disabled_by is tenant and info_version increases by one. After unbanning, the profile, admins, lists and attributes are as they were, and users just enter again.
Chat rooms banned by the platform
Rooms with disabled_by platform were banned by the platform for breaking laws or platform rules. You can't unban or dissolve them; banning them again doesn't change anything and just returns the current info.
/{org_name}/{app_name}/chatrooms/{room_id}/disablePath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request body
The body is optional.
| Field | Type | Required | Description |
|---|---|---|---|
reason | String | No | The ban reason, up to 256 characters without control characters. Saved in the chat room object's status_reason, visible only through server APIs and the console, never in clients |
Banning a room you already banned only replaces the reason with the new reason (clearing it if omitted); info_version doesn't change and users aren't notified; changed is true if the reason changed and false otherwise.
Request example
curl -X POST "$IM_API/$ORG/$APP/chatrooms/100311027198984192/disable" \
-H "Authorization: Bearer $APP_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"reason": "直播内容违规,调查中"
}'Response
On success you get 200 OK with the banned chat room object plus changed with the same meaning as in Update a chat room's profile.
{
"room_id": "100311027198984192",
"name": "周末音乐会 · 彩排",
"description": "",
"avatar_url": "",
"announcement": "",
"announcement_updated_at": null,
"announcement_updated_by": null,
"owner": null,
"admins": [],
"max_members": 100000,
"mute_all": false,
"listed": true,
"status": "disabled",
"disabled_by": "tenant",
"member_count": 0,
"info_version": 2,
"attributes_version": 0,
"created_at": "2026-10-04T19:20:12.573Z",
"status_reason": "直播内容违规,调查中",
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 0,
"changed": true
}Errors
| HTTP status | code | Description |
|---|---|---|
| 400 | invalid_argument | reason is longer than 256 characters or has control characters |
| 404 | not_found | The chat room doesn't exist or was dissolved |
Unban a chat room
Lift your ban so the room returns to normal and users can enter again. status becomes active, status_reason is cleared and info_version increases by one. If the room isn't banned, nothing changes and changed is false.
/{org_name}/{app_name}/chatrooms/{room_id}/enablePath parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request example
curl -X POST "$IM_API/$ORG/$APP/chatrooms/100311027198984192/enable" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 200 OK with the unbanned chat room object plus changed, in the same structure as Ban a chat room, with status active and disabled_by and status_reason null.
Errors
| HTTP status | code | Description |
|---|---|---|
| 403 | permission_denied | The room is banned by the platform (disabled_by platform), and only the platform can unban it |
| 404 | not_found | The chat room doesn't exist or was dissolved |
Dissolve a chat room
Dissolve a chat room. This can't be undone; usually called when a stream ends. Afterwards:
| Result | |
|---|---|
| Online users | All removed (reason dismissed); nobody can enter again |
| Management data | Admins, mutes, bans, the allowlist, attributes and recent messages are deleted shortly after |
| Counts and IDs | No longer counted toward the app's chat rooms; the ID is never reused |
| Queries | Get a chat room still works for 30 days (status dismissed); other APIs return 404 not_found (chatroom_dismissed). The record is deleted after 30 days |
Dissolving the same room again also returns 204 No Content.
/{org_name}/{app_name}/chatrooms/{room_id}Path parameters
For org_name and app_name, see the server overview.
| Parameter | Type | Description |
|---|---|---|
room_id | String | The chat room ID |
Request example
curl -X DELETE "$IM_API/$ORG/$APP/chatrooms/100311027031212032" \
-H "Authorization: Bearer $APP_TOKEN"Response
On success you get 204 No Content with no body. Getting the room afterwards:
{
"room_id": "100311027031212032",
"name": "新品发布会互动区",
"description": "",
"avatar_url": "",
"announcement": "",
"announcement_updated_at": null,
"announcement_updated_by": null,
"owner": null,
"admins": [],
"max_members": 100000,
"mute_all": false,
"listed": false,
"status": "dismissed",
"disabled_by": null,
"member_count": 0,
"info_version": 1,
"attributes_version": 0,
"created_at": "2026-10-04T19:20:12.533Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": "2026-10-04T19:27:20.733Z",
"attribute_count": 0
}Errors
| HTTP status | code | Description |
|---|---|---|
| 403 | permission_denied | The room is banned by the platform (disabled_by platform) and can't be dissolved |
| 404 | not_found | The chat room doesn't exist |
Data structures
Chat room object
Chat room objects from server APIs have all the fields below. The chat room info clients see doesn't include status_reason, max_members_setting, created_via, created_by, dismissed_at or attribute_count.
| Field | Type | Description |
|---|---|---|
room_id | String | The chat room ID, generated by the system and never changed |
name | String | Name |
description | String | Description; empty string if none |
avatar_url | String | Cover address; empty string if none |
announcement | String | Announcement; empty string if none |
announcement_updated_at | String | When the announcement last changed; null if never set |
announcement_updated_by | String | Who last changed the announcement from a client; null when changed by the server or console, or when that person was deleted |
owner | String | The owner's username; null when there's no owner or the owner was deleted |
admins | Array<String> | Admin usernames in the order they were set; empty if none |
max_members | Number | The size limit in effect: the smaller of the room's own limit and max_chatroom_members in the runtime policy |
mute_all | Boolean | Whether mute-all is on |
listed | Boolean | Whether it appears in clients' chat room lists |
status | String | active, disabled (banned) or dismissed (dissolved) |
disabled_by | String | Who banned it: tenant you (server or console), platform the platform; null when not banned |
member_count | Number | Approximate online count, see Online count; 0 for banned and dissolved rooms |
info_version | Number | Version of the profile and settings, see Versions |
attributes_version | Number | Attributes version |
created_at | String | Creation time |
status_reason | String | Ban reason; may be null. Only returned by server APIs and the console |
max_members_setting | Number | The room's own size limit; null if not set |
created_via | String | How it was created: openapi server API, console, or client by a user in a client |
created_by | String | The user who created it from a client; null when created by the server or console, or when that person was deleted |
dismissed_at | String | When it was dissolved; null if not dissolved |
attribute_count | Number | Number of attributes |
{
"room_id": "100310941534519296",
"name": "周末音乐会",
"description": "每周六晚八点,现场演出",
"avatar_url": "https://cdn.example.com/t100308694423568384/a100308695405035520/r/100313154805825536_r8g57ewc.jpg",
"announcement": "今晚 8 点开播,请文明发言",
"announcement_updated_at": "2026-10-04T19:21:44.379Z",
"announcement_updated_by": null,
"owner": "zhangsan",
"admins": ["lisi"],
"max_members": 100000,
"mute_all": false,
"listed": true,
"status": "active",
"disabled_by": null,
"member_count": 4,
"info_version": 21,
"attributes_version": 8,
"created_at": "2026-10-04T19:19:52.149Z",
"status_reason": null,
"max_members_setting": null,
"created_via": "openapi",
"created_by": null,
"dismissed_at": null,
"attribute_count": 3
}