Skip to main content

Create Room

Create rooms for interactive livestreaming with co-hosting capabilities, configure participants, and obtain broadcaster credentials for streaming.

Creating a Room

Basic Co-Hosts Room

Create a room for collaborative broadcasting with multiple participants:
Task { @MainActor in
    do {
        let room = try await AmityRoomRepository.shared.createRoom(
            title: "Product Launch Event",
            description: "Join us for the unveiling of our latest features",
            thumbnailFileId: nil,
            metadata: nil,
            channelEnabled: true,
            parentRoomId: nil
        )
        print("Room created: \(room.roomId)")
        print("Status: \(room.status)")
    } catch {
        print("Failed to create room: \(error)")
    }
}

Room with Live Chat Channel

To enable live chat for viewer interaction, you must create a live channel after creating the room and livestream post. The channel requires both the postId and roomId to be properly linked.
Channels are not automatically created. You must manually create the channel after the post is created, passing both the postId and roomId.
// 1. First create the room
let room = try await AmityRoomRepository.shared.createRoom(
    title: "Weekly Q&A Session",
    description: "Ask us anything about our product",
    thumbnailFileId: nil,
    metadata: ["category": "education"],
    channelEnabled: true,
    parentRoomId: nil
)

// 2. Create the livestream post
let post = try await AmityPostRepository.shared.createLiveStreamPost(
    targetType: .community,
    targetId: communityId,
    roomId: room.roomId,
    text: "Join our Q&A session!",
    title: room.title,
    metadata: nil,
    mentionUserIds: nil,
    hashtags: nil
)

// 3. Create the live chat channel with postId and roomId
let channelRepository = AmityChatClient.shared.channelRepository
let channel = try await channelRepository.createChannel(room.title)
    .live()
    .postId(postId: post.postId)
    .roomId(roomId: room.roomId)
    .build()
    .create()

print("Live chat channel created: \(channel.channelId)")

Room with Thumbnail

Upload and attach a thumbnail image:
// First upload the thumbnail
let thumbnailData = UIImage(named: "room-cover")?.jpegData(compressionQuality: 0.8)
let thumbnailFile = try await AmityFileRepository.shared.uploadImage(thumbnailData!)

// Create room with thumbnail
let room = try await AmityRoomRepository.shared.createRoom(
    title: "Community Livestream",
    description: "Join our weekly community gathering",
    thumbnailFileId: thumbnailFile.fileId,
    metadata: nil,
    channelEnabled: true,
    parentRoomId: nil
)

Parameters

Type: string
Required: Yes
Description: Room title/name
Guidelines:
  • Clear and descriptive
  • Indicates content or purpose
  • Recommended max: 100 characters
Example:
title: "Product Roadmap Discussion"
Type: string
Required: No
Description: Detailed room description
Guidelines:
  • Provide context about the stream
  • Mention topics to be covered
  • Include any prerequisites
Example:
description: "Join us as we discuss upcoming features and answer your questions"
Type: string
Required: No
Description: File ID of uploaded thumbnail
Usage:
  1. Upload image using FileRepository
  2. Use returned fileId in room creation
Example:
thumbnailFileId: "file-abc123"
Type: object
Required: No
Description: Custom metadata for the room
Use Cases:
  • Store custom properties
  • Link to external systems
  • Track categories or tags
Example:
metadata: {
  category: "education",
  language: "en",
  eventId: "event-123"
}
Type: boolean
Required: No
Default: false
Description: Indicates the room supports integrated chat
Behavior:
  • When true, signals that the room supports live chat
  • You must manually create the live channel after creating the post
  • Use postId and roomId when creating the channel
  • See Room with Live Chat Channel for full workflow
Example:
channelEnabled: true
Type: string
Required: No
Description: ID of parent room for hierarchical relationships
Use Cases:
  • Breakout sessions
  • Multi-language streams
  • Regional broadcasts
Example:
parentRoomId: "room-main-session"

Getting Broadcaster Data

After creating a room, obtain streaming credentials:
Task { @MainActor in
    do {
        let broadcasterData = try await AmityRoomRepository.shared.getBroadcastData(
            roomId: room.roomId
        )
        
        // Handle broadcaster data
        if case .coHosts(let token, let url) = broadcasterData {
            print("Co-host token: \(token)")
            print("Co-host URL: \(url)")
            // Use LiveKit SDK with these credentials
        }
    } catch {
        print("Failed to get broadcaster data: \(error)")
    }
}
Broadcaster Credentials: The broadcast data contains credentials needed to start streaming. Use LiveKit SDK with the coHostToken and coHostUrl to connect to the streaming server.

