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

# Types

> Public types of the SMeeting Swift SDK: request parameters such as MeetingCreateReq and MeetingEnterReq, RoomInfo / MeetingUserInfo / MeetingInfo, pagination, event data types, all enums with raw values, and audio routing and call quality types from SRTC. Read when you need a field or enum.

This page lists the types the SDK exposes publicly. All field names are given as Swift property names.

***

### Request parameters

#### MeetingCreateReq

Parameters for creating / updating a meeting. To construct:

```swift theme={null}
var req = MeetingCreateReq(title: "Weekly project sync", meetingMode: .normal)
req.meetingType = .appointment
req.planTime = Int(Date().timeIntervalSince1970) + 1800
req.planDur = 60
```

| Field | Type | Description |
| - | - | - |
| `title` | `String` | Meeting title (required when constructing) |
| `meetingMode` | `MeetingMode` | Meeting mode (required when constructing) |
| `roomNo` | `String?` | Custom room number; generated by the server if omitted |
| `content` | `String?` | Meeting description |
| `meetingType` | `MeetingType?` | Meeting type; treated as an instant meeting if omitted |
| `planTime` | `Int?` | Scheduled start time, timestamp in seconds |
| `planDur` | `Int?` | Meeting duration, in minutes |
| `attendType` | `AttendType?` | Entry restriction type |
| `password` | `String?` | Meeting password; required for password-protected entry |
| `conferee` | `[String]?` | Invitee IDs; required only for invitation-only entry |
| `coHosts` | `[String]?` | Co-host IDs |
| `maximum` | `Int?` | Maximum number of members |
| `endType` | `EndType?` | How the meeting ends |
| `entryMutePolicy` | `EntryMutePolicy?` | Mute-on-entry policy |
| `watermarkDisabled` | `Bool?` | Whether to turn off the watermark |
| `screenshotDisabled` | `Bool?` | Whether to prevent screenshots |
| `chatDisabled` | `Bool?` | Whether to disable chat for everyone |
| `waitingRoomDisabled` | `Bool?` | Whether to turn off the waiting room |
| `enterBeforeHostDisabled` | `Bool?` | Whether to prevent entering before the host |
| `autoRecord` | `Bool?` | Whether to record automatically |
| `layoutData` | `LayoutData?` | Composite layout |
| `background` | `String?` | Resource key of the background image |
| `attachments` | `[Attachment]?` | Meeting materials |
| `extendInfo` | `String?` | Business extension field; a JSON string is recommended |

#### MeetingEnterReq

Parameters for entering a meeting. To construct:

```swift theme={null}
var req = MeetingEnterReq(nickname: "Alice", roomNo: "10000001")
req.password = "123456"
```

| Field | Type | Description |
| - | - | - |
| `nickname` | `String` | In-meeting display name (required when constructing) |
| `meetingId` | `String?` | Meeting ID; provide either this or `roomNo` |
| `roomNo` | `String?` | Room number; provide either this or `meetingId` |
| `password` | `String?` | Meeting password |
| `avatar` | `String?` | In-meeting avatar |
| `streamVendor` | `MeetingStreamVendor?` | Media streaming vendor; follows the server configuration if omitted |
| `extendInfo` | `String?` | Business extension field |

#### PageParam

```swift theme={null}
let page = PageParam(page: 1, perPage: 20)
```

| Field | Type | Description |
| - | - | - |
| `page` | `Int` | Page number; defaults to `1` |
| `perPage` | `Int` | Items per page; defaults to `20` |

#### ResourceListReq

```swift theme={null}
var req = ResourceListReq(page: 1, perPage: 20)
req.meetingId = meetingId
```

| Field | Type | Description |
| - | - | - |
| `page` / `perPage` | `Int` | Pagination |
| `parentId` | `String?` | Parent folder ID |
| `meetingId` | `String?` | Meeting ID |
| `resName` | `String?` | Filter by resource name |
| `resType` | `String?` | Filter by resource type |

#### ResourceCreateReq

```swift theme={null}
var req = ResourceCreateReq(resName: "Meeting materials.pdf", resType: "pdf")
req.resKey = key
```

