"/rooms/latest":
    get:
        tags: [Rooms]
        operationId: getPublicRooms
        summary: List recent public rooms
        description: |
            Returns a snapshot of the most-recently-active public rooms — what the
            "explore" surface in the VR client uses to populate its rail. Rate-limited.
        security:
            - cloudApiKey: []
        responses:
            "200":
                description: Recent public rooms.
                content:
                    application/json:
                        schema:
                            type: array
                            items: { $ref: "../components/schemas/PublicRoom.yaml" }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "429": { $ref: "../cloud-api.yaml#/components/responses/TooManyRequests" }

"/rooms/join":
    post:
        tags: [Rooms]
        operationId: joinRoomViaInvite
        summary: Join a room via invite code
        description: |
            Joins a room using an invite code (instead of a known `roomId`). The
            cluster resolves the invite code to a room and returns the join payload.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        required: [inviteCode]
                        properties:
                            inviteCode: { type: string }
        responses:
            "200":
                description: Join payload — connection details for the assigned media server.
                content:
                    application/json:
                        schema: { $ref: "#/~1room~1{roomId}~1join/post/responses/200/content/application~1json/schema" }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../cloud-api.yaml#/components/responses/Forbidden" }
            "404":
                description: Invite code did not resolve.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "429": { $ref: "../cloud-api.yaml#/components/responses/TooManyRequests" }

"/room":
    post:
        tags: [Rooms]
        operationId: createRoom
        summary: Create a room
        description: |
            Creates a new room (persistent or ad-hoc, public or private). The
            calling user becomes the owner. Returns the freshly-minted
            `PublicRoom` directly — the VR client establishes the
            media-server connection separately via `/room/{roomId}/join`.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            name: { type: string }
                            description: { type: string }
                            visibility:
                                type: string
                                description: "`RoomVisibility` — `Public`, `Private`, `FriendsOnly`."
                            category: { type: string }
                            environmentId: { type: string }
                            maxUsersPerInstance: { type: integer }
                            instancePolicy: { type: string }
                        additionalProperties: true
        responses:
            "200":
                description: Created room.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/PublicRoom.yaml" }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403": { $ref: "../cloud-api.yaml#/components/responses/Forbidden" }

"/room/{roomId}":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
    get:
        tags: [Rooms]
        operationId: getRoom
        summary: Fetch a room
        description: |
            Returns the live snapshot of a room. The caller must be in the room
            (or have an invite or be the owner) for private rooms; public rooms
            are visible to anyone authenticated.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Live room.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/PublicRoom.yaml" }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller lacks visibility into this room.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
    put:
        tags: [Rooms]
        operationId: updateRoom
        summary: Update a room (owner-only)
        description: Mutates the room's settings. Restricted to the room owner / admins.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            name: { type: string }
                            description: { type: string }
                            visibility: { type: string }
                            category: { type: string }
                            environmentId: { type: string }
                            backgroundImageUrl: { type: string, format: uri }
                            microphonePolicy: { type: string }
                            movementSoundsPolicy: { type: string }
                            drawingVisibility: { type: string }
                            avatarNameVisibility: { type: string }
                            poseVisibility: { type: string }
                            toySpawnability: { type: string }
                            preferredUserType: { type: string }
                        additionalProperties: true
        responses:
            "200":
                description: Updated room.
                content:
                    application/json:
                        schema: { $ref: "../components/schemas/PublicRoom.yaml" }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not the owner / admin.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
    delete:
        tags: [Rooms]
        operationId: deleteRoom
        summary: Delete a room (owner-only)
        description: Removes a room. Restricted to the room owner.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Room deleted.
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not the owner.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }

"/rooms":
    get:
        tags: [Rooms]
        operationId: getRoomsForAccount
        summary: Rooms the caller is in or owns
        description: Lists rooms the calling user owns or is currently in.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Caller's rooms.
                content:
                    application/json:
                        schema:
                            type: array
                            items: { $ref: "../components/schemas/PublicRoom.yaml" }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }

