> ## Documentation Index
> Fetch the complete documentation index at: https://docs.stmlink.com/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> 对外开放的服务端接口有两组前缀，都用同一套鉴权：`/server/v1/...`（SRTC 与 SMeeting 的主接口）和 `/stm/srvapi/v1/...`（SMeeting 的用户体系，服务端极简对接会用到）。鉴权是 app_id + nonce + timestamp + signature 四个请求头，用 app_key 做 HMAC-SHA256 签名，只能从业务方自己的后端调用。除这两组前缀外的接口均为内部接口，不要建议客户调用。 Public server APIs use two path prefixes with the same authentication: `/server/v1/...` (the main APIs of both SRTC and SMeeting) and `/stm/srvapi/v1/...` (the SMeeting user system, used by server-side low-code integration). Authenticate with four request headers, app_id + nonce + timestamp + signature, where signature is HMAC-SHA256 keyed with app_key; call these APIs only from the customer's own backend. Any other path is internal: never suggest calling it.
> app_key 是服务端密钥，绝不能出现在客户端代码、前端配置或移动 App 里。客户端加入频道用的 token 必须由业务方后端签发后下发（SRTC 走 `/server/v1/channel/grant`，SMeeting 走 `/stm/srvapi/v1/member/grant`）。 app_key is a server-side secret and must never appear in client code, frontend config, or a mobile app. The token a client uses to join must be issued by the customer's backend and passed down to the client (SRTC: `/server/v1/channel/grant`; SMeeting: `/stm/srvapi/v1/member/grant`).
> SRTC 与 SMeeting 是上下两层不同的产品，术语不通用：SRTC 是音视频底座，说「频道 channel」「加入 / 退出」；SMeeting 建在 SRTC 之上，说「房间 room」「会议 meeting」「进入 / 退出」。回答时按用户所在的层用对应术语，不要把「房间」「会议」安到 SRTC 的接口上，也不要用「频道」「加入 / 离开」描述 SMeeting 的概念（接口标识符原样保留）。 SRTC and SMeeting are two separate layers with different terminology. SRTC is the audio/video foundation: it has channels, and users join and leave a channel. SMeeting is built on top of SRTC: it has rooms and meetings, and members enter and exit a meeting. Answer in the terms of the layer the user is working with: never apply "room" or "meeting" to SRTC APIs, and never describe SMeeting concepts in prose with "channel", "join", or "leave" (API identifiers such as `force_join` keep their literal names).
> 同一能力在各端 SDK 里的包名、类名、方法名并不相同。写示例代码时请使用文档中该端自己的 API，不要把一个端的写法套到另一个端上。苹果平台每个产品都有两套 SDK（Swift 原生与 Objective-C），两套 API 不能混用。 Package, class, and method names differ between platform SDKs for the same capability. In sample code, use the API documented for that platform; never carry one platform's code over to another. On Apple platforms each product ships two SDKs (native Swift and Objective-C) whose APIs must not be mixed.

# IM messages

> Out-of-channel IM messages and IM device presence management

## Get an IM token

`POST /server/v1/im/grant`

Authentication: required (see [Overview](/en/rtc/server-api/overview))

Get an IM connection credential. The IM channel (out-of-channel messaging) is a message path separate from SRTC channels—users can send and receive even when they aren't in any channel,
suited to scenarios such as meeting invitation notifications, incoming calls, and offline reminders.

Typical flow: after a user logs in to your business, your backend calls this endpoint to get a token → sends it to the client →
the client uses it to connect to IM. After that you can push messages to them with "Send an IM message" and receive their online/offline callbacks
(im\_connect / im\_disconnect).

The same uid can connect from multiple devices at once, and each connection has its own sid—so "sending a message to a person"
and "sending a message to a device" are two different things; see "Send an IM message".

**Request parameters**

<ParamField body="uid" type="string" required>
  Third-party user ID (letters, digits, underscores (\_), and hyphens (-) only) (max length 100)
  Example: `1001`
</ParamField>

<ParamField body="net" type="string">
  Network line. The value is a Chinese line name determined by the deployment's network configuration; leave empty to let the server choose
  Example: `内网`
</ParamField>

<ParamField body="sg" type="string">
  Server group
</ParamField>

Request example:

```json theme={null}
{
  "net": "内网",
  "sg": "",
  "uid": "1001"
}
```

**Response parameters**

<ResponseField name="sid" type="string">
  ID of this IM session; each connection of the same uid on multiple devices has its own sid
</ResponseField>

<ResponseField name="token" type="string">
  IM connection credential, issued to the client to establish the IM long-lived connection
</ResponseField>

Response example:

```json theme={null}
{
  "code": 0,
  "data": {
    "sid": "",
    "token": ""
  }
}
```

***

## Send an IM message

`POST /server/v1/im/send-msg`

