> ## 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.

# Overview

> Basics of the SRTC Server API: channel lifecycle and naming rules, base URL, request headers, the HMAC-SHA256 signing algorithm, uid and sid, and the response format. Read this before calling any SRTC server endpoint.

The server API is called by your backend (see the reference backend implementation).

### Basic concepts

**Channel**: A channel is an audio and video space (think of it as a meeting). Users in the same channel can receive each other's real-time audio and video.

#### Joining a channel

1. Your client calls your backend's endpoint for joining a channel
2. Your backend calls `channel/grant` of the `server API` to get a token and returns it to your client
3. Your client passes the `token` to the RTC SDK to join the channel

#### Opening and destroying a channel

* A channel can be opened manually (for example, when you need to set some channel properties in advance)
* If the channel is not open when the first user joins, it opens automatically
* A channel is destroyed automatically if no one joins within 2 hours after it opens, or 2 hours after the last user leaves

#### Channel name rules

A string of up to 64 bytes. The supported character set is:

* The 26 lowercase letters a-z.
* The 26 uppercase letters A-Z.
* The 10 digits 0-9.
* "-", "\_".

### Conventions

* This protocol uses HTTP + JSON for transport (`application/json`)
* All endpoints of the protocol support `POST` only
* Strings are encoded in UTF-8

### Base URL

```text theme={null}
https://<your-domain>/server/v1/...
```

<Note>
  In a standard deployment, SRTC is served at the domain root. The `/meeting/` prefix on the same domain goes to the SMeeting service,
  and the two sets of endpoints are not interchangeable (see [Choosing SRTC or SMeeting](/en/choose)). For deployments on a dedicated domain, follow the access information we provide.
</Note>

### Prerequisites

You need an `app_id` and an `app_key` before making calls

### Request headers

| Header | Description | Notes |
| - | - | - |
| app\_id | App ID | Required. `app-id` or `appid` is also accepted, for languages or gateways that don't support underscores |
| nonce | Unique request ID, prevents duplicate submission | Required, a random 16-character string |
| timestamp | Unix timestamp in seconds | Required, the client's local timestamp, accurate to the second.<br />The client's local time must be within 5 minutes of the server's time; otherwise the server rejects the request. |
| signature | Signature value | Required. Computed with HMAC-SHA256, using the app\_key issued by the server as the key, over the request data other than signature. |

#### Signing algorithm

Step 1: Build the string to sign by joining `app_id`, `nonce`, `timestamp`, and the JSON string of the request body with &

```typescript theme={null}
// Assume app_id=1 nonce=2 timestamp=3 and the request body is {}
app_id=1&nonce=2&timestamp=3&{}
```

Step 2: Compute HMAC-SHA256 over the string. The key is the `app_key` secret key.

```typescript theme={null}
HMACSHA256(key, stringToSign)
```

Step 3: Convert the binary result to lowercase hexadecimal to get the `signature`

Three details that are easy to get wrong:

* The field names in the string to sign must match the **request header names you actually use**—if you use `app-id`, write `app-id=`, not `app_id=`
* Sign the request body as the **raw string**. It must be byte-for-byte identical to what you send (including whitespace and field order); don't serialize it again
* `app_key` is only used to compute the signature locally on your server. It **must never appear in a request or be sent to a client**

### uid and sid

* `uid` is the user ID from your own system. You assign it; the RTC side does not generate it
* `sid` is the ID of this session. The RTC side generates it when issuing the grant, and the same `uid` gets a different `sid` each time it joins

### Callbacks

Besides the endpoints you call, the RTC side also calls back your backend when the state of a channel, user, or recording changes.
See the [Callback events guide](/en/rtc/server-api/guides/callbacks).

### Response format

Both success and failure return HTTP 200. The business result is determined by `code`.

On success, `code` is 0 and `data` contains the data

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

On error, `code` is the error code and `msg` is the error description

```json theme={null}
{
    "code": 1003,
    "msg": "请求头中的signature无效"
}
```

The `msg` above means "Invalid signature in request headers". **Check `code`**; don't match on the `msg` text. For all values, see [Error codes](/en/rtc/server-api/error-codes).
