openapi: 3.0.3
info:
  title: OpenTalk Controller Frontend API
  description: >-
    Specifies the endpoints and structure of the OpenTalk Controller Frontend
    API
  contact:
    name: OpenTalk Team
    email: mail@opentalk.eu
  license:
    name: EUPL-1.2
  version: 0.0.0-dev
servers:
  - url: /v1
paths:
  /auth/login:
    get:
      tags:
        - api::v1::auth
      summary: Get the configured OIDC provider
      description: >-
        Returns the relevant information for a frontend to authenticate against
        the

        configured OIDC provider for the OpenTalk service.
      operationId: get_login
      responses:
        '200':
          description: Get information about the OIDC provider
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetLoginResponse'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security: []
    post:
      tags:
        - api::v1::auth
      summary: The login endpoint
      description: >-
        Attempt to authenticate with a provided ID token. The ID token can be

        received from an OIDC provider and contains information about the
        requesting

        user as well as an expiration timestamp. When a valid token with an
        unknown user

        is provided, a new user will be created in the database.
      operationId: post_login
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostLoginRequestBody'
        required: true
      responses:
        '200':
          description: Login successful, answer contains a list of permissions
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostLoginResponse'
              example:
                permissions: []
        '400':
          description: The provided ID token is malformed or contains invalid claims
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
              example:
                code: invalid_claims
                message: some required attributes are missing or malformed
        '401':
          description: The provided ID token is invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorBody'
              example:
                code: unauthorized
                message: Authentication failed
        '500':
          $ref: '#/components/responses/InternalServerError'
      security: []
  /events:
    get:
      tags:
        - api::v1::events
      summary: Get a list of events accessible by the requesting user
      description: >-
        Returns a paginated list of events and their exceptions inside the given
        time range
      operationId: get_events
      parameters:
        - name: time_min
          in: query
          description: Optional minimum time in which the event happens
          required: false
          schema:
            allOf:
              - $ref: '#/components/schemas/Timestamp'
            nullable: true
        - name: time_max
          in: query
          description: Optional maximum time in which the event happens
          required: false
          schema:
            allOf:
              - $ref: '#/components/schemas/Timestamp'
            nullable: true
        - name: invitees_max
          in: query
          description: |-
            Maximum number of invitees to return inside the event resource

            Default value is 0
          required: false
          schema:
            type: integer
            format: int32
            minimum: 0
        - name: favorites
          in: query
          description: Return only favorite events
          required: false
          schema:
            type: boolean
        - name: invite_status
          in: query
          description: Filter the events by invite status
          required: false
          schema:
            type: array
            items:
              $ref: '#/components/schemas/EventInviteStatus'
        - name: per_page
          in: query
          description: How many events to return per page
          required: false
          schema:
            type: integer
            format: int64
            nullable: true
        - name: after
          in: query
          description: >-
            Cursor token to get the next page of events


            Returned by the endpoint if the maximum number of events per page
            has been hit
          required: false
          schema:
            allOf:
              - type: string
                description: >-
                  An encoded cursor pointing to a position in a series of
                  elements
            nullable: true
        - name: adhoc
          in: query
          description: >-
            Only get events that are either marked as adhoc or non-adhoc


            If present, all adhoc events will be returned when `true`, all
            non-adhoc

            events will be returned when `false`. If not present, all events
            will

            be returned regardless of their `adhoc` flag value.
          required: false
          schema:
            type: boolean
            nullable: true
        - name: time_independent
          in: query
          description: >-
            Only get events that are either time-independent or time-dependent


            If present, all time-independent events will be returned when
            `true`,

            all time-dependent events will be returned when `false`. If absent,

            all events will be returned regardless of their time dependency.
          required: false
          schema:
            type: boolean
            nullable: true
      responses:
        '200':
          description: List of the events and exceptions
          headers:
            link:
              schema:
                $ref: '#/components/schemas/CursorLink'
              description: Links for paging through the results
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/EventOrException'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    post:
      tags:
        - api::v1::events
      summary: Create a new event
      description: Create a new event with the fields sent in the body.
      operationId: new_event
      parameters:
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostEventsBody'
        required: true
      responses:
        '201':
          description: The event has been created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResource'
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}:
    get:
      tags:
        - api::v1::events
      summary: Get an event
      description: Returns the event resource for the given id
      operationId: get_event
      parameters:
        - name: invitees_max
          in: query
          description: |-
            Maximum number of invitees to return inside the event resource

            Default value is 0
          required: false
          schema:
            type: integer
            format: int64
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '200':
          description: Event was successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::events
      summary: Delete an event and its owned resources, including the associated room.
      description: >-
        Deletes the event by the id if found. See the query parameters for
        affecting

        the behavior of this endpoint, such as mail notification suppression, or

        succeding even if external resources cannot be successfully deleted.
      operationId: delete_event
      parameters:
        - name: force_delete_reference_if_external_services_fail
          in: query
          description: >-
            Flag to force delete the reference if the deletion at the external
            services fails
          required: false
          schema:
            type: boolean
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '204':
          description: The event was successfully deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::events
      summary: Patch an event
      description: Fields that are not provided in the request body will remain unchanged.
      operationId: patch_event
      parameters:
        - name: invitees_max
          in: query
          description: Maximum number of invitees to include inside the event
          required: false
          schema:
            type: integer
            format: int64
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchEventBody'
        required: true
      responses:
        '200':
          description: The event was successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventResource'
        '204':
          description: The patch was empty
        '400':
          description: |-
            Could not modify the specified event due to wrong
                            syntax or bad values, for example an invalid timestamp string
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/instances:
    get:
      tags:
        - api::v1::events::instances
      summary: Get a list of the instances of an event
      description: >-
        The instances are calculated based on the RRULE of the event. If no
        RRULE is

        set for the event, the single event instance is returned.


        If no pagination query is added, the default page size is used.
      operationId: get_event_instances
      parameters:
        - name: invitees_max
          in: query
          description: Maximum number of invitees to include inside the event
          required: false
          schema:
            type: integer
            format: int64
        - name: time_min
          in: query
          description: Minimum time of the event instances
          required: false
          schema:
            allOf:
              - $ref: '#/components/schemas/Timestamp'
            nullable: true
        - name: time_max
          in: query
          description: Maximum time of the event instances
          required: false
          schema:
            allOf:
              - $ref: '#/components/schemas/Timestamp'
            nullable: true
        - name: per_page
          in: query
          description: How many events to return per page
          required: false
          schema:
            type: integer
            format: int64
            nullable: true
        - name: after
          in: query
          required: false
          schema:
            $ref: '#/components/schemas/GetEventInstancesCursor'
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '200':
          description: List of event instances successfully returned
          headers:
            link:
              schema:
                $ref: '#/components/schemas/PageLink'
              description: Links for paging through the results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetEventInstancesResponseBody'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/instances/{instance_id}:
    get:
      tags:
        - api::v1::events::instances
      summary: Get an event instance
      description: Returns the event instance resource
      operationId: get_event_instance
      parameters:
        - name: event_id
          in: path
          description: ID of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
        - name: instance_id
          in: path
          description: ID of the event instance
          required: true
          schema:
            $ref: '#/components/schemas/InstanceId'
        - name: invitees_max
          in: query
          description: >-
            Maximum number of invitees to return inside the event instance
            resource


            Default: 0
          required: false
          schema:
            type: integer
            format: int64
        - name: suppress_email_notification
          in: query
          description: Flag to suppress email notification
          required: false
          schema:
            type: boolean
      responses:
        '200':
          description: Event instance successfully returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetEventInstanceResponseBody'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::events::instances
      summary: API Endpoint `PATCH /events/{event_id}/{instance_id}`
      description: >-
        Patch an instance of a recurring event. This creates or modifies an
        exception for the event

        at the point of time of the given instance_id.

        Returns the patched event instance
      operationId: patch_event_instance
      parameters:
        - name: event_id
          in: path
          description: ID of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
        - name: instance_id
          in: path
          description: ID of the event instance
          required: true
          schema:
            $ref: '#/components/schemas/InstanceId'
        - name: invitees_max
          in: query
          description: >-
            Maximum number of invitees to return inside the event instance
            resource


            Default: 0
          required: false
          schema:
            type: integer
            format: int64
        - name: suppress_email_notification
          in: query
          description: Flag to suppress email notification
          required: false
          schema:
            type: boolean
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchEventInstanceBody'
        required: true
      responses:
        '200':
          description: Event instance successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventInstance'
        '204':
          description: The request body was empty, no changes required
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/invite:
    delete:
      tags:
        - api::v1::events::invites
      summary: Decline an invite to an event
      description: No content required, the request will accept the invitation.
      operationId: decline_event_invite
      parameters:
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '204':
          description: Invitation was declined
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::events::invites
      summary: Accept an invite to an event
      description: No content required, the request will accept the invitation.
      operationId: accept_event_invite
      parameters:
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '204':
          description: Invitation was accepted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/invites:
    get:
      tags:
        - api::v1::events::invites
      summary: Get the invites for an event
      description: Returns the list of event invites
      operationId: get_invites_for_event
      parameters:
        - name: pagination
          in: query
          description: Results will be paginated by this pagination specification
          required: true
          schema:
            type: object
            description: Page-based pagination query
            properties:
              page:
                type: integer
                format: int64
                description: The number of the page
              per_page:
                type: integer
                format: int64
                description: The number of entries per page
        - name: status
          in: query
          description: If present, the results will be filtered by that state
          required: false
          schema:
            allOf:
              - $ref: '#/components/schemas/EventInviteStatus'
            nullable: true
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '200':
          description: Event instance successfully returned
          headers:
            link:
              schema:
                $ref: '#/components/schemas/CursorLink'
              description: Links for paging through the results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetEventInstanceResponseBody'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    post:
      tags:
        - api::v1::events::invites
      summary: Create a new invite to an event
      description: Create a new invite to an event with the fields sent in the body.
      operationId: create_invite_to_event
      parameters:
        - name: suppress_email_notification
          in: query
          description: Flag to suppress email notification
          required: false
          schema:
            type: boolean
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostEventInviteBody'
        required: true
      responses:
        '201':
          description: The user or email has been invited to the event
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/EventResource'
        '204':
          description: >-
            The user or email was already invited before, or the user is the
            creator of the event, in which case they have been invited
            implicitly
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/invites/email:
    delete:
      tags:
        - api::v1::events::invites
      summary: Delete an invite from an event
      description: >-
        Delete/Withdraw an event invitation using the email address as the
        identifier.


        This will also withdraw invites from registered users if the provided
        email address matches theirs.
      operationId: delete_email_invite_to_event
      parameters:
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DeleteEmailInviteBody'
        required: true
      responses:
        '204':
          description: The email event invitation has been deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::events::invites
      summary: Patch an event email invite with the provided fields
      description: Fields that are not provided in the request body will remain unchanged.
      operationId: update_email_invite_to_event
      parameters:
        - name: event_id
          in: path
          description: The id of the event to be modified
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchEmailInviteBody'
        required: true
      responses:
        '204':
          description: Invite was successfully updated
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            The requesting user does not have the required permissions to update
            the invite.
                          Only the creator of an event can update the invites.
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/invites/{user_id}:
    delete:
      tags:
        - api::v1::events::invites
      summary: Delete an invite from an event
      description: This will uninvite the user from the event
      operationId: delete_invite_to_event
      parameters:
        - name: event_id
          in: path
          description: ID of the event to delete the invite for
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
        - name: user_id
          in: path
          description: ID of the user to delete the invite for
          required: true
          schema:
            $ref: '#/components/schemas/UserId'
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
      responses:
        '204':
          description: The user event invitation has been deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::events::invites
      summary: Patch an event invite with the provided fields
      description: Fields that are not provided in the request body will remain unchanged.
      operationId: update_invite_to_event
      parameters:
        - name: event_id
          in: path
          description: The id of the event to be modified
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
        - name: user_id
          in: path
          description: The id of the invited user to be modified
          required: true
          schema:
            $ref: '#/components/schemas/UserId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchInviteBody'
        required: true
      responses:
        '204':
          description: Invite was successfully updated
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          description: >-
            The requesting user does not have the required permissions to update
            the invite.
                          Only the creator of an event can update the invites.
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /events/{event_id}/shared_folder:
    get:
      tags:
        - api::v1::events::shared_folder
      summary: Get the shared folder for an event
      description: Returns the shared folder for an event if available
      operationId: get_shared_folder_for_event
      parameters:
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '200':
          description: Shared folder returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedFolder'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    put:
      tags:
        - api::v1::events::shared_folder
      summary: Create a shared folder for an event
      description: Returns the shared folder for an event if created
      operationId: put_shared_folder_for_event
      parameters:
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '200':
          description: Shared folder created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedFolder'
        '304':
          description: Shared folder was already present
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SharedFolder'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::events::shared_folder
      summary: Delete the shared folder of an event
      description: >-
        Will delete the shared folder from the external system and remove the
        reference to it
      operationId: delete_shared_folder_for_event
      parameters:
        - name: event_id
          in: path
          description: The id of the event
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
        - name: force_delete_reference_if_shared_folder_deletion_fails
          in: query
          description: >-
            Flag to force delete the reference to the shared folder if the
            deletion of the shared folder fails
          required: false
          schema:
            type: boolean
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
      responses:
        '204':
          description: >-
            Shared folder was successfully deleted, or no shared folder had been
            present
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /invite/verify:
    post:
      tags:
        - api::v1::invites
      summary: Verify an invite code
      description: Verifies the invite and returns the room url for the invite code
      operationId: verify_invite_code
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostInviteVerifyRequestBody'
        required: true
      responses:
        '200':
          description: Invite is valid, the response body tells the room id
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CodeVerified'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: Invalid body contents received
        '500':
          $ref: '#/components/responses/InternalServerError'
      security: []
  /rooms:
    get:
      tags:
        - api::v1::rooms
      summary: Get a list of rooms accessible by the requesting user
      description: >-
        All rooms accessible to the requesting user are returned in a list. If
        no

        pagination query is added, the default page size is used.
      operationId: accessible
      parameters:
        - name: per_page
          in: query
          description: The number of entries per page
          required: false
          schema:
            type: integer
            format: int64
        - name: page
          in: query
          description: The number of the page
          required: false
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: List of accessible rooms successfully returned
          headers:
            link:
              schema:
                $ref: '#/components/schemas/PageLink'
              description: Links for paging through the results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetRoomsResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    post:
      tags:
        - api::v1::rooms
      summary: Create a new room
      description: Creates a new room withh the settings given in the request body.
      operationId: new
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostRoomsRequestBody'
        required: true
      responses:
        '201':
          description: Room successfully created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomResource'
        '400':
          description: >-
            Wrong syntax or bad values such as invalid owner id received in the
            body
        '401':
          $ref: '#/components/responses/Unauthorized'
        '422':
          description: Invalid body contents received
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}:
    get:
      tags:
        - api::v1::rooms
      summary: Get a room
      description: >-
        Returns the room resource including additional information such as the
        creator profile.
      operationId: get
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      responses:
        '200':
          description: Room was successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::rooms
      summary: Delete a room and its owned resources.
      description: >-
        Deletes the room by the id if found. See the query parameters for
        affecting

        the behavior of this endpoint, such as mail notification suppression, or

        succeding even if external resources cannot be successfully deleted.
      operationId: delete
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: force_delete_reference_if_external_services_fail
          in: query
          description: >-
            Flag to force delete the reference if the deletion at the external
            services fails
          required: false
          schema:
            type: boolean
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
      responses:
        '204':
          description: Room was successfully deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::rooms
      summary: Patch a room with the provided fields
      description: Fields that are not provided in the request body will remain unchanged.
      operationId: patch_room
      parameters:
        - name: room_id
          in: path
          description: The id of the room to be modified
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchRoomsRequestBody'
        required: true
      responses:
        '200':
          description: Room was successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomResource'
        '400':
          description: |-
            Could not modify the specified room due to wrong
                            syntax or bad values, for example an invalid owner id
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/assets:
    get:
      tags:
        - api::v1::assets
      summary: Get the assets associated with a room.
      description: |-
        This returns assets that are available for a room. If no
        pagination query is added, the default page size is used.
      operationId: room_assets
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: per_page
          in: query
          description: The number of entries per page
          required: false
          schema:
            type: integer
            format: int64
        - name: page
          in: query
          description: The number of the page
          required: false
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: The assets have been returned successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetRoomsAssetsResponseBody'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/assets/{asset_id}:
    get:
      tags:
        - api::v1::assets
      summary: Get a specific asset inside a room.
      description: >-
        This will return the plain asset contents, e.g. the binary file contents
        or

        whatever else is stored inside the asset storage.
      operationId: room_asset
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: asset_id
          in: path
          description: The id of the asset
          required: true
          schema:
            $ref: '#/components/schemas/AssetId'
      responses:
        '200':
          $ref: '#/components/responses/BinaryData'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::assets
      summary: Delete an asset from a room.
      description: The asset is removed from the room and deleted from the storage.
      operationId: delete_room_asset
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: asset_id
          in: path
          description: The id of the asset
          required: true
          schema:
            $ref: '#/components/schemas/AssetId'
      responses:
        '204':
          description: The asset has been deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/event:
    get:
      tags:
        - api::v1::rooms
      summary: Get a room's event
      description: >-
        This returns the event with which the room is associated. Please note

        that rooms can exist without events, in which case a `404` status will
        be

        returned.
      operationId: get_room_event
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      responses:
        '200':
          description: The room's event was successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/EventInfo'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
        - InviteCode: []
  /rooms/{room_id}/invites:
    get:
      tags:
        - api::v1::invites
      summary: Get all invites for a room
      description: |-
        This returns all invites that are available for a room. If no
        pagination query is added, the default page size is used.
      operationId: get_invites
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: per_page
          in: query
          description: The number of entries per page
          required: false
          schema:
            type: integer
            format: int64
        - name: page
          in: query
          description: The number of the page
          required: false
          schema:
            type: integer
            format: int64
      responses:
        '200':
          description: The invites could be loaded successfully
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetRoomsInvitesResponseBody'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    post:
      tags:
        - api::v1::invites
      summary: Create a new invite
      description: A new invite to the room is created with the information in the body.
      operationId: add_invite
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostInviteRequestBody'
        required: true
      responses:
        '200':
          description: Successfully create a new invite
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InviteResource'
        '400':
          description: |-
            Could not create a new invite due to wrong syntax or
                            bad values, for example an invalid owner id.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/invites/{invite_code}:
    get:
      tags:
        - api::v1::invites
      summary: Get a room invite
      description: Returns the room invite resource
      operationId: get_invite
      parameters:
        - name: room_id
          in: path
          description: The room id for the invite
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: invite_code
          in: path
          description: The invite code id
          required: true
          schema:
            $ref: '#/components/schemas/InviteCode'
      responses:
        '200':
          description: Successfully retrieved the room invite
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InviteResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    put:
      tags:
        - api::v1::invites
      summary: Update an invite code
      description: Updates the field values as set in the request body.
      operationId: update_invite
      parameters:
        - name: room_id
          in: path
          description: The room id for the invite
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: invite_code
          in: path
          description: The invite code id
          required: true
          schema:
            $ref: '#/components/schemas/InviteCode'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PutInviteRequestBody'
        required: true
      responses:
        '200':
          description: Successfully updated the room invite
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/InviteResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::invites
      summary: Delete an invite code
      description: The invite code will no longer be usable once it is deleted.
      operationId: delete_invite
      parameters:
        - name: room_id
          in: path
          description: The room id for the invite
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: invite_code
          in: path
          description: The invite code id
          required: true
          schema:
            $ref: '#/components/schemas/InviteCode'
      responses:
        '204':
          description: Successfully deleted the room invite
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/sip:
    get:
      tags:
        - api::v1::sip_configs
      summary: Get the sip config for the specified room.
      description: >-
        Returns the sip config if available for the room, otherwise `404
        NOT_FOUND`

        is returned.
      operationId: get_room_sip
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      responses:
        '200':
          description: The SIP config is successfully returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SipConfigResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    put:
      tags:
        - api::v1::sip_configs
      summary: >-
        Modify the sip configuration of a room. A new sip configuration is
        created
      description: |-
        if none was set before.

        Returns the new modified sip configuration.
        Get the sip config for the specified room.
      operationId: put
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PutSipConfig'
        required: true
      responses:
        '200':
          description: The SIP configuration was updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SipConfigResource'
        '201':
          description: A new SIP configuration was created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SipConfigResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::sip_configs
      summary: Delete the SIP configuration of a room.
      description: This removes the dial-in functionality from the room.
      operationId: delete_room_sip
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      responses:
        '204':
          description: The SIP configuration was successfully deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/start:
    post:
      tags:
        - api::v1::rooms
      summary: Start a signaling session as a registered user
      description: >-
        This endpoint has to be called in order to get a room ticket. When
        joining a room, the ticket

        must be provided as a `Sec-WebSocket-Protocol` header field when
        starting the WebSocket

        connection.
      operationId: start
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostRoomsStartRequestBody'
        required: true
      responses:
        '200':
          description: Returns the information for joining the room
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomsStartResponse'
        '400':
          description: >-
            Either no breakout rooms were found for this room, or the breakout
            room id is invalid
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              examples:
                InvalidBreakoutRoomId:
                  summary: Invalid breakout room id
                  value:
                    code: invalid_breakout_room_id
                    message: The provided breakout room ID is invalid
                NoBreakoutRooms:
                  summary: No breakout rooms
                  value:
                    code: no_breakout_rooms
                    message: The requested room has no breakout rooms
        '401':
          description: |-
            The provided AccessToken is expired or the
                            provided ID- or Access-Token is invalid. The WWW-Authenticate
                            header will contain a error description 'session expired' to
                            distinguish between an invalid and an expired token.
          headers:
            www-authenticate:
              schema:
                type: string
              description: >-
                will contain 'session expired' to distinguish between an invalid
                and an expired token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
        '403':
          description: >-
            The user has not been invited to join the room or has been banned
            from entering this room
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              examples:
                UserBanned:
                  summary: User has been banned from the room
                  value:
                    code: banned_from_room
                    message: This user has been banned from entering this room
                UserNotInvited:
                  summary: User has not been invited to join the room
                  value:
                    code: forbidden
                    message: Access to the requested resource is forbidden
        '404':
          description: >-
            The specified room could not be found or it has no event associated
            with it
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              example:
                code: not_found
                message: A requested resource could not be found
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/start_invited:
    post:
      tags:
        - api::v1::rooms
      summary: Start a signaling session for an invitation code
      description: >-
        Returns a ticket to be used with the `/signaling` endpoint. When joining
        a

        room, the ticket must be provided as `Sec-WebSocket-Protocol` header
        field

        when starting the WebSocket connection. When the requested room has a

        password set, the requester must provide the correct password through
        the

        requests body. When the request has no password set, the password will
        be

        ignored if provided.
      operationId: start_invited
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostRoomsStartInvitedRequestBody'
        required: true
      responses:
        '200':
          description: >-
            Response body includes the information needed to connect to the
            signaling endpoint
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomsStartResponse'
        '400':
          description: |-
            The provided ID token is malformed or contains
                            invalid claims,  no breakout rooms were found for this room, the
                            breakout room id is invalid, the room doesn't exist or the guest
                            does not have a valid invite for this room. Guests shall not be
                            able to distinguish between existing rooms and rooms they don't
                            have permission to enter, therefore the response is the same in
                            these cases
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              examples:
                InvalidBreakoutRoomId:
                  summary: Invalid breakout room id
                  value:
                    code: invalid_breakout_room_id
                    message: The provided breakout room ID is invalid
                NoBreakoutRooms:
                  summary: No breakout rooms
                  value:
                    code: no_breakout_rooms
                    message: The requested room has no breakout rooms
                RoomIdMismatch:
                  summary: Room id mismatch
                  value:
                    code: bad_request
                    message: Room id mismatch
        '401':
          description: |-
            Either: the provided access token is expired or the
                            provided id or access token is invalid. The WWW-Authenticate
                            header will contain an error description 'session expired' to
                            distinguish between an invalid and an expired token.
                            Or: the provided password was incorrect, in which case the body
                            contains more information.
          headers:
            www-authenticate:
              schema:
                type: string
              description: >-
                will contain 'session expired' to distinguish between an invalid
                and an expired token
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              examples:
                ExpiredOrInvalidAccessToken:
                  summary: Expired or invalid access token
                  value:
                    code: unauthorized
                    message: The session for this user has expired
                WrongRoomPassword:
                  summary: Wrong room password
                  value:
                    code: wrong_room_password
                    message: The provided password does not match the room password
        '403':
          description: The participant has been banned from entering this room
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              example:
                code: banned_from_room
                message: This user has been banned from entering this room
        '404':
          $ref: '#/components/responses/NotFound'
        '422':
          description: Invalid body contents received
        '500':
          $ref: '#/components/responses/InternalServerError'
      security: []
  /rooms/{room_id}/streaming_targets:
    get:
      tags:
        - api::v1::streaming_targets
      summary: List the streaming targets of a room
      description: Returns the streaming targets available for a room
      operationId: get_streaming_targets
      parameters:
        - name: per_page
          in: query
          description: The number of entries per page
          required: false
          schema:
            type: integer
            format: int64
        - name: page
          in: query
          description: The number of the page
          required: false
          schema:
            type: integer
            format: int64
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      responses:
        '200':
          description: List of streaming targets successfully returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetRoomStreamingTargetsResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    post:
      tags:
        - api::v1::streaming_targets
      summary: Create a new streaming target
      description: Creates a new streaming target for the given room
      operationId: post_streaming_target
      parameters:
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PostRoomStreamingTargetRequest'
        required: true
      responses:
        '200':
          description: Successfully create a new streaming target
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PostRoomStreamingTargetResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/streaming_targets/{streaming_target_id}:
    get:
      tags:
        - api::v1::streaming_targets
      summary: Get a streaming target
      description: Returns a single streaming target for a specific room.
      operationId: get_streaming_target
      parameters:
        - name: room_id
          in: path
          description: The room id for the invite
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: streaming_target_id
          in: path
          description: The streaming target id
          required: true
          schema:
            $ref: '#/components/schemas/StreamingTargetId'
      responses:
        '200':
          description: The streaming target has been successfully returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetRoomStreamingTargetResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::streaming_targets
      summary: Deletes a single streaming target.
      description: The streaming target is deleted from the room.
      operationId: delete_streaming_target
      parameters:
        - name: room_id
          in: path
          description: The room id for the invite
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: streaming_target_id
          in: path
          description: The streaming target id
          required: true
          schema:
            $ref: '#/components/schemas/StreamingTargetId'
        - name: suppress_email_notification
          in: query
          description: Flag to disable email notification
          required: false
          schema:
            type: boolean
      responses:
        '204':
          description: The streaming target has been deleted
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::streaming_targets
      summary: Update a room streaming target
      description: Modifies and returns a single streaming target.
      operationId: patch_streaming_target
      parameters:
        - name: room_id
          in: path
          description: The room id for the invite
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: streaming_target_id
          in: path
          description: The streaming target id
          required: true
          schema:
            $ref: '#/components/schemas/StreamingTargetId'
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ChangeRoomStreamingTargetRequest'
        required: true
      responses:
        '200':
          description: Streaming target was successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ChangeRoomStreamingTargetResponse'
        '400':
          description: |-
            Could not modify the specified streaming target due to wrong
                            syntax or bad values
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /rooms/{room_id}/tariff:
    get:
      tags:
        - api::v1::rooms
      summary: Get a room's tariff
      description: >-
        This returns the tariff that applies to the room, typically the tariff
        of

        the room creator.
      operationId: get_room_tariff
      parameters:
        - name: room_id
          in: path
          description: The id of the room
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
      responses:
        '200':
          description: The room's tariff was successfully retrieved
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TariffResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
        - InviteCode: []
  /services/call_in/start:
    post:
      tags:
        - api::v1::services::call_in
      summary: Starts a signaling session
      description: >-
        Takes call-in id and pin and returns a ticket for the `/signaling`
        endpoint. Behaves similar to the

        `/rooms/{room_id}/start` endpoint.


        This endpoint is provided for call-in gateways to start a room
        connection

        for call-in participants. The participant typically has to provide the

        credentials (id and pin) via DTMF (the number pad).
      operationId: post_call_in_start
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartCallInRequestBody'
        required: true
      responses:
        '200':
          description: >-
            The dial-in participant has successfully authenticated for the room.
            Information needed for connecting to the signaling is contained in
            the response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceStartResponse'
        '400':
          description: '`id` and `pin` are not valid for any room.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              example:
                code: invalid_credentials
                message: given call-in id & pin combination is not valid
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /services/recording/start:
    post:
      tags:
        - api::v1::services::recording
      summary: Starts a signaling session for recording
      description: >-
        This endpoint is provided for participation of recording and streaming
        clients

        which will join incognito and receive all the information and media
        streams required

        for creating a recording or livestream of the meeting.
      operationId: start_recording
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/StartRecordingRequestBody'
        required: true
      responses:
        '200':
          description: >-
            The recording participant has successfully authenticated for the
            room. Information needed for connecting to the signaling is
            contained in the response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ServiceStartResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          description: Recording has not been configured
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/StandardErrorBody'
              example:
                code: not_found
                message: A requested resource could not be found
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /services/recording/upload:
    get:
      tags:
        - api::v1::services::recording
      summary: Streaming upload of a rendered recording
      description: >-
        This is a WebSocket endpoint, all the data that is sent in binary
        messages

        is stored in the destination file.
      operationId: ws_upload
      parameters:
        - name: room_id
          in: query
          description: The room id
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: file_extension
          in: query
          description: The file extension
          required: true
          schema:
            $ref: '#/components/schemas/FileExtension'
        - name: timestamp
          in: query
          description: The recording creation timestamp
          required: true
          schema:
            $ref: '#/components/schemas/Timestamp'
        - name: connection
          in: header
          required: true
          schema:
            type: string
            enum:
              - Upgrade
        - name: upgrade
          in: header
          required: true
          schema:
            type: string
            enum:
              - websocket
      responses:
        '200':
          description: WebSocket connection succcessfully established
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /services/recording/upload_render:
    post:
      tags:
        - api::v1::services::recording
      summary: Upload a rendered recording
      description: |-
        The body of this request should simply contain the raw data.
        This endpoint is deprecated, please use the streaming upload
        `/services/recording/upload` WebSocket endpoint instead.
      operationId: upload_render
      parameters:
        - name: room_id
          in: query
          description: The room id
          required: true
          schema:
            $ref: '#/components/schemas/RoomId'
        - name: file_extension
          in: query
          description: The file extension
          required: true
          schema:
            $ref: '#/components/schemas/FileExtension'
        - name: timestamp
          in: query
          description: The recording creation timestamp
          required: true
          schema:
            $ref: '#/components/schemas/Timestamp'
      requestBody:
        description: The raw data to be uploaded
        content:
          application/octet-stream:
            schema:
              type: string
              format: binary
        required: true
      responses:
        '204':
          description: The recording was uploaded successfully
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      deprecated: true
      security:
        - BearerAuth: []
  /signaling:
    get:
      tags:
        - api::signaling
      summary: Room signaling websocket
      description: >-
        The room signaling websocket.

        Documentation:
        <https://docs.opentalk.eu/developer/controller/signaling/>.
      operationId: ws_service
      parameters:
        - name: Sec-WebSocket-Protocol
          in: header
          required: true
          schema:
            type: string
            pattern: ^opentalk-signaling-json-v1.0, ticket#.*$
          example: >-
            opentalk-signaling-json-v1.0,
            ticket#eyJpc3MiOiJodHRwczovL2V4YW1wbGUuYXV0aDAuY29tLy
        - name: connection
          in: header
          required: true
          schema:
            type: string
            enum:
              - Upgrade
        - name: upgrade
          in: header
          required: true
          schema:
            type: string
            enum:
              - websocket
      responses:
        '200':
          description: WebSocket connection succcessfully established
        '400':
          $ref: '#/components/responses/BadRequest'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /turn:
    get:
      tags:
        - api::v1::turn
      summary: Get a TURN server and corresponding credentials
      description: |-
        The returned TURN server can be used with the credentials to circumvent
        NAT restrictions.
      operationId: get_turn
      responses:
        '200':
          description: TURN server and corresponding credentials
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetTurnServersResponse'
        '204':
          description: No TURN servers have been configured
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
        - InviteCode: []
  /users/find:
    get:
      tags:
        - api::v1::users
      summary: Find users
      description: Query users for autocomplete fields
      operationId: find
      parameters:
        - name: q
          in: query
          description: The query string
          required: true
          schema:
            type: string
      responses:
        '200':
          description: Search results
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetFindResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /users/me:
    get:
      tags:
        - api::v1::users
      summary: Get the current user's profile
      description: |-
        Returns the private user profile of the currently logged-in user. This
        private profile contains information that is not visible in the public
        profile, such as tariff status or the used storage.
      operationId: get_me
      responses:
        '200':
          description: Information about the logged in user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PrivateUserProfile'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    patch:
      tags:
        - api::v1::users
      summary: Patch the current user's profile
      description: Fields that are not provided in the request body will remain unchanged.
      operationId: patch_users_me
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/PatchMeBody'
        required: true
      responses:
        '200':
          description: User profile was successfully updated
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/RoomResource'
        '400':
          description: |-
            Could not modify the user's profile due to wrong
                            syntax or bad values
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /users/me/assets:
    get:
      tags:
        - api::v1::users
      summary: Get the assets associated with the user.
      description: >-
        All assets associated to the requesting user are returned in a list. If
        no

        pagination query is added, the default page size is used.
      operationId: get_me_assets
      parameters:
        - name: per_page
          in: query
          description: The number of entries per page
          required: false
          schema:
            type: integer
            format: int64
        - name: page
          in: query
          description: The number of the page
          required: false
          schema:
            type: integer
            format: int64
        - name: sort
          in: query
          description: sort by this field
          required: true
          schema:
            $ref: '#/components/schemas/AssetSorting'
        - name: order
          in: query
          description: ordering direction
          required: true
          schema:
            $ref: '#/components/schemas/Ordering'
      responses:
        '200':
          description: List of accessible assets successfully returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetUserAssetsResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /users/me/event_favorites/{event_id}:
    put:
      tags:
        - api::v1::events::favorites
      summary: Add an event to the current user's favorites
      description: The event will be marked as favorited by the calling user.
      operationId: add_event_to_favorites
      parameters:
        - name: event_id
          in: path
          description: The id of the event that gets marked as favorite
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '201':
          description: The event has been addded to the user's favorites
        '204':
          description: >-
            The event had already been added to the user's favorites, no changes
            made
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
    delete:
      tags:
        - api::v1::events::favorites
      summary: Remove an event from the current user's favorites
      description: The event will be marked as non-favorited by the calling user.
      operationId: remove_event_from_favorites
      parameters:
        - name: event_id
          in: path
          description: The id of the event that gets marked as non-favorited
          required: true
          schema:
            $ref: '#/components/schemas/EventId'
      responses:
        '204':
          description: The event has been removed from the user's favorites
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /users/me/pending_invites:
    get:
      tags:
        - api::v1::events::invites
      summary: Get information about pending invites
      description: Returns information about pending invites for the current user
      operationId: get_event_invites_pending
      responses:
        '200':
          description: Information about pending invites is returned
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/GetEventInvitesPendingResponse'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '404':
          $ref: '#/components/responses/NotFound'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /users/me/tariff:
    get:
      tags:
        - api::v1::users
      summary: Get the current user tariff information.
      description: Returns the tariff information for the currently logged in user.
      operationId: get_me_tariff
      responses:
        '200':
          description: Information about the tariff of the current user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TariffResource'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
  /users/{user_id}:
    get:
      tags:
        - api::v1::users
      summary: Get a user's public profile
      description: Returns the public profile of a user.
      operationId: get_user
      parameters:
        - name: user_id
          in: path
          description: The id of the user
          required: true
          schema:
            $ref: '#/components/schemas/UserId'
      responses:
        '200':
          description: Information about the user
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/PublicUserProfile'
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '500':
          $ref: '#/components/responses/InternalServerError'
      security:
        - BearerAuth: []