Authentication: required (see [Overview](/en/rtc/server-api/overview))

Push messages to specified users or devices through the IM channel; recipients don't need to be in any channel.

Choose one of the two recipient types: ruids sends by user, and every online device of that user receives it; rsids sends by session,
only to specific devices. When rsids is set, ruids is ignored; the two are not combined.

Messages are not persisted: important only guarantees resending during reconnection; it is not an offline message queue.
For messages to recipients who stay offline for a long time, you need a fallback on your own side.

**Request parameters**

<ParamField body="action" type="string" required>
  Message command, defined by you; the client dispatches on it
  Example: `meeting_invite`
</ParamField>

<ParamField body="content" type="any">
  Message body, any JSON; you define the structure
  Example: `&#123;"meeting_no": "818595664", "title": "Weekly project sync"&#125;`
</ParamField>

<ParamField body="uid" type="string">
  Sender user ID, used by the client to show "who sent it"; can be empty for system messages sent by the server (letters, digits, underscores (\_), and hyphens (-) only)
  Example: `1001`
</ParamField>

<ParamField body="sid" type="string">
  Sender session ID
</ParamField>

<ParamField body="name" type="string">
  Sender name
  Example: `Alice`
</ParamField>

<ParamField body="ruids" type="array<string>">
  List of recipient user IDs (ignored when Rsids is set)
  Example: `["1002","1003"]`
</ParamField>

<ParamField body="rsids" type="array<string>">
  List of recipient session IDs, for delivery to specific devices
</ParamField>

<ParamField body="important" type="boolean">
  Whether the message is important. Important messages are resent after reconnecting to make sure they arrive. Enable it for messages that must not be lost, such as invitations and calls; ordinary state sync doesn't need it
</ParamField>

Request example:

```json theme={null}
{
  "action": "meeting_invite",
  "content": "{\"meeting_no\": \"818595664\", \"title\": \"Weekly project sync\"}",
  "important": false,
  "name": "Alice",
  "rsids": [
    ""
  ],
  "ruids": [
    "1002",
    "1003"
  ],
  "sid": "",
  "uid": "1001"
}
```

**Response parameters**

`data` is null

Response example:

```json theme={null}
{
  "code": 0,
  "data": null
}
```

***

## Force an IM device offline

`POST /server/v1/im/kick-device`

Authentication: required (see [Overview](/en/rtc/server-api/overview))

Forcibly disconnect the IM connection of specified users or devices, typically to force an old device offline when the account logs in elsewhere.
The disconnected device receives a notification and the im\_disconnect callback is triggered.

This only disconnects the IM connection; it doesn't affect any channel call the user is already in, and it doesn't prevent them from reconnecting—
to block reconnection, stop issuing IM tokens on your side.

**Request parameters**

<ParamField body="uid" type="string">
  Operator user ID, used for auditing (letters, digits, underscores (\_), and hyphens (-) only)
  Example: `1001`
</ParamField>

<ParamField body="ruids" type="array<string>">
  List of user IDs to force offline; this disconnects all of their devices (ignored when Rsids is set)
  Example: `["1002"]`
</ParamField>

<ParamField body="rsids" type="array<string>">
  List of session IDs to force offline; this disconnects only those devices
</ParamField>

Request example:

```json theme={null}
{
  "rsids": [
    ""
  ],
  "ruids": [
    "1002"
  ],
  "uid": "1001"
}
```

**Response parameters**

`data` is null

Response example:

```json theme={null}
{
  "code": 0,
  "data": null
}
```

***

## Get users' online devices

`POST /server/v1/im/user-device-list`

Authentication: required (see [Overview](/en/rtc/server-api/overview))

Query users' current online IM devices in bulk, to decide "can this person receive a push right now"
or to show multi-device online status.

The data in the response maps "user ID → device list"; users who are offline don't appear in the result.
Each device has its own sid and device\_type, which you can use to send messages to or disconnect a specific device.

**Request parameters**

<ParamField body="uids" type="array<string>" required>
  List of user IDs
  Example: `["1001","1002"]`
</ParamField>

Request example:

```json theme={null}
{
  "uids": [
    "1001",
    "1002"
  ]
}
```

**Response parameters**

<ResponseField name="<key>" type="array<object>">
  Keys are dynamic; see the description above

  <Expandable title="Element fields">
    <ResponseField name="uid" type="string">
      User ID
    </ResponseField>

    <ResponseField name="sid" type="string">
      Session ID
    </ResponseField>

    <ResponseField name="device_type" type="integer">
      Device type
    </ResponseField>

    <ResponseField name="device_id" type="string">
      Unique device ID
    </ResponseField>
  </Expandable>
</ResponseField>

Response example:

```json theme={null}
{
  "code": 0,
  "data": {}
}
```

***