| Field | Type | Description |
| - | - | - |
| `resName` | `String` | Resource name (required when constructing) |
| `resType` | `String` | Resource type (required when constructing) |
| `resKey` | `String?` | Resource key, from `presignedPutObject` |
| `meetingId` | `String?` | The meeting it belongs to |
| `parentId` | `String?` | Parent folder ID |

#### Layout and recording parameters

`McuStartReq`, `LayoutData`, `Watermark`, `Tag`, `Cell`, `DivList`, and `Attachment` all provide initializers whose optional parameters have default values; they're also `Codable`, so you can decode them from JSON delivered by your backend with `JSONDecoder`. For the mapping between fields and JSON keys, see [Recording and composite layout](/en/meeting/swift/advanced/recording).

***

### Meeting and member info

#### RoomInfo

Room info of the current meeting, returned by `getRoomInfo()`.

| Field | Type | Description |
| - | - | - |
| `id` | `String` | Meeting ID |
| `roomNo` | `String` | Room number |
| `parent` | `String` | Meeting ID of the main meeting (only set for sub-meetings) |
| `title` | `String` | Meeting title |
| `content` | `String` | Meeting description |
| `meetingType` | `MeetingType` | Meeting type |
| `meetingMode` | `MeetingMode` | Meeting mode |
| `planTime` / `planDur` | `Int` | Scheduled start time (timestamp in seconds) / duration (minutes) |
| `entryMutePolicy` | `EntryMutePolicy` | Mute-on-entry policy |
| `micDisabled` | `Bool` | Mute all |
| `selfUnmuteMicDisabled` | `Bool` | Members can't unmute themselves |
| `cameraDisabled` | `Bool` | Camera off for everyone |
| `selfUnmuteCameraDisabled` | `Bool` | Members can't turn their cameras back on themselves |
| `shareDisabled` | `Bool` | Sharing disabled |
| `chatDisabled` | `Bool` | Chat disabled for everyone |
| `screenshotDisabled` | `Bool` | Screenshots disabled |
| `watermarkDisabled` | `Bool` | Watermark turned off |
| `waitingRoomDisabled` | `Bool` | Waiting room turned off |
| `enterBeforeHostDisabled` | `Bool` | Entering before the host is disabled |
| `locked` | `Bool` | The meeting is locked |
| `password` | `String` | Meeting password |
| `shareState` | `Int` | Current sharing: `0` none, `1` screen, `2` whiteboard |
| `shareUid` | `String` | Current sharer |
| `recordStatus` | `Int` | Recording status |
| `creator` | `String` | Creator |
| `hostUid` | `String` | Host |
| `coHosts` | `[String]` | Co-hosts |
| `appId` | `String` | App ID |
| `extendInfo` | `String` | Business extension field |

#### MeetingUserInfo

In-meeting member info, returned by `getUserInfo(_:)` / `getUsersInfo()` / `getUsersInfoList()`.

| Field | Type | Description |
| - | - | - |
| `uid` | `String` | Member ID |
| `name` | `String` | In-meeting display name |
| `avatar` | `String` | In-meeting avatar |
| `role` | `Role` | In-meeting role |
| `micState` | `MicState` | Microphone state |
| `cameraState` | `CameraState` | Camera state |
| `shareState` | `Int` | Sharing state: `0` none, `1` screen, `2` whiteboard |
| `chatDisabled` | `Bool` | Whether chat is disabled for this member individually |
| `drawDisabled` | `Bool` | Whether the member is prevented from drawing |
| `isKickout` | `Bool` | Whether the member has been removed |
| `trackDescs` | `[String]` | List of descriptions of the tracks currently published |
| `deviceType` | `String` | Device type |
| `deviceId` | `String` | Device ID |
| `version` | `String` | Client SDK version |
| `joinAt` | `Int` | Time of entering the meeting |
| `extendInfo` | `String` | Business extension field |

#### MeetingInfo

Meeting details, returned by `detailRoom(...)`, `attendeeRoom(...)`, and `attendedRoom(...)`.