Creating Livestream Post

Link the room to a post for social distribution:
Task { @MainActor in
    do {
        let post = try await AmityPostRepository.shared.createLiveStreamPost(
            targetType: .community,
            targetId: "community-123",
            roomId: room.roomId,
            text: "Join us for today's live session!",
            title: room.title,
            metadata: nil,
            mentionUserIds: nil,
            hashtags: nil
        )
        print("Livestream post created: \(post.postId)")
    } catch {
        print("Failed to create post: \(error)")
    }
}

Complete Workflow Example

Full room creation, post, channel, and streaming setup:
Task { @MainActor in
    do {
        // 1. Create room
        let room = try await AmityRoomRepository.shared.createRoom(
            title: "Product Demo",
            description: "Live demo of our new features",
            thumbnailFileId: nil,
            metadata: nil,
            channelEnabled: true,
            parentRoomId: nil
        )
        
        // 2. Create livestream post
        let post = try await AmityPostRepository.shared.createLiveStreamPost(
            targetType: .community,
            targetId: communityId,
            roomId: room.roomId,
            text: "Going live now! Join us for a product demo.",
            title: room.title,
            metadata: nil,
            mentionUserIds: nil,
            hashtags: nil
        )
        
        // 3. Create live chat channel (must be after post creation)
        let channelRepository = AmityChatClient.shared.channelRepository
        let channel = try await channelRepository.createChannel(room.title)
            .live()
            .postId(postId: post.postId)
            .roomId(roomId: room.roomId)
            .build()
            .create()
        
        // 4. Get broadcaster credentials
        let broadcasterData = try await AmityRoomRepository.shared.getBroadcastData(
            roomId: room.roomId
        )
        
        // 5. Initialize broadcaster (LiveKit example)
        if case .coHosts(let token, let url) = broadcasterData {
            try await initializeLiveKitBroadcaster(url: url, token: token)
        }
        
        // 6. Start broadcasting
        try await startStreaming()
        
        print("Room created and streaming started!")
        print("Room ID: \(room.roomId)")
        print("Post ID: \(post.postId)")
        print("Channel ID: \(channel.channelId)")
    } catch {
        print("Failed to create room and start streaming: \(error)")
    }
}
Important: The live chat channel must be created after the post is created, as it requires the postId. The order is: Room → Post → Channel.

Best Practices

Configure rooms appropriately:
  • Always enable channels for viewer interaction
  • Upload thumbnails before creating posts
  • Set clear, descriptive titles
  • Include relevant metadata for filtering
  • Validate participant list before creation
Handle participants effectively:
  • Include all co-hosts in initial creation
  • Limit participants to reasonable number (3-5)
  • Verify user IDs exist before adding
  • Update participant list as needed
Implement robust error handling:
try {
    const room = await roomRepository.createRoom(options);
    const broadcasterData = await roomRepository.getBroadcastData(room.roomId);
    // Proceed with streaming
} catch (error) {
    if (error.code === 'INVALID_PARTICIPANTS') {
        showError("One or more participants are invalid");
    } else if (error.code === 'QUOTA_EXCEEDED') {
        showError("Room creation limit reached");
    } else {
        showError("Failed to create room");
    }
    // Clean up if needed
}
Clean up resources appropriately:
  • Delete rooms after streaming ends
  • Stop streaming before deleting
  • Handle interrupted streams
  • Check room status before operations

Error Handling

do {
    let room = try await AmityRoomRepository.shared.createRoom(
        title: title,
        description: description,
        thumbnailFileId: thumbnailId,
        metadata: metadata,
        channelEnabled: true,
        parentRoomId: nil
    )
    // Success
} catch AmityError.invalidParameter(let message) {
    showError("Invalid room data: \(message)")
} catch AmityError.quotaExceeded {
    showError("Room creation limit reached")
} catch AmityError.permissionDenied {
    showError("You don't have permission to create rooms")
} catch {
    showError("Failed to create room: \(error.localizedDescription)")
}