"/room/{roomId}/join":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
    post:
        tags: [Rooms]
        operationId: joinRoomById
        summary: Join a room by id
        description: |
            Joins a known room. Returns connection details for the assigned media
            server. The caller must be allowed in (public room, or has an invite,
            or owner / admin / friend depending on visibility).
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        requestBody:
            required: false
            content:
                application/json:
                    schema:
                        type: object
                        properties:
                            inviteCode: { type: string }
                            seatIndex: { type: integer }
                        additionalProperties: true
        responses:
            "200":
                description: Join payload.
                content:
                    application/json:
                        schema:
                            type: object
                            required: [room, connection]
                            properties:
                                room: { $ref: "../components/schemas/PublicRoom.yaml" }
                                connection:
                                    type: object
                                    description: Media-server connection details.
                                    properties:
                                        mediaServerId: { type: string }
                                        host: { type: string }
                                        port: { type: integer }
                                        token: { type: string }
                                        userSessionId: { type: string }
                                    additionalProperties: true
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not allowed in this room.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "429": { $ref: "../cloud-api.yaml#/components/responses/TooManyRequests" }

"/room/{roomId}/data":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
    get:
        tags: [Rooms]
        operationId: getRoomData
        summary: Read free-form room data
        description: |
            Reads the free-form key/value bag attached to a room — used by
            activities and games to share state across a session.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Key/value bag.
                content:
                    application/json:
                        schema:
                            type: object
                            additionalProperties: true
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
    put:
        tags: [Rooms]
        operationId: setRoomData
        summary: Write free-form room data
        description: |
            Writes one or more key/value pairs to the room's data bag. Per-key
            size limits and per-room total size limits apply server-side.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        requestBody:
            required: true
            content:
                application/json:
                    schema:
                        type: object
                        additionalProperties: true
        responses:
            "200":
                description: Updated key/value bag.
                content:
                    application/json:
                        schema:
                            type: object
                            additionalProperties: true
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not in the room (or not allowed to mutate it).
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "422":
                description: Payload exceeds server-side limits.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }

"/room/{roomId}/data/{key}":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
        - in: path
          name: key
          required: true
          schema: { type: string }
    delete:
        tags: [Rooms]
        operationId: deleteRoomData
        summary: Delete one key from room data
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Key removed.
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "404":
                description: No matching room or key.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }

"/room/{roomId}/seat/{seatIndex}":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
        - in: path
          name: seatIndex
          required: true
          schema: { type: integer }
    put:
        tags: [Rooms]
        operationId: updateSeatIndex
        summary: Move the caller to a seat
        description: Reseats the calling user to a specific seat index.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Seat updated.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                roomId: { type: string }
                                seatIndex: { type: integer }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Seat unavailable or caller not in the room.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No room with this id.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }

"/room/{roomId}/users/{userSessionId}/kick":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
        - in: path
          name: userSessionId
          required: true
          schema: { type: string }
    get:
        tags: [Rooms]
        operationId: kickUser
        summary: Kick another user (owner / mod-only)
        description: |
            Kicks another user from the room. Restricted to the room owner / mod
            list. The kicked user can rejoin (it's an eject in moderation terms);
            staff-side kicks come from the admin spec.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Kick acknowledged.
                content:
                    application/json:
                        schema:
                            type: object
                            properties:
                                kicked: { type: boolean }
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "403":
                description: Caller is not the room's owner / mod.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
            "404":
                description: No matching session in this room.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }

"/room/{roomId}/leave":
    parameters:
        - in: path
          name: roomId
          required: true
          schema: { type: string }
    get:
        tags: [Rooms]
        operationId: leaveRoom
        summary: Leave the current room
        description: Removes the caller from the room.
        security:
            - cloudApiKey: []
              cloudAccessToken: []
        responses:
            "200":
                description: Left.
            "401": { $ref: "../cloud-api.yaml#/components/responses/Unauthorized" }
            "404":
                description: Caller was not in this room.
                content:
                    application/json:
                        schema: { $ref: "../cloud-api.yaml#/components/schemas/Error" }