| Field | Type | Description |
| - | - | - |
| `id` | `String` | Meeting ID |
| `title` | `String` | Meeting title |
| `roomNo` | `String` | Room number |
| `meetingType` | `MeetingType` | Meeting type |
| `meetingMode` | `MeetingMode` | Meeting mode |
| `meetingStatus` | `MeetingStatus` | Meeting status |
| `attendType` | `AttendType` | Entry restriction type |
| `password` | `String` | Meeting password |
| `conferee` | `[String]` | Invitees |
| `coHosts` | `[String]?` | Co-hosts |
| `creator` | `String` | Creator |
| `maximum` | `Int?` | Maximum number of members |
| `endType` | `EndType?` | How the meeting ends |
| `autoRecord` | `Bool` | Whether to record automatically |
| `layoutData` | `LayoutData?` | Composite layout |
| `watermarkDisabled` / `screenshotDisabled` / `chatDisabled` | `Bool` | The corresponding switches |
| `waitingRoomDisabled` / `enterBeforeHostDisabled` | `Bool` | The corresponding switches |
| `planTime` / `planDur` | `Int` | Scheduled start time / duration |
| `beginTime` / `endTime` | `Int` | Actual start / end time |
| `createdAt` | `Int` | Creation time |
| `extendInfo` | `String` | Business extension field |

#### ParticipantInfo

Attendance record, returned by `roomParticipant(...)`.

| Field | Type | Description |
| - | - | - |
| `id` | `String` | Record ID |
| `userId` | `String` | Member ID |
| `nickname` | `String` | In-meeting display name |
| `enterAt` / `exitAt` | `Int` | Enter / exit time |

#### OnlineMemberInfo

An online member, returned by `adminListOnlineMember(...)`: `userId`, `nickname`, `deviceType`, `joinAt`.

#### NoEnterUserInfo

An invitee who hasn't entered the meeting, returned by `meetNotEnter()`: `id`, `nickname`, `mobile`, `avatar`, `role`, `relUid`.

#### WaitingRoomUserInfo

A member in the waiting room, returned by `adminWaitingRoomUsers()`: `userId`, `name`, `avatar`, `at`.

#### SubMeetingInfo / SubMeetingUser

Sub-meeting info, returned by `adminSubMeetingList(...)`.

| Field | Type | Description |
| - | - | - |
| `id` | `String` | Sub-meeting ID, used by the APIs that arrange sub-meetings |
| `mainMeetingId` | `String` | Main meeting ID |
| `meetingId` | `String` | The sub-meeting's own meeting ID, used to enter the sub-meeting |
| `title` | `String` | Sub-meeting title |
| `users` | `[SubMeetingUser]` | Assigned members; each item contains `uid` and `name` |
| `status` | `MeetingStatus` | Sub-meeting status |

#### AgentInfo

A device that can be invited, returned by `agentList(...)`: `id`, `name`, `type` (`AgentType`), `status` (`AgentStatus`), `contact`, `remark`.

#### ResourceInfo

A resource, returned by `resourcesList(...)`.

| Field | Type | Description |
| - | - | - |
| `id` | `String` | Resource ID |
| `isFolder` | `Bool` | Whether it's a folder |
| `parentId` | `String` | Parent folder ID |
| `resName` / `resType` / `resKey` / `resSize` | `String` / `String` / `String` / `Int` | Name, type, storage key, size |
| `userId` / `meetingId` | `String` | The user / meeting it belongs to |
| `createdAt` / `updatedAt` | `String` | Creation / update time |

#### SignInfo / SignDetailInfo

Sign-in activities and sign-in details.

| Type | Fields |
| - | - |
| `SignInfo` | `uid`, `beginAt`, `dur`, `endAt`, `desc`, `nums` |
| `SignDetailInfo` | `id`, `epoch`, `nickname`, `role`, `userId`, `createdAt` |

#### McuRecordConfig / McuRecordDetail