components:
  schemas:
    AssetId:
      type: string
      format: uuid
      description: The id of an asset
      example: 00000000-0000-0000-0000-0000aabbcc00
    AssetResource:
      type: object
      description: Representation of an asset resource
      required:
        - id
        - filename
        - created_at
        - kind
        - size
      properties:
        created_at:
          type: string
          format: date-time
          description: The timestamp the asset was created
        filename:
          type: string
          description: The filename of the asset
        id:
          $ref: '#/components/schemas/AssetId'
        kind:
          type: string
          description: The asset kind
        namespace:
          type: string
          description: The namespace of the asset
          nullable: true
        size:
          type: integer
          format: int64
          description: The size of the asset in bytes
      example:
        created_at: '2024-06-18T11:22:33Z'
        filename: recording.webm
        id: 00000000-0000-0000-0000-0000aabbcc00
        kind: record
        namespace: recording
        size: 98765432
    AssetSorting:
      type: string
      description: Properties by which a list of assets can get sorted.
      enum:
        - filename
        - size
        - namespace
        - kind
        - created_at
    BreakoutRoomId:
      type: string
      format: uuid
      description: The id of a breakout room
      example: 00000000-0000-0000-0000-0000badcab1e
    CallInId:
      $ref: '#/components/schemas/NumericId'
    CallInInfo:
      type: object
      description: Information needed to participate in a call-in connection.
      required:
        - tel
        - id
        - password
      properties:
        id:
          $ref: '#/components/schemas/CallInId'
        password:
          $ref: '#/components/schemas/CallInPassword'
        tel:
          type: string
          description: SIP Call-In phone number which must be used to reach the room
      example:
        id: '1234567890'
        password: '0987654321'
        tel: +555-123-456-789
    CallInPassword:
      $ref: '#/components/schemas/NumericId'
    ChangeRoomStreamingTargetRequest:
      $ref: '#/components/schemas/UpdateStreamingTarget'
    ChangeRoomStreamingTargetResponse:
      $ref: '#/components/schemas/RoomStreamingTarget'
    CodeVerified:
      type: object
      description: Verify response body for *POST /invite/verify*
      required:
        - room_id
        - password_required
      properties:
        password_required:
          type: boolean
          description: If password is required
        room_id:
          $ref: '#/components/schemas/RoomId'
    CursorLink:
      type: string
      example: >-
        <https://api.example.org/resource?after=urlencodednextpagetoken>;
        rel='next'
    DateTimeTz:
      type: object
      description: Representation of a datetime timezone
      required:
        - datetime
        - timezone
      properties:
        datetime:
          type: string
          format: date-time
          description: UTC datetime
        timezone:
          $ref: '#/components/schemas/TimeZone'
      example:
        datetime: '2024-07-05T17:23:42Z'
        timezone: Europe/Berlin
    DeleteEmailInviteBody:
      type: object
      description: >-
        Query parameters for the `DELETE /events/{event_id}/invites/email`
        endpoint
      required:
        - email
      properties:
        email:
          $ref: '#/components/schemas/EmailAddress'
    EmailAddress:
      type: string
      format: email
      description: An e-mail address
      example: alice@example.com
    EmailInvite:
      type: object
      description: Request body variant for the `POST /events/{event_id}/invites` endpoint
      required:
        - email
      properties:
        email:
          $ref: '#/components/schemas/EmailAddress'
        role:
          $ref: '#/components/schemas/EmailInviteRole'
      example:
        email: alice@example.com
        role: guest
    EmailInviteRole:
      type: string
      enum:
        - guest
        - moderator
      example: guest
    EmailOnlyUser:
      type: object
      description: User profile with only email and avatar url
      required:
        - email
        - avatar_url
      properties:
        avatar_url:
          type: string
          description: Avatar url of the user
        email:
          type: string
          description: Email of the user
      example:
        avatar_url: https://secure.gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
        email: alice@example.com
    ErrorBody:
      oneOf:
        - $ref: '#/components/schemas/StandardErrorBody'
        - $ref: '#/components/schemas/ValidationErrorBody'
      description: The body of an error response
    EventAndInstanceId:
      type: string
      description: An event id and an instance id
      example: 00000000-0000-0000-0000-004433221100_20240705T170242Z
    EventDescription:
      type: string
      description: The description of an event
      example: The Weekly Team Event
      maxLength: 4096
    EventExceptionResource:
      type: object
      description: >-
        Event exception resource


        Overrides event properties for a event recurrence. May only exist for
        events of type `recurring`.
      required:
        - id
        - recurring_event_id
        - instance_id
        - created_by
        - created_at
        - updated_by
        - updated_at
        - original_starts_at
        - type
        - status
        - can_edit
      properties:
        can_edit:
          type: boolean
          description: Can the current user edit this resource
        created_at:
          $ref: '#/components/schemas/Timestamp'
        created_by:
          $ref: '#/components/schemas/PublicUserProfile'
        description:
          allOf:
            - $ref: '#/components/schemas/EventDescription'
        ends_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        id:
          $ref: '#/components/schemas/EventAndInstanceId'
        instance_id:
          $ref: '#/components/schemas/InstanceId'
        is_all_day:
          type: boolean
          description: Override the `is_all_day` property of the instance
        original_starts_at:
          $ref: '#/components/schemas/DateTimeTz'
        recurring_event_id:
          $ref: '#/components/schemas/EventId'
        starts_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        status:
          $ref: '#/components/schemas/EventStatus'
        title:
          allOf:
            - $ref: '#/components/schemas/EventTitle'
        type:
          $ref: '#/components/schemas/EventType'
        updated_at:
          $ref: '#/components/schemas/Timestamp'
        updated_by:
          $ref: '#/components/schemas/PublicUserProfile'
      example:
        can_edit: false
        created_at: '2024-07-20T14:16:19Z'
        created_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
        description: The Weekly Team Event
        ends_at:
          datetime: '2024-07-05T17:00:00Z'
          timezone: Europe/Berlin
        id: 00000000-0000-0000-0000-004433221100_20240705T170242Z
        instance_id: 20240705T170242Z
        is_all_day: false
        original_starts_at:
          datetime: '2024-07-05T16:00:00Z'
          timezone: Europe/Berlin
        recurring_event_id: 00000000-0000-0000-0000-004433221100
        starts_at:
          datetime: '2024-07-05T15:00:00Z'
          timezone: Europe/Berlin
        status: ok
        title: Team Event
        type: instance
        updated_at: '2024-07-20T14:16:19Z'
        updated_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
    EventId:
      type: string
      format: uuid
      description: The identifier of an event
      example: 00000000-0000-0000-0000-004433221100
    EventInfo:
      type: object
      description: Information about an event
      required:
        - id
        - room_id
        - title
        - is_adhoc
        - e2e_encryption
      properties:
        e2e_encryption:
          type: boolean
          description: >-
            Indicates whether the meeting room should have e2e encryption
            enabled.
        id:
          $ref: '#/components/schemas/EventId'
        is_adhoc:
          type: boolean
          description: True if the event was created ad-hoc
        meeting_details:
          allOf:
            - $ref: '#/components/schemas/MeetingDetails'
        room_id:
          $ref: '#/components/schemas/RoomId'
        title:
          $ref: '#/components/schemas/EventTitle'
      example:
        e2e_encryption: false
        id: 00000000-0000-0000-0000-004433221100
        is_adhoc: false
        meeting_details:
          call_in:
            id: '1234567890'
            password: '0987654321'
            tel: +555-123-456-789
          invite_code_id: 00000000-0000-0000-0000-0000deadbeef
          streaming_links:
            - name: My OwnCast Stream
              url: https://owncast.example.com/mystream
        room_id: 00000000-0000-0000-0000-0000abadcafe
        title: Team Event
    EventInstance:
      type: object
      description: |-
        Event instance resource

        An event instance is an occurrence of an recurring event

        Exceptions for the instance are always already applied

        For infos on undocumented fields see [`EventResource`]

        [`EventResource`]: ../event_ressource/struct.EventResource.html
      required:
        - id
        - recurring_event_id
        - instance_id
        - created_by
        - created_at
        - updated_by
        - updated_at
        - title
        - description
        - room
        - invitees_truncated
        - invitees
        - is_all_day
        - starts_at
        - ends_at
        - type
        - status
        - invite_status
        - is_favorite
        - can_edit
      properties:
        can_edit:
          type: boolean
          description: Fkag to indicate if the current user can edit the event
        created_at:
          $ref: '#/components/schemas/Timestamp'
        created_by:
          $ref: '#/components/schemas/PublicUserProfile'
        description:
          $ref: '#/components/schemas/EventDescription'
        ends_at:
          $ref: '#/components/schemas/DateTimeTz'
        id:
          $ref: '#/components/schemas/EventAndInstanceId'
        instance_id:
          $ref: '#/components/schemas/InstanceId'
        invite_status:
          $ref: '#/components/schemas/EventInviteStatus'
        invitees:
          type: array
          items:
            $ref: '#/components/schemas/EventInvitee'
          description: >-
            List of event invitees and their invite status. Might not be
            complete, see `invite_truncated`
        invitees_truncated:
          type: boolean
          description: >-
            Flag which indicates if `invitees` contains all invites as far as
            known to the application
        is_all_day:
          type: boolean
          description: Flag indicating whether the event is all-day
        is_favorite:
          type: boolean
          description: Flag to indicate if the event is a favorite of the current user
        recurring_event_id:
          $ref: '#/components/schemas/EventId'
        room:
          $ref: '#/components/schemas/EventRoomInfo'
        shared_folder:
          allOf:
            - $ref: '#/components/schemas/SharedFolder'
        starts_at:
          $ref: '#/components/schemas/DateTimeTz'
        status:
          $ref: '#/components/schemas/EventStatus'
        title:
          $ref: '#/components/schemas/EventTitle'
        type:
          $ref: '#/components/schemas/EventType'
        updated_at:
          $ref: '#/components/schemas/Timestamp'
        updated_by:
          $ref: '#/components/schemas/PublicUserProfile'
      example:
        can_edit: false
        created_at: '2024-07-20T14:16:19Z'
        created_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
        description: The Weekly Team Event
        ends_at:
          datetime: '2024-07-22T11:00:00Z'
          timezone: Europe/Berlin
        id: 00000000-0000-0000-0000-004433221100_20240705T170242Z
        instance_id: 20240705T170242Z
        invite_status: pending
        invitees:
          - profile:
              avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
              display_name: Alice Adams
              email: alice@example.com
              firstname: Alice
              id: 00000000-0000-0000-0000-0000000a11c3
              kind: registered
              lastname: Adams
              role: user
              title: ''
            status: accepted
        invitees_truncated: true
        is_all_day: false
        is_favorite: false
        recurring_event_id: 00000000-0000-0000-0000-004433221100
        room:
          call_in:
            id: '1234567890'
            password: '9876543210'
            tel: +555-12345-67890
          e2e_encryption: false
          id: 00000000-0000-0000-0000-0000abadcafe
          password: v3rys3cr3t
          waiting_room: false
        shared_folder:
          read:
            password: v3rys3cr3t
            url: https://cloud.example.com/shares/abc123
        starts_at:
          datetime: '2024-07-22T10:00:00Z'
          timezone: Europe/Berlin
        status: ok
        title: Team Event
        type: recurring
        updated_at: '2024-07-20T14:16:19Z'
        updated_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
    EventInviteStatus:
      type: string
      enum:
        - pending
        - accepted
        - tentative
        - declined
      example: accepted
    EventInvitee:
      type: object
      description: |-
        Invitee to an event

        Contains user profile and invitee status
      required:
        - profile
        - status
      properties:
        profile:
          $ref: '#/components/schemas/EventInviteeProfile'
        status:
          $ref: '#/components/schemas/EventInviteStatus'
      example:
        profile:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          kind: registered
          lastname: Adams
          role: user
          title: ''
        status: accepted
    EventInviteeProfile:
      oneOf:
        - allOf:
            - $ref: '#/components/schemas/PublicInviteUserProfile'
            - type: object
              required:
                - kind
              properties:
                kind:
                  type: string
                  enum:
                    - registered
        - allOf:
            - $ref: '#/components/schemas/UnregisteredUser'
            - type: object
              required:
                - kind
              properties:
                kind:
                  type: string
                  enum:
                    - unregistered
        - allOf:
            - $ref: '#/components/schemas/EmailOnlyUser'
            - type: object
              required:
                - kind
              properties:
                kind:
                  type: string
                  enum:
                    - email
      description: Profile of an event invitee
      example:
        avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
        display_name: Alice Adams
        email: alice@example.com
        firstname: Alice
        id: 00000000-0000-0000-0000-0000000a11c3
        kind: registered
        lastname: Adams
        role: user
        title: ''
      discriminator:
        propertyName: kind
    EventOrException:
      oneOf:
        - $ref: '#/components/schemas/EventResource'
        - $ref: '#/components/schemas/EventExceptionResource'
      description: Return type of the `GET /events` endpoint
      example:
        can_edit: false
        created_at: '2024-07-20T14:16:19Z'
        created_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
        description: The Weekly Team Event
        id: 00000000-0000-0000-0000-004433221100
        invite_status: accepted
        invitees:
          - profile:
              avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
              display_name: Alice Adams
              email: alice@example.com
              firstname: Alice
              id: 00000000-0000-0000-0000-0000000a11c3
              kind: registered
              lastname: Adams
              role: user
              title: ''
            status: accepted
        invitees_truncated: false
        is_adhoc: false
        is_favorite: false
        is_time_independent: false
        room:
          call_in:
            id: '1234567890'
            password: '9876543210'
            tel: +555-12345-67890
          e2e_encryption: false
          id: 00000000-0000-0000-0000-0000abadcafe
          password: v3rys3cr3t
          waiting_room: false
        shared_folder:
          read:
            password: v3rys3cr3t
            url: https://cloud.example.com/shares/abc123
        show_meeting_details: true
        starts_at:
          datetime: '2024-07-05T17:02:42Z'
          timezone: Europe/Berlin
        streaming_targets:
          - id: 00000000-0000-0000-0000-000043434343
            kind: custom
            name: Example Stream
            public_url: https://streaming.example.com/livestream123
            streaming_endpoint: https://ingress.streaming.example.com/
            streaming_key: aabbccddeeff
        title: Team Event
        type: single
        updated_at: '2024-07-20T14:16:19Z'
        updated_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
    EventResource:
      type: object
      description: |-
        Event Resource representation

        Returned from `GET /events/` and `GET /events/{event_id}`
      required:
        - id
        - created_by
        - created_at
        - updated_by
        - updated_at
        - title
        - description
        - room
        - invitees_truncated
        - invitees
        - is_time_independent
        - is_adhoc
        - type
        - invite_status
        - is_favorite
        - can_edit
        - show_meeting_details
      properties:
        can_edit:
          type: boolean
          description: Can the current user edit this resource
        created_at:
          $ref: '#/components/schemas/Timestamp'
        created_by:
          $ref: '#/components/schemas/PublicUserProfile'
        description:
          $ref: '#/components/schemas/EventDescription'
        ends_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        id:
          $ref: '#/components/schemas/EventId'
        invite_status:
          $ref: '#/components/schemas/EventInviteStatus'
        invitees:
          type: array
          items:
            $ref: '#/components/schemas/EventInvitee'
          description: >-
            List of event invitees and their invite status. Might not be
            complete, see `invite_truncated`
        invitees_truncated:
          type: boolean
          description: >-
            Flag which indicates if `invitees` contains all invites as far as
            known to the application

            May also be true if there are no invitees but no invitees were
            requested
        is_adhoc:
          type: boolean
          description: Flag indicating whether the event is ad-hoc created.
        is_all_day:
          type: boolean
          description: |-
            Is the event an all day event

            All-day events have no start/end time, they last the entire day(s)
        is_favorite:
          type: boolean
          description: Is this event in the current user's favorite list?
        is_time_independent:
          type: boolean
          description: >-
            Is the event time independent?


            Time independent events are not bound to any time but instead are
            constantly available to join
        recurrence_pattern:
          $ref: '#/components/schemas/RecurrencePattern'
        room:
          $ref: '#/components/schemas/EventRoomInfo'
        shared_folder:
          allOf:
            - $ref: '#/components/schemas/SharedFolder'
        show_meeting_details:
          type: boolean
          description: >-
            Indicates whether meeting details should be provided. If absent, no
            meeting details are made available.
        starts_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        streaming_targets:
          type: array
          items:
            $ref: '#/components/schemas/RoomStreamingTarget'
          description: The streaming targets of the room associated with the event
        title:
          $ref: '#/components/schemas/EventTitle'
        type:
          $ref: '#/components/schemas/EventType'
        updated_at:
          $ref: '#/components/schemas/Timestamp'
        updated_by:
          $ref: '#/components/schemas/PublicUserProfile'
      example:
        can_edit: false
        created_at: '2024-07-20T14:16:19Z'
        created_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
        description: The Weekly Team Event
        id: 00000000-0000-0000-0000-004433221100
        invite_status: accepted
        invitees:
          - profile:
              avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
              display_name: Alice Adams
              email: alice@example.com
              firstname: Alice
              id: 00000000-0000-0000-0000-0000000a11c3
              kind: registered
              lastname: Adams
              role: user
              title: ''
            status: accepted
        invitees_truncated: false
        is_adhoc: false
        is_favorite: false
        is_time_independent: false
        room:
          call_in:
            id: '1234567890'
            password: '9876543210'
            tel: +555-12345-67890
          e2e_encryption: false
          id: 00000000-0000-0000-0000-0000abadcafe
          password: v3rys3cr3t
          waiting_room: false
        shared_folder:
          read:
            password: v3rys3cr3t
            url: https://cloud.example.com/shares/abc123
        show_meeting_details: true
        starts_at:
          datetime: '2024-07-05T17:02:42Z'
          timezone: Europe/Berlin
        streaming_targets:
          - id: 00000000-0000-0000-0000-000043434343
            kind: custom
            name: Example Stream
            public_url: https://streaming.example.com/livestream123
            streaming_endpoint: https://ingress.streaming.example.com/
            streaming_key: aabbccddeeff
        title: Team Event
        type: single
        updated_at: '2024-07-20T14:16:19Z'
        updated_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
    EventRoomInfo:
      type: object
      description: All information about a room in which an event takes place
      required:
        - id
        - waiting_room
      properties:
        call_in:
          allOf:
            - $ref: '#/components/schemas/CallInInfo'
        e2e_encryption:
          type: boolean
          description: Flag to check if the room has e2e encryption enabled
        id:
          $ref: '#/components/schemas/RoomId'
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
        waiting_room:
          type: boolean
          description: Flag to check if the room has a waiting room enabled
      example:
        call_in:
          id: '1234567890'
          password: '9876543210'
          tel: +555-12345-67890
        e2e_encryption: false
        id: 00000000-0000-0000-0000-0000abadcafe
        password: v3rys3cr3t
        waiting_room: false
    EventStatus:
      type: string
      description: Status of an event
      enum:
        - ok
        - cancelled
      example: ok
    EventTitle:
      type: string
      description: The title of an event
      example: Team Event
      maxLength: 255
    EventType:
      type: string
      description: |-
        Type of event resource.

        Is used as type discriminator in field `type`.
      enum:
        - single
        - recurring
        - instance
        - exception
      example: single
    FeatureId:
      type: string
      description: A feature identifier
      example: myfeature
      maxLength: 255
      minLength: 1
      pattern: ^[-_0-9a-zA-Z]*$
    FileExtension:
      type: string
      description: An extension for a file path
      example: pdf
      maxLength: 10
      pattern: ^[0-9a-zA-Z]*$
    GetEventInstanceResponseBody:
      $ref: '#/components/schemas/EventInstance'
    GetEventInstancesCursor:
      type: string
      description: An encoded cursor pointing to a position in a series of elements
    GetEventInstancesResponseBody:
      type: array
      items:
        $ref: '#/components/schemas/EventInstance'
      description: Response for *GET /events/{event_id}/instances*
      example:
        - can_edit: false
          created_at: '2024-07-20T14:16:19Z'
          created_by:
            avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
            display_name: Alice Adams
            email: alice@example.com
            firstname: Alice
            id: 00000000-0000-0000-0000-0000000a11c3
            lastname: Adams
            title: ''
          description: The Weekly Team Event
          ends_at:
            datetime: '2024-07-22T11:00:00Z'
            timezone: Europe/Berlin
          id: 00000000-0000-0000-0000-004433221100_20240705T170242Z
          instance_id: 20240705T170242Z
          invite_status: pending
          invitees:
            - profile:
                avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
                display_name: Alice Adams
                email: alice@example.com
                firstname: Alice
                id: 00000000-0000-0000-0000-0000000a11c3
                kind: registered
                lastname: Adams
                role: user
                title: ''
              status: accepted
          invitees_truncated: true
          is_all_day: false
          is_favorite: false
          recurring_event_id: 00000000-0000-0000-0000-004433221100
          room:
            call_in:
              id: '1234567890'
              password: '9876543210'
              tel: +555-12345-67890
            e2e_encryption: false
            id: 00000000-0000-0000-0000-0000abadcafe
            password: v3rys3cr3t
            waiting_room: false
          shared_folder:
            read:
              password: v3rys3cr3t
              url: https://cloud.example.com/shares/abc123
          starts_at:
            datetime: '2024-07-22T10:00:00Z'
            timezone: Europe/Berlin
          status: ok
          title: Team Event
          type: recurring
          updated_at: '2024-07-20T14:16:19Z'
          updated_by:
            avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
            display_name: Alice Adams
            email: alice@example.com
            firstname: Alice
            id: 00000000-0000-0000-0000-0000000a11c3
            lastname: Adams
            title: ''
    GetEventInvitesPendingResponse:
      type: object
      description: Response body for the `GET /users/me/pending_invites` endpoint
      required:
        - total_pending_invites
      properties:
        total_pending_invites:
          type: integer
          format: int32
          description: The total number of pending invites for the current user
          minimum: 0
      example:
        total_pending_invites: 3
    GetFindResponse:
      type: array
      items:
        $ref: '#/components/schemas/GetFindResponseItem'
      description: The response for the find endpoint
    GetFindResponseItem:
      oneOf:
        - allOf:
            - $ref: '#/components/schemas/PublicUserProfile'
            - type: object
              required:
                - kind
              properties:
                kind:
                  type: string
                  enum:
                    - registered
        - allOf:
            - $ref: '#/components/schemas/UnregisteredUser'
            - type: object
              required:
                - kind
              properties:
                kind:
                  type: string
                  enum:
                    - unregistered
      description: The response for users found
      discriminator:
        propertyName: kind
    GetLoginResponse:
      type: object
      description: Body of the response to a *GET* request on `/auth/login`
      required:
        - oidc
      properties:
        oidc:
          $ref: '#/components/schemas/OidcProvider'
    GetRoomStreamingTargetResponse:
      $ref: '#/components/schemas/RoomStreamingTarget'
    GetRoomStreamingTargetsResponse:
      type: array
      items:
        $ref: '#/components/schemas/RoomStreamingTarget'
      description: The body of a *GET /rooms/{room_id}/streaming_targets* response
      example:
        - id: 00000000-0000-0000-0000-000043434343
          kind: custom
          name: Example Stream
          public_url: https://streaming.example.com/livestream123
          streaming_endpoint: https://ingress.streaming.example.com/
          streaming_key: aabbccddeeff
    GetRoomsAssetsResponseBody:
      type: array
      items:
        $ref: '#/components/schemas/AssetResource'
      description: Response for *GET /rooms/{room_id}/assets*
      example:
        - created_at: '2024-06-18T11:22:33Z'
          filename: recording.webm
          id: 00000000-0000-0000-0000-0000aabbcc00
          kind: record
          namespace: recording
          size: 98765432
    GetRoomsInvitesResponseBody:
      type: array
      items:
        $ref: '#/components/schemas/InviteResource'
      description: Response for *GET /rooms/{room_id}/invites*
      example:
        - active: true
          created: '2024-06-18T11:22:33Z'
          created_by:
            avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
            display_name: Alice Adams
            email: alice@example.com
            firstname: Alice
            id: 00000000-0000-0000-0000-0000000a11c3
            lastname: Adams
            title: ''
          expiration: null
          invite_code: 00000000-0000-0000-0000-0000deadbeef
          room_id: 00000000-0000-0000-0000-0000abadcafe
          updated: '2024-06-20T14:16:19Z'
          updated_by:
            avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
            display_name: Alice Adams
            email: alice@example.com
            firstname: Alice
            id: 00000000-0000-0000-0000-0000000a11c3
            lastname: Adams
            title: ''
    GetRoomsResponse:
      type: array
      items:
        $ref: '#/components/schemas/RoomResource'
      description: The JSON body returned by the `/rooms` `GET` endpoint
    GetTurnServersResponse:
      type: array
      items:
        $ref: '#/components/schemas/IceServer'
      description: Response to the *GET /turn* endpoint request
    GetUserAssetsResponse:
      type: object
      description: Response body for the `GET /v1/users/me/assets` endpoint
      required:
        - owned_assets
      properties:
        owned_assets:
          type: array
          items:
            $ref: '#/components/schemas/UserAssetResource'
          description: Assets owned by the user
      example:
        owned_assets:
          - created_at: '2024-06-18T11:22:33Z'
            event_id: 00000000-0000-0000-0000-004433221100
            filename: recording.webm
            id: 00000000-0000-0000-0000-0000aabbcc00
            kind: record
            namespace: recording
            room_id: 00000000-0000-0000-0000-0000abadcafe
            size: 98765432
    IceServer:
      oneOf:
        - $ref: '#/components/schemas/Turn'
        - $ref: '#/components/schemas/Stun'
      description: Description of an ICE server
    InstanceId:
      type: string
      description: An event instance id
      example: '2024-07-20T15:23:42+00:00'
    InviteCode:
      type: string
      format: uuid
      description: An invite code
      example: 00000000-0000-0000-0000-0000deadbeef
    InviteResource:
      type: object
      description: A room invite code with associated information.
      required:
        - invite_code
        - created
        - created_by
        - updated
        - updated_by
        - room_id
        - active
      properties:
        active:
          type: boolean
          description: If the invite is active
        created:
          type: string
          format: date-time
          description: The timestamp this invite was created at
        created_by:
          $ref: '#/components/schemas/PublicUserProfile'
        expiration:
          type: string
          format: date-time
          description: Optional expiration date of the invite
          nullable: true
        invite_code:
          $ref: '#/components/schemas/InviteCode'
        room_id:
          $ref: '#/components/schemas/RoomId'
        updated:
          type: string
          format: date-time
          description: The timestamp this invite was updated at
        updated_by:
          $ref: '#/components/schemas/PublicUserProfile'
      example:
        active: true
        created: '2024-06-18T11:22:33Z'
        created_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
        expiration: null
        invite_code: 00000000-0000-0000-0000-0000deadbeef
        room_id: 00000000-0000-0000-0000-0000abadcafe
        updated: '2024-06-20T14:16:19Z'
        updated_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
    InviteRole:
      type: string
      enum:
        - user
        - moderator
      example: user
    MeetingDetails:
      type: object
      description: Details about meeting
      properties:
        call_in:
          allOf:
            - $ref: '#/components/schemas/CallInInfo'
        invite_code_id:
          allOf:
            - $ref: '#/components/schemas/InviteCode'
        streaming_links:
          type: array
          items:
            $ref: '#/components/schemas/StreamingLink'
          description: The links for accessing the stream
      example:
        call_in:
          id: '1234567890'
          password: '0987654321'
          tel: +555-123-456-789
        invite_code_id: 00000000-0000-0000-0000-0000deadbeef
        streaming_links:
          - name: My OwnCast Stream
            url: https://owncast.example.com/mystream
    ModuleFeatureId:
      anyOf:
        - type: string
          description: A feature identifier
          example: myfeature
          maxLength: 255
          minLength: 1
          pattern: ^[-_0-9a-zA-Z]*$
        - type: string
          description: A module feature identifier
          example: mymodule::myfeature
          pattern: ^[-_0-9a-zA-Z]{1,255}::[-_0-9a-zA-Z]{1,255}$
      example: mymodule::myfeature
    ModuleId:
      anyOf:
        - type: string
          description: A module identifier
          example: mymodule
          maxLength: 255
          minLength: 1
          pattern: ^[-_0-9a-zA-Z]*$
      default: core
      example: mymodule
    NumericId:
      type: string
      description: A string containing number characters
      example: '0000000000'
      maxLength: 10
      minLength: 10
      pattern: '[0-9]+'
    OidcProvider:
      type: object
      description: Represents an OIDC provider
      required:
        - name
        - url
      properties:
        name:
          type: string
          description: The name of the provider
        url:
          type: string
          description: The url of the provider
    Ordering:
      type: string
      description: The sorting order that should be applied
      enum:
        - ascending
        - descending
    PageLink:
      type: string
      example: >-
        <https://api.example.org/resource?page=2>; rel='next',
        <https://api.example.org/resource?page=5>; rel='last'
    PatchEmailInviteBody:
      type: object
      description: Request body for the `PATCH /events/{event_id}/invites/email` endpoint
      required:
        - email
      properties:
        email:
          $ref: '#/components/schemas/EmailAddress'
        role:
          allOf:
            - $ref: '#/components/schemas/EmailInviteRole'
          nullable: true
    PatchEventBody:
      type: object
      description: Body for the `PATCH /events/{event_id}` endpoint
      properties:
        description:
          allOf:
            - $ref: '#/components/schemas/EventDescription'
        e2e_encryption:
          type: boolean
          description: Patch whether the event is encrypted
        ends_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        has_shared_folder:
          type: boolean
          description: >-
            Either add a shared folder to the event, if none existed before or
            delete the shared folder
        is_adhoc:
          type: boolean
          description: Patch the adhoc flag.
        is_all_day:
          type: boolean
          description: >-
            Patch if the event is an all-day event


            If it changes the value from false to true this request must ensure

            that the `starts_at.datetime` and `ends_at.datetime` have a 00:00
            time part.
        is_time_independent:
          type: boolean
          description: |-
            Patch the time independence of the event

            If it changes the independence from true false this body has to have
            `is_all_day`, `starts_at` and `ends_at` set
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
        recurrence_pattern:
          allOf:
            - $ref: '#/components/schemas/RecurrencePattern'
        show_meeting_details:
          type: boolean
          description: Patch wether the meeting details are displayed or not
        starts_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        streaming_targets:
          type: array
          items:
            $ref: '#/components/schemas/StreamingTarget'
          description: The streaming targets of the room associated with the event
        title:
          allOf:
            - $ref: '#/components/schemas/EventTitle'
        waiting_room:
          type: boolean
          description: Patch the presence of a waiting room
      example:
        description: The new description
        has_shared_folder: true
        show_meeting_details: false
        title: The new title
    PatchEventInstanceBody:
      type: object
      description: Request body for the `PATCH /events/{event_id}/{instance_id}` endpoint
      properties:
        description:
          allOf:
            - $ref: '#/components/schemas/EventDescription'
        ends_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        is_all_day:
          type: boolean
          description: Flag to indicate if the event is all-day
        starts_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        status:
          allOf:
            - $ref: '#/components/schemas/EventStatus'
        title:
          allOf:
            - $ref: '#/components/schemas/EventTitle'
      example:
        is_all_day: false
        status: cancelled
        title: Early morning meeting
    PatchInviteBody:
      type: object
      description: >-
        Request body for the `PATCH /events/{event_id}/invites/{user_id}`
        endpoint
      properties:
        role:
          allOf:
            - $ref: '#/components/schemas/InviteRole'
      example:
        role: moderator
    PatchMeBody:
      type: object
      description: Used to modify user settings.
      properties:
        conference_theme:
          type: string
          description: The conference theme
          nullable: true
        dashboard_theme:
          type: string
          description: The dashboard theme
          nullable: true
        display_name:
          type: string
          description: The user's display name
          nullable: true
        language:
          type: string
          description: The user's language
          nullable: true
        title:
          type: string
          description: The user's title
          nullable: true
      example:
        conference_theme: null
        dashboard_theme: null
        display_name: Alice Adams
        language: en
        title: null
    PatchRoomsRequestBody:
      type: object
      description: API request parameters to patch a room
      properties:
        e2e_encryption:
          type: boolean
          description: If e2e encryption is enabled
          nullable: true
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
          nullable: true
        waiting_room:
          type: boolean
          description: If waiting room is enabled
          nullable: true
    PostEventInviteBody:
      oneOf:
        - $ref: '#/components/schemas/UserInvite'
        - $ref: '#/components/schemas/EmailInvite'
      description: Request body for the `POST /events/{event_id}/invites` endpoint
      example:
        invitee: 00000009-9889-9889-9889-988000000000
        role: user
    PostEventsBody:
      type: object
      description: Body of the `POST /events` endpoint
      required:
        - title
        - description
        - is_time_independent
      properties:
        description:
          $ref: '#/components/schemas/EventDescription'
        e2e_encryption:
          type: boolean
          description: Should the created event be encrypted?
        ends_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        has_shared_folder:
          type: boolean
          description: Should the created event have a shared folder?
        is_adhoc:
          type: boolean
          description: Is this an ad-hoc chatroom?
        is_all_day:
          type: boolean
          description: >-
            Should the event be all-day?


            If true, requires `starts_at.datetime` and `ends_at.datetime` to
            have a 00:00 time part
        is_time_independent:
          type: boolean
          description: |-
            Should the created event be time independent?

            If true, all following fields must be null
            If false, requires `is_all_day`, `starts_at`, `ends_at`
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
        recurrence_pattern:
          $ref: '#/components/schemas/RecurrencePattern'
        show_meeting_details:
          type: boolean
          description: Should it be able to show the meeting details?
        starts_at:
          allOf:
            - $ref: '#/components/schemas/DateTimeTz'
        streaming_targets:
          type: array
          items:
            $ref: '#/components/schemas/StreamingTarget'
          description: The streaming targets of the room associated with the event
        title:
          $ref: '#/components/schemas/EventTitle'
        waiting_room:
          type: boolean
          description: Should the created event have a waiting room?
      example:
        description: The weekly teammeeting
        e2e_encryption: false
        ends_at:
          datetime: '2024-07-22T11:00:00Z'
          timezone: Europe/Berlin
        has_shared_folder: false
        is_adhoc: false
        is_time_independent: false
        password: v3rys3cr3t
        recurrence_pattern:
          - FREQ=WEEKLY;INTERVAL=1;BYDAY=MO
        show_meeting_details: true
        starts_at:
          datetime: '2024-07-22T10:00:00Z'
          timezone: Europe/Berlin
        streaming_targets:
          - kind: custom
            name: Example Stream
            public_url: https://streaming.example.com/livestream123
            streaming_endpoint: https://ingress.streaming.example.com/
            streaming_key: aabbccddeeff
        title: Teammeeting
        waiting_room: false
    PostInviteRequestBody:
      type: object
      description: Body for *POST /rooms/{room_id}/invites*
      properties:
        expiration:
          type: string
          format: date-time
          description: Optional expiration date of the invite
          nullable: true
      example:
        expiration: '2024-06-20T14:16:19Z'
    PostInviteVerifyRequestBody:
      type: object
      description: Verify body for *POST /invite/verify*
      required:
        - invite_code
      properties:
        invite_code:
          $ref: '#/components/schemas/InviteCode'
    PostLoginRequestBody:
      type: object
      description: Body of a *POST* request on `/auth/login`
      required:
        - id_token
      properties:
        id_token:
          type: string
          description: The id token to use for the login
          example: bG9yZW0gaXBzdW0sIHF1aWEgZG9sb3Igc2
    PostLoginResponse:
      type: object
      description: Body of the response to a *POST* request on `/auth/login`
      required:
        - permissions
      properties:
        permissions:
          type: array
          items:
            type: string
          description: >-
            Permissions is a set of strings that each define a permission a user
            has.
          uniqueItems: true
    PostRoomStreamingTargetRequest:
      $ref: '#/components/schemas/StreamingTarget'
    PostRoomStreamingTargetResponse:
      $ref: '#/components/schemas/RoomStreamingTarget'
    PostRoomsRequestBody:
      type: object
      description: API request parameters to create a new room
      properties:
        e2e_encryption:
          type: boolean
          description: >-
            Enable/Disable e2e encryption for this room; defaults to false when
            not set
        enable_sip:
          type: boolean
          description: Enable/Disable sip for this room; defaults to false when not set
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
          nullable: true
        waiting_room:
          type: boolean
          description: >-
            Indicates whether the meeting room should have the waiting room
            enabled.

            When not present, the waiting room will be disabled.
    PostRoomsStartInvitedRequestBody:
      type: object
      description: >-
        The JSON body expected when making a *POST
        /rooms/{room_id}/start_invited*
      required:
        - invite_code
      properties:
        breakout_room:
          allOf:
            - $ref: '#/components/schemas/BreakoutRoomId'
        invite_code:
          type: string
          description: The invite code
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
        resumption:
          allOf:
            - $ref: '#/components/schemas/ResumptionToken'
      example:
        breakout_room: 00000000-0000-0000-0000-0000badcab1e
        invite_code: 00000000-0000-0000-0000-0000deadbeef
        password: v3rys3cr3t
        resumption: 654321zyxwvutsrqponmlkjihgfedcba654321zyxwvutsrqponmlkjihgfedcba
    PostRoomsStartRequestBody:
      type: object
      description: The JSON body expected when making a *POST /rooms/{room_id}/start*
      properties:
        breakout_room:
          allOf:
            - $ref: '#/components/schemas/BreakoutRoomId'
        resumption:
          allOf:
            - $ref: '#/components/schemas/ResumptionToken'
      example:
        breakout_room: 00000000-0000-0000-0000-00000badcafe
        resumption: 654321zyxwvutsrqponmlkjihgfedcba654321zyxwvutsrqponmlkjihgfedcba
    PrivateUserProfile:
      type: object
      description: >-
        Private user profile.


        Similar to [`PublicUserProfile`], but contains additional "private"
        information about a user.

        Is only accessible to the user himself.

        Is used on */users/me* endpoints.
      required:
        - id
        - email
        - title
        - firstname
        - lastname
        - display_name
        - avatar_url
        - dashboard_theme
        - conference_theme
        - language
        - tariff_status
        - used_storage
      properties:
        avatar_url:
          type: string
          description: The user's avatar URL
        conference_theme:
          type: string
          description: The conference theme
        dashboard_theme:
          type: string
          description: The dashboard theme
        display_name:
          type: string
          description: The user's display name
        email:
          type: string
          description: The email of the user
        firstname:
          type: string
          description: The user's first name
        id:
          $ref: '#/components/schemas/UserId'
        language:
          type: string
          description: The language for the user
        lastname:
          type: string
          description: The user's last name
        tariff_status:
          $ref: '#/components/schemas/TariffStatus'
        title:
          type: string
          description: The title of the user
        used_storage:
          type: integer
          format: int64
          description: The user's used storage
          minimum: 0
    PublicInviteUserProfile:
      allOf:
        - $ref: '#/components/schemas/PublicUserProfile'
        - type: object
          required:
            - role
          properties:
            role:
              $ref: '#/components/schemas/InviteRole'
      description: Profile of a public event invitee
      example:
        avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
        display_name: Alice Adams
        email: alice@example.com
        firstname: Alice
        id: 00000000-0000-0000-0000-0000000a11c3
        lastname: Adams
        role: user
        title: ''
    PublicUserProfile:
      type: object
      description: >-
        Public user details.


        Contains general "public" information about a user. Is accessible to all
        other users.
      required:
        - id
        - email
        - title
        - firstname
        - lastname
        - display_name
        - avatar_url
      properties:
        avatar_url:
          type: string
          description: The user's avatar URL
        display_name:
          type: string
          description: The user's display name
        email:
          type: string
          description: The email of the user
        firstname:
          type: string
          description: The user's first name
        id:
          $ref: '#/components/schemas/UserId'
        lastname:
          type: string
          description: The user's last name
        title:
          type: string
          description: The title of the user
      example:
        avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
        display_name: Alice Adams
        email: alice@example.com
        firstname: Alice
        id: 00000000-0000-0000-0000-0000000a11c3
        lastname: Adams
        title: ''
    PutInviteRequestBody:
      type: object
      description: Body for *PUT /rooms/{room_id}/invites/{invite_code}*
      properties:
        expiration:
          type: string
          format: date-time
          description: Optional expiration date of the invite
          nullable: true
      example:
        expiration: '2024-06-20T14:16:19Z'
    PutSipConfig:
      type: object
      description: Body for the `PUT /rooms/{room_id}/sip` endpoint
      properties:
        lobby:
          type: boolean
          description: >-
            Enable or disable the lobby for users that join throughh SIP.
            Defaults

            to [`false`] when not explicity set on creation.
        password:
          allOf:
            - $ref: '#/components/schemas/CallInPassword'
      example:
        lobby: true
        password: '9876543210'
    RecurrencePattern:
      type: array
      items:
        $ref: '#/components/schemas/RecurrenceRule'
      description: A recurrence pattern containing recurrence rules
      example:
        - FREQ=WEEKLY;INTERVAL=1;BYDAY=MO
      maxItems: 4
      minItems: 1
    RecurrenceRule:
      type: string
      description: A recurrence rule according to RFC5545
      example: FREQ=WEEKLY;INTERVAL=1;BYDAY=MO
      maxLength: 1024
    ResumptionToken:
      type: string
      description: A resumption token
    RoomId:
      type: string
      format: uuid
      description: The id of a room
      example: 00000000-0000-0000-0000-0000abadcafe
    RoomPassword:
      type: string
      description: A room password
      example: v3rys3cr3t
      maxLength: 255
      minLength: 1
    RoomResource:
      type: object
      description: >-
        A Room


        Contains all room information. Is only be accessible to the owner and
        users with

        appropriate permissions.
      required:
        - id
        - created_by
        - created_at
        - waiting_room
      properties:
        created_at:
          $ref: '#/components/schemas/Timestamp'
        created_by:
          $ref: '#/components/schemas/PublicUserProfile'
        id:
          $ref: '#/components/schemas/RoomId'
        password:
          allOf:
            - $ref: '#/components/schemas/RoomPassword'
        waiting_room:
          type: boolean
          description: If waiting room is enabled
      example:
        created_at: '1970-01-01T00:00:00Z'
        created_by:
          avatar_url: https://gravatar.com/avatar/c160f8cc69a4f0bf2b0362752353d060
          display_name: Alice Adams
          email: alice@example.com
          firstname: Alice
          id: 00000000-0000-0000-0000-0000000a11c3
          lastname: Adams
          title: ''
        id: 00000000-0000-0000-0000-000000000000
        password: v3rys3cr3t
        waiting_room: false
    RoomStreamingTarget:
      allOf:
        - $ref: '#/components/schemas/StreamingTarget'
        - type: object
          required:
            - id
          properties:
            id:
              $ref: '#/components/schemas/StreamingTargetId'
      description: A streaming target which is specific for a Room
      example:
        id: 00000000-0000-0000-0000-000043434343
        kind: custom
        name: Example Stream
        public_url: https://streaming.example.com/livestream123
        streaming_endpoint: https://ingress.streaming.example.com/
        streaming_key: aabbccddeeff
    RoomsStartResponse:
      type: object
      description: >-
        The JSON body returned from the start endpoints supporting session
        resumption
      required:
        - ticket
        - resumption
      properties:
        resumption:
          $ref: '#/components/schemas/ResumptionToken'
        ticket:
          $ref: '#/components/schemas/TicketToken'
      example:
        resumption: 654321zyxwvutsrqponmlkjihgfedcba654321zyxwvutsrqponmlkjihgfedcba
        ticket: abcdefghijklmnopqrstuvwxyz123456abcdefghijklmnopqrstuvwxyz123456
    ServiceStartResponse:
      type: object
      description: Response for `POST /**/**/start` endpoints
      required:
        - ticket
        - resumption
      properties:
        resumption:
          $ref: '#/components/schemas/ResumptionToken'
        ticket:
          $ref: '#/components/schemas/TicketToken'
    SharedFolder:
      type: object
      description: |-
        Information about a shared folder containing
        read and optional write access
      required:
        - read
      properties:
        read:
          $ref: '#/components/schemas/SharedFolderAccess'
        read_write:
          allOf:
            - $ref: '#/components/schemas/SharedFolderAccess'
      example:
        read:
          password: v3rys3cr3t
          url: https://cloud.example.com/shares/abc123
    SharedFolderAccess:
      type: object
      description: Information required to access a shared folder
      required:
        - url
        - password
      properties:
        password:
          type: string
          description: Password required to access the shared folder
        url:
          type: string
          description: Shared folder URL
      example:
        password: v3rys3cr3t
        url: https://cloud.example.com/shares/abc123
    SipConfigResource:
      type: object
      description: Response for the `GET /rooms/{room_id}/sip` endpoint
      required:
        - room
        - sip_id
        - password
        - lobby
      properties:
        lobby:
          type: boolean
          description: Flag if the room is a lobby
        password:
          $ref: '#/components/schemas/CallInPassword'
        room:
          $ref: '#/components/schemas/RoomId'
        sip_id:
          $ref: '#/components/schemas/CallInId'
      example:
        lobby: false
        password: '9876543210'
        room: 00000000-0000-0000-0000-0000abadcafe
        sip_id: '0123456789'
    StandardErrorBody:
      type: object
      description: Standard API error body
      required:
        - code
        - message
      properties:
        code:
          type: string
          description: Machine readable error code
        message:
          type: string
          description: Human readable message
    StartCallInRequestBody:
      type: object
      description: Body for the `POST /services/call_in/start` endpoint
      required:
        - id
        - pin
      properties:
        id:
          $ref: '#/components/schemas/CallInId'
        pin:
          $ref: '#/components/schemas/CallInPassword'
    StartRecordingRequestBody:
      type: object
      description: Response for the `POST /services/recording/start` endpoint
      required:
        - room_id
      properties:
        breakout_room:
          allOf:
            - $ref: '#/components/schemas/BreakoutRoomId'
          nullable: true
        room_id:
          $ref: '#/components/schemas/RoomId'
    StreamingKey:
      type: string
      description: The secret key of a streaming target
      example: aabbccddeeff
    StreamingLink:
      type: object
      description: Streaming link for an event
      required:
        - name
        - url
      properties:
        name:
          type: string
          description: The name of the streaming link
        url:
          type: string
          format: uri
          description: The url of the streaming link
      example:
        name: My OwnCast Stream
        url: https://owncast.example.com/mystream
    StreamingTarget:
      allOf:
        - $ref: '#/components/schemas/StreamingTargetKind'
        - type: object
          required:
            - name
          properties:
            name:
              type: string
              description: The name of the streaming target
      description: A streaming target
      example:
        kind: custom
        name: Example Stream
        public_url: https://streaming.example.com/livestream123
        streaming_endpoint: https://ingress.streaming.example.com/
        streaming_key: aabbccddeeff
    StreamingTargetId:
      type: string
      format: uuid
      description: ID of a streaming target
      example: 00000000-0000-0000-0000-000043434343
    StreamingTargetKind:
      oneOf:
        - type: object
          description: The "custom" kind
          required:
            - streaming_endpoint
            - streaming_key
            - public_url
            - kind
          properties:
            kind:
              type: string
              enum:
                - custom
            public_url:
              type: string
              format: uri
              description: The url from which the stream can be accessed
            streaming_endpoint:
              type: string
              format: uri
              description: The endpoint url of the streaming target
            streaming_key:
              $ref: '#/components/schemas/StreamingKey'
      description: A streaming target kind
      example:
        kind: custom
        public_url: https://streaming.example.com/livestream123
        streaming_endpoint: https://ingress.streaming.example.com/
        streaming_key: aabbccddeeff
      discriminator:
        propertyName: kind
    Stun:
      type: object
      description: STUN Server for users.
      required:
        - uris
      properties:
        uris:
          type: array
          items:
            type: string
          description: STUN URIs for this TURN server following rfc7065
    TariffId:
      type: string
      format: uuid
      description: The id of a tariff
    TariffModuleResource:
      type: object
      description: Tariff information related to a specific module
      required:
        - features
      properties:
        features:
          type: array
          items:
            $ref: '#/components/schemas/FeatureId'
          description: Enabled features for the tariff
          uniqueItems: true
    TariffResource:
      type: object
      description: Information related to a specific tariff
      required:
        - id
        - name
        - quotas
        - enabled_modules
        - disabled_features
        - modules
      properties:
        disabled_features:
          type: array
          items:
            $ref: '#/components/schemas/ModuleFeatureId'
          description: >-
            Disabled features for the tariff  (deprecated, use 'modules'
            instead)
          deprecated: true
          uniqueItems: true
        enabled_modules:
          type: array
          items:
            $ref: '#/components/schemas/ModuleId'
          description: Enabled modules for the tariff (deprecated, use 'modules' instead)
          deprecated: true
          uniqueItems: true
        id:
          $ref: '#/components/schemas/TariffId'
        modules:
          type: object
          description: Enabled modules for the tariff, including their enabled features
          additionalProperties:
            $ref: '#/components/schemas/TariffModuleResource'
        name:
          type: string
          description: The name of the tariff
        quotas:
          type: object
          description: The quotas of the tariff
          additionalProperties:
            type: integer
            format: int64
            minimum: 0
      example:
        disabled_features:
          - recording::stream
        enabled_modules:
          - chat
          - core
          - media
          - moderation
          - recording
        id: 00000000-0000-0000-0000-000000000000
        modules:
          chat:
            features: []
          core:
            features: []
          media:
            features: []
          moderation:
            features: []
          recording:
            features:
              - record
        name: Starter tariff
        quotas:
          max_storage: 50000
    TariffStatus:
      type: string
      enum:
        - default
        - paid
        - downgraded
    TicketToken:
      type: string
      description: A ticket token
    TimeZone:
      type: string
      description: A time zone
      example: Europe/Berlin
    Timestamp:
      type: string
      format: date-time
      description: |-
        A UTC DateTime wrapper that implements ToRedisArgs and FromRedisValue.

        The values are stores as unix timestamps in redis.
    Turn:
      type: object
      description: TURN access credentials for users.
      required:
        - username
        - password
        - ttl
        - uris
      properties:
        password:
          type: string
          description: The TURN access username
        ttl:
          type: string
          description: Time to live of the TURN service
        uris:
          type: array
          items:
            type: string
          description: URIs of the TURN service
        username:
          type: string
          description: The TURN access username
    UnregisteredUser:
      type: object
      description: Representation of a unregistered user
      required:
        - email
        - firstname
        - lastname
        - avatar_url
      properties:
        avatar_url:
          type: string
          description: Avatar URL for the unregistered user
        email:
          type: string
          description: Email of the unregistered user
        firstname:
          type: string
          description: First name of the unregistered user
        lastname:
          type: string
          description: Last name of the unregistered user
    UpdateStreamingTarget:
      allOf:
        - allOf:
            - $ref: '#/components/schemas/UpdateStreamingTargetKind'
          nullable: true
        - type: object
          properties:
            name:
              type: string
              description: The name of the streaming target
              nullable: true
      description: >-
        Data to update a streaming target (only fields with [`Some`] are
        updated)
      example:
        kind: custom
        name: My OwnCast Stream
        public_url: https://owncast.example.com/
        streaming_endpoint: https://ingress.example.com/
        streaming_key: aabbccddeeff
    UpdateStreamingTargetKind:
      oneOf:
        - type: object
          description: The "custom" kind
          required:
            - kind
          properties:
            kind:
              type: string
              enum:
                - custom
            public_url:
              type: string
              format: uri
              description: The url from which the stream can be accessed
              nullable: true
            streaming_endpoint:
              type: string
              format: uri
              description: The endpoint url of the streaming target
              nullable: true
            streaming_key:
              allOf:
                - $ref: '#/components/schemas/StreamingKey'
              nullable: true
      description: >-
        Data to update a streaming target kind (only fields with [`Some`] are
        updated)
      example:
        kind: custom
        public_url: https://owncast.example.com/
        streaming_endpoint: https://ingress.example.com/
        streaming_key: aabbccddeeff
      discriminator:
        propertyName: kind
    UserAssetResource:
      allOf:
        - $ref: '#/components/schemas/AssetResource'
        - type: object
          required:
            - room_id
          properties:
            event_id:
              allOf:
                - $ref: '#/components/schemas/EventId'
            room_id:
              $ref: '#/components/schemas/RoomId'
      description: Information related to a specific asset
      example:
        created_at: '2024-06-18T11:22:33Z'
        event_id: 00000000-0000-0000-0000-004433221100
        filename: recording.webm
        id: 00000000-0000-0000-0000-0000aabbcc00
        kind: record
        namespace: recording
        room_id: 00000000-0000-0000-0000-0000abadcafe
        size: 98765432
    UserId:
      type: string
      format: uuid
      description: The id of a user
      example: 00000009-9889-9889-9889-988000000000
    UserInvite:
      type: object
      description: Request body variant for the `POST /events/{event_id}/invites` endpoint
      required:
        - invitee
      properties:
        invitee:
          $ref: '#/components/schemas/UserId'
        role:
          $ref: '#/components/schemas/InviteRole'
      example:
        invitee: 00000009-9889-9889-9889-988000000000
        role: user
    ValidationErrorBody:
      type: object
      description: The body of a validation error response
      required:
        - code
        - message
        - errors
      properties:
        code:
          type: string
          description: Machine readable error message
        errors:
          type: array
          items:
            $ref: '#/components/schemas/ValidationErrorEntry'
          description: A list validation errors
        message:
          type: string
          description: Human readable message
    ValidationErrorEntry:
      type: object
      description: An entry in a validation error list
      required:
        - code
      properties:
        code:
          type: string
          description: Machine readable error message
        field:
          type: string
          description: >-
            The field related to the error


            If the value is [`None`] that means the error happened at struct
            level
          nullable: true
        message:
          type: string
          description: Human readable error message
          nullable: true
  responses:
    BadRequest:
      description: Bad request
    BinaryData:
      description: Binary data
    Forbidden:
      description: The authorized user has no permission to access the requested resource
    InternalServerError:
      description: An internal server error occurred
    NotFound:
      description: The requested data could not be found
    Unauthorized:
      description: >-
        The provided access token is expired or the provided id or access token
        is invalid.
                The WWW-Authenticate header will contain an error description 'session expired' to distinguish between
                an invalid and an expired token
      headers:
        www-authenticate:
          schema:
            type: string
          description: >

            Will contain 'session expired' to distinguish between an invalid and
            an expired token.


            Examples:

                Bearer error="invalid_token", error_description="The provided access token is invalid"
                Bearer error="invalid_token", error_description="The user session expired"
      content:
        application/json:
          schema:
            type: object
            description: Internal reusable dummy type for utoipa unauthorized error
            required:
              - code
              - message
            properties:
              code:
                type: string
                description: Machine readable error code
              message:
                type: string
                description: Human readable message
  securitySchemes:
    BearerAuth:
      type: http
      scheme: bearer
    InviteCode:
      type: http
      scheme: bearer
tags:
  - name: api::v1::auth
    description: Endpoints related to authentication
  - name: api::v1::invites
    description: Endpoints related to meeting invites
  - name: api::v1::rooms
    description: Endpoints related to meeting rooms
  - name: api::v1::events
    description: Endpoints related to events
  - name: api::v1::events::favorites
    description: Endpoints related to user's favorite events
  - name: api::v1::events::instances
    description: Endpoints related to event instances
  - name: api::v1::events::invites
    description: Endpoints related to event invites
  - name: api::v1::events::shared_folder
    description: Endpoints related to event shared folders
  - name: api::v1::assets
    description: Endpoints related to file assets
  - name: api::v1::sip_configs
    description: Endpoints related to SIP configuration
  - name: api::v1::services::call_in
    description: Endpoints related to the meeting call-in service
  - name: api::v1::services::recording
    description: Endpoints related to the meeting recording service
  - name: api::v1::streaming_targets
    description: Endpoints related to streaming targets
  - name: api::v1::turn
    description: Endpoints related TURN server usage
  - name: api::v1::users
    description: Endpoints related to user information and management
  - name: api::signaling
    description: Endpoints for signaling connections in a meeting