| Type | Fields |
| - | - |
| `McuRecordConfig` | `appId`, `layout`, `watermarkType`, `windowTagType`, `createdAt`, `updatedAt` |
| `McuRecordDetail` | `id`, `opUid`, `opName`, `channel`, `title`, `roomNo`, `taskStatus`, `errDesc`, `vodKey`, `vodSize`, `mcuAt`, `mcuDur`, `tags`, `createdAt`, `updatedAt` |

#### MeetingToken

The parsed contents of the login token. You usually don't need it—the token is issued by your backend, and you just pass it to `login(token:)`. If you need to check on the client in advance whether the token has expired, you can:

```swift theme={null}
let info = try MeetingToken.decode(from: token)
if info.isExpired { /* Get a new one from your backend */ }
```

| Field | Type | Description |
| - | - | - |
| `appId` | `String` | App ID |
| `userId` | `String` | User ID |
| `nickname` | `String` | Nickname |
| `expAt` | `Int` | Expiration time, timestamp in seconds |
| `isExpired` | `Bool` | Whether it has expired |

***

### Pagination

#### PageResult

```swift theme={null}
let result = try await meeting.attendeeRoom()
result.data      // [MeetingInfo]
result.meta      // MetaRes
```

| Field | Type | Description |
| - | - | - |
| `data` | `[T]` | List of data |
| `meta` | `MetaRes` | Pagination info |

`MetaRes`: `totalCount`, `pageCount`, `currentPage`, `perPage`.

***

### Event data types

#### Connection and members

| Type | Fields |
| - | - |
| `DisconnectEventData` | `reason: DisconnectReason`, `error: Error?` |
| `UserExitEventData` | `uid`, `reason: DisconnectReason` |
| `UserCameraStateChangeEventData` | `uid`, `cameraState`, `byAdmin`, `opUid` |
| `UserMicStateChangeEventData` | `uid`, `micState`, `byAdmin`, `opUid` |
| `UserNameChangeEventData` | `uid`, `nickname`, `byAdmin`, `opUid` |
| `UserRoleChangeEventData` | `uid`, `role`, `opUid` |
| `UserChatDisabledChangeEventData` | `uid`, `chatDisabled`, `opUid` |
| `UserDrawDisabledChangeEventData` | `uid`, `drawDisabled`, `opUid` |
| `UserHandupEventData` | `uid`, `type: HandupType`, `step: UserHandupStep` |

#### Room state

| Type | Fields |
| - | - |
| `RoomMicStateChangeEventData` | `micDisabled`, `selfUnmuteMicDisabled`, `opUid` |
| `RoomCameraStateChangeEventData` | `cameraDisabled`, `selfUnmuteCameraDisabled`, `opUid` |
| `RoomShareStateChangeEventData` | `shareDisabled`, `opUid` |
| `RoomChatDisabledChangeEventData` | `chatDisabled`, `opUid` |
| `RoomScreenshotDisabledChangeEventData` | `screenshotDisabled`, `opUid` |
| `RoomWatermarkDisabledChangeEventData` | `watermarkDisabled`, `opUid` |
| `RoomLockedChangeEventData` | `locked`, `opUid` |
| `RoomTitleChangeEventData` | `title`, `previousTitle` (**no `opUid`**; see [Events](/en/meeting/swift/events)) |
| `RoomShareStartEventData` | `uid`, `shareType: ShareType` |
| `RoomShareStopEventData` | `uid`, `shareType`, `byAdmin`, `opUid` |
| `ShareBroadcastStartEventData` | `uid` (iOS full-screen sharing only, the sharer's own side) |
| `ShareBroadcastStopEventData` | `uid`, `reason` (the reason it ended, from the extension or the system) |
| `RoomMcuTaskEventData` | `taskType: McuTaskType`, `taskStatus: McuTaskStatus`, `errDesc` |
| `RoomJoinFailedEventData` | `uid`, `name`, `errDesc`, `failedType` |

#### Messages

| Type | Fields |
| - | - |
| `RoomChatMsgEventData` | `msgType: ChatMsgType`, `msg`, `uid: String?`, `isPrivate` |
| `RoomCustomMsgEventData` | `msg`, `uid: String?`, `isPrivate` |

#### Host commands and raise hand

| Type | Fields |
| - | - |
| `AdminConfirmHandupEventData` | `type: HandupType`, `approve`, `opUid`, `targetId` |
| `AdminRequestOpenMicEventData` | `opUid` |
| `AdminRequestOpenCameraEventData` | `opUid` |

#### Waiting room and sub-meetings

| Type | Fields |
| - | - |
| `UserEnterWaitingRoomEventData` | `uid`, `name`, `avatar` |
| `UserExitWaitingRoomEventData` | `uid`, `name`, `avatar` |
| `AdminUpdateWaitingRoomDisabledEventData` | `waitingRoomDisabled`, `opUid` |
| `AdminStartSubMeetingEventData` | `meetingId`, `title`, `uids` |
| `AdminStopSubMeetingEventData` | `parent` |
| `AdminMoveSubMeetingUserEventData` | `fromMeetingId`, `fromMeetingTitle`, `toMeetingId`, `toMeetingTitle` |

#### Sign-in, roll call, and devices

| Type | Fields |
| - | - |
| `SignInActivityEventData` | `hostId`, `hostName`, `epoch`, `beginAt`, `dur`, `endAt`, `desc` |
| `SignInFinishEventData` | `hostId`, `hostName`, `epoch` |
| `RollCallNamedEventData` | `id` (the roll call record identifier, sent back when answering), `sid` (uid of the host who started the roll call), `time` |
| `DeviceChangeEventData` | `device: DeviceInfo` |
| `AudioRouteChangeEventData` | `route: AudioRoute`, `previousRoute: AudioRoute`, `reason: AVAudioSession.RouteChangeReason` (iOS only) |

#### Out-of-meeting messages

All out-of-meeting message event data consists of two parts: `base` and `content`.

| Type | Fields |
| - | - |
| `ImBaseEventData` | `sid`, `uid`, `name`, `avatar: String?` |
| `ImCallCallingEventData` | `base`, `content: ImCallContent` (`roomNo`, `meetingId`, `title`) |
| `ImMeetingRemindEventData` | `base`, `content: ImMeetingRemindContent` (`roomNo`, `meetingId`, `title`, `creatorName`, `planDur`, `planTime`) |
| `ImAdminMoveOutWaitingRoomEventData` | `base`, `content: ImMoveOutWaitingRoomContent` (`parent`, `meetingId`, `title`) |
| `ImUserHelpSubMeetingEventData` | `base`, `content: ImHelpSubMeetingContent` (`parent`, `meetingId`, `title`) |
| `ImDisconnectEventData` | `reason: String?` |

***

### Enums

#### TrackDesc

| Enum value | Raw value | Description |
| - | - | - |
| `mic` | `mic` | Microphone audio |
| `cameraBig` | `camera_big` | Camera high stream |
| `cameraSmall` | `camera_small` | Camera low stream |
| `screen` | `screen` | Screen sharing |

#### Role

| Enum value | Raw value | Description |
| - | - | - |
| `member` | `0` | Regular member |
| `host` | `1` | Host |
| `coHost` | `2` | Co-host |

#### MicState / CameraState

| Enum value | Raw value | Description |
| - | - | - |
| `on` | `1` | On |
| `off` | `2` | Off |

#### ShareType

| Enum value | Raw value | Description |
| - | - | - |
| `screen` | `1` | Screen sharing |
| `whiteBoard` | `2` | Whiteboard |

#### HandupType

| Enum value | Raw value | Description |
| - | - | - |
| `mic` | `1` | Request to turn on the microphone |
| `camera` | `2` | Request to turn on the camera |
| `chat` | `3` | Request to chat |
| `share` | `4` | Request to share |

#### UserHandupStep

| Enum value | Raw value | Description |
| - | - | - |
| `request` | `1` | Raise hand |
| `cancel` | `2` | Lower hand |
| `confirmOpen` | `3` | Confirm turning on the device |
| `rejectOpen` | `4` | Reject turning on the device |

#### ChatMsgType

| Enum value | Raw value | Description |
| - | - | - |
| `text` | `1` | Text |
| `file` | `2` | File |
| `pic` | `3` | Image |
| `sound` | `4` | Voice |

#### MeetingType

| Enum value | Raw value | Description |
| - | - | - |
| `instant` | `1` | Instant meeting |
| `appointment` | `2` | Scheduled meeting |

#### MeetingMode

| Enum value | Raw value | Description |
| - | - | - |
| `normal` | `1` | Normal mode (not composite) |
| `mix` | `2` | Composite mode |
| `voice` | `3` | Voice meeting |
| `training` | `4` | Training meeting |
| `subMeeting` | `5` | Sub-meeting |

#### MeetingStatus

| Enum value | Raw value | Description |
| - | - | - |
| `unStart` | `1` | Not started |
| `running` | `2` | In progress |
| `end` | `3` | Ended |

#### AttendType

| Enum value | Raw value | Description |
| - | - | - |
| `unLimit` | `1` | No restriction |
| `password` | `2` | Enter with a password |
| `invite` | `3` | Invitees only |
| `passwordAndInvite` | `4` | Password + invitees only |

#### EndType

| Enum value | Raw value | Description |
| - | - | - |
| `normal` | `0` | Normal (delayed) end |
| `force` | `1` | Forced end |

#### EntryMutePolicy

| Enum value | Raw value | Description |
| - | - | - |
| `silent` | `1` | Everyone is muted by default on entry |
| `unRestrict` | `2` | No restriction; follows the client's initial audio state |
| `silentAfter6` | `3` | Muted by default on entry once there are more than 6 people |

#### MeetingStreamVendor

| Enum value | Raw value |
| - | - |
| `ook` | `ook` |
| `seastart` | `seastart` |
| `wangsuCDN` | `wangsucdn` |

`ook` has been retired along with the server (2026-08) and is kept only for compatibility with existing deployments; don't use it for new integrations.

If you're not sure which one to use, don't pass it, and let the server decide based on the deployment configuration.

#### UserType

| Enum value | Raw value | Description |
| - | - | - |
| `normal` | `1` | Regular user |
| `sip` | `2` | SIP user |
| `h323` | `3` | H.323 user |

#### McuTaskType

| Enum value | Raw value | Description |
| - | - | - |
| `record` | `1` | Recording mode |
| `mix` | `2` | Stream mixing mode |
| `mixAndRecord` | `3` | Stream mixing and recording |

#### McuTaskStatus

| Enum value | Raw value | Description |
| - | - | - |
| `running` | `1` | In progress |
| `exception` | `2` | Ended abnormally |
| `normal` | `3` | Ended normally |

#### LayoutType

| Enum value | Raw value | Description |
| - | - | - |
| `auto` | `auto` | Automatic layout |
| `full` | `full` | Full screen |
| `grids2` | `grids_2` | Split in two |
| `grids3` | `grids_3` | Three tiles in a triangle (two on top, one centered below) |
| `grids4` | `grids_4` | 4-tile grid |
| `grids5` | `grids_5` | 5-tile grid |
| `grids6` | `grids_6` | 6-tile grid |
| `grids8` | `grids_8` | 8-tile grid |
| `grids9` | `grids_9` | 9-tile grid |
| `grids10` | `grids_10` | 10-tile grid |
| `grids12` | `grids_12` | 12-tile grid |
| `grids16` | `grids_16` | 16-tile grid |
| `grids20` | `grids_20` | 20-tile grid |
| `grids25` | `grids_25` | 25-tile grid |
| `right4` | `right_4` | Small windows on the right |
| `top4` | `top_4` | Small windows on top |
| `br7` | `br_7` | Bottom L-shaped layout |
| `tl7` | `tl_7` | Top L-shaped layout |
| `tb8` | `tb_8` | Side-by-side layout (four small tiles each on top and bottom, two large tiles side by side in the middle) |

#### AgentType

| Enum value | Raw value | Description |
| - | - | - |
| `sip` | `2` | SIP |
| `h323` | `3` | H.323 |
| `gb28181` | `4` | GB28181 |
| `rtsp` | `5` | RTSP stream pulling |
| `rtmp` | `6` | RTMP stream pulling |
| `filePlay` | `7` | File playback |
| `tencentMeet` | `8` | Tencent Meeting |
| `ai` | `9` | AI |

#### AgentStatus

| Enum value | Raw value | Description |
| - | - | - |
| `idle` | `1` | Idle |
| `busy` | `2` | Busy |
| `offline` | `3` | Offline |

#### PresignedPutObjectType

| Enum value | Raw value | Description |
| - | - | - |
| `attach` | `attach` | Meeting attachment |
| `background` | `background` | Background image |
| `user` | `user` | User resource |

***

### Types from SRTC

The following types are defined in the underlying SRTC module and require `import SRTC` to use: `LogLevel`, `CameraPreset`, `MicPreset`, `ScreenPreset`, `DeviceInfo`, `DisconnectReason`, `SRTCVideoView`, `SRTCVideoRenderer`, `ScreenCaptureSources`, `DisplaySource`, `WindowSource`, `LocalCameraTrack`, `LocalScreenTrack`, `RemoteVideoTrack`, `Track`, `SRTCBroadcastPicker`.

`NativeVideoView` is an alias SMeeting defines for the render view; its actual type is `SRTCVideoRenderer`.

#### Audio routing (iOS)

| Type | Description |
| - | - |
| `AudioRoute` | The system's actual output route, **read-only with five states**: `unknown` / `speaker` (speakerphone) / `receiver` (earpiece) / `bluetooth` / `headset`. Also has `displayName`, `isBuiltIn`, and `isExternal` |
| `AudioRouteTarget` | The target you can actively switch to, **with only two states**: `speaker` / `earpiece` |
| `AudioRouteInfo` | A port snapshot (for diagnostics): `id`, `route`, `name`, `isActive` |
| `AudioCallState` | System call state: `unknown` / `dialing` / `incoming` / `connected` / `disconnected` |

For why there are only two switchable states, see [Audio routing](/en/meeting/swift/advanced/audio-routing).

#### Call quality

| Type | Fields |
| - | - |
| `ConnectionQuality` | Quality level: `unknown` / `excellent` / `good` / `poor` / `lost` |
| `QualitySample` | `level`, `score` (0–100), `mos` (1.0–4.5), `loss` (0–1), `rtt`, `jitter` (ms), `packets`, `bitrate` (kbps), `bytes` |
| `QualityReport` | `ts` (Unix milliseconds), `pub: QualitySample` (uplink), `sub: QualitySample` (downlink) |
| `QualityEvaluation` | `uplink`, `downlink`, `overall` (the worse tier), `mos` (the smaller of uplink and downlink), `timestamp` |
| `ConnectionQualityChange` | `evaluation: QualityEvaluation`, `previous: ConnectionQuality` (`unknown` on the first tier change) |
| `ActiveSpeakerInfo` | `uid`, `trackId`, `level` (volume normalized to 0–1) |
| `ActiveSpeakersSnapshot` | `ts`, `speakers: [ActiveSpeakerInfo]` (already sorted by volume in descending order; empty when no one is speaking) |
| `LayerSwitchedInfo` | `subKey`, `fromTrackId`, `toTrackId`, `reason` (such as `bwe_down` / `bwe_up`), `latencyMs` |

For value ranges and usage of the fields, see [SRTC · Call quality and active speakers](/en/rtc/swift/advanced/call-quality).

#### Receive stream status

| Type | Fields |
| - | - |
| `ReceiveStreamStatus` | `uid` (the member publishing the stream), `trackId`, `trackDesc` (`camera` / `screen`, etc.), `timedOut` (`true` timed out, `false` recovered) |

Delivered by `meeting(_:didChangeReceiveStreamStatus:)`, it determines per track whether a video track is still producing frames, which is a different matter from the quality tier of the whole connection; see [Events](/en/meeting/swift/events).

***

### Related pages

* [Events](/en/meeting/swift/events)
* [Error handling](/en/meeting/swift/error-codes)
