---
openapi: 3.1.0
info:
  title: Demodesk Public API
  version: v2
  description: |
    Customer-facing API for external integrations.

    We're currently bringing more capabilities to the v2 API and you should use it whenever possible.
    For some use cases, you may need to use the [v1 API](https://help.demodesk.com/en/articles/8518816-api-reference) instead, which will be discontinued in the future, though.

    ## Authentication

    All requests require a token passed as a Bearer token in the `Authorization` HTTP header:

    ```
    curl -H "Authorization: Bearer YOUR_API_KEY" https://demodesk.com/api/v2/recordings
    ```

    Generate an API key in your Demodesk account under *Settings > Integrations > Other*.
    The deprecated `api-key` HTTP header is still accepted for backwards compatibility.

    The key inherits the permissions of the user who created it.
    To access resources across your whole company, use the API key of an admin user who is a member of all restricted groups.

    ## MCP

    AI Agents can use the same capabilities of this API via an MCP server located at `https://demodesk.com/mcp`. The server supports OAuth2 authentication discovery.
  contact:
    email: support@demodesk.com
servers:
- url: https://demodesk.com/api/v2
  description: Public demodesk host
security:
- bearerAuth: []
tags:
- name: Recordings
  description: Endpoints to discover recordings and fetch related artifacts.
- name: Users
  description: Endpoints regarding user management.
paths:
  "/me":
    get:
      tags:
      - Users
      operationId: getCurrentUser
      x-mcp:
        enabled: true
        toolName: users_get_me
        title: Get current user
        description: |
          Resolve who is authenticated for this API key or OAuth token.
          Typical use case: disambiguating prompts like "my meetings" and obtaining the current user's id/email for follow-up filtering.
          Returns the authenticated user's core profile fields.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 5000
      summary: Get current user
      description: |
        Returns the user represented by the provided API key or OAuth token.

        Rate limits:
        - Global: 120 requests per minute per API key.
      responses:
        '200':
          description: Current user fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/current-user-response"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/users":
    get:
      tags:
      - Users
      operationId: listUsers
      x-mcp:
        enabled: true
        toolName: users_list
        title: List users
        description: |
          List active users visible to the authenticated user.
          Typical use case: selecting or resolving teammates by name/email before filtering recordings or assigning follow-up actions. It can also be used to confirm that users exist when given a specific email address.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 5000
      summary: List users
      description: |
        Returns active users visible to the authenticated user.

        Rate limits:
        - Global: 120 requests per minute per API key.
      parameters:
      - "$ref": "#/components/parameters/search"
      - "$ref": "#/components/parameters/cursor"
      - "$ref": "#/components/parameters/limit"
      responses:
        '200':
          description: Users fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/users-index-response"
        '400':
          "$ref": "#/components/responses/bad-request"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/recordings":
    get:
      tags:
      - Recordings
      operationId: listRecordings
      x-mcp:
        enabled: true
        toolName: recordings_list
        title: List recordings
        description: |
          Find meeting recordings visible to the authenticated Demodesk user.
          Typical use case: searching, filtering, or browsing calls (for example: "show last week's meetings", "find calls where I talked to Daniel").
          Prefer dedicated people filters over internal ids: `host_eq`, `host_in`, `attendee_eq`, `attendee_in`.
          Person filter values support an email address or `me` (resolves to authenticated user).
          Examples: `filter[host_eq]=host@example.com`, `filter[host_eq]=me`, `filter[attendee_eq]=attendee@example.com`, `filter[attendee_eq]=me`, `filter[attendee_in][]=me&filter[attendee_in][]=champion@example.com`.
          Returns paginated recording metadata and cursor info; use returned ids/tokens in follow-up tools like getting the transcripts of the found meetings.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 30000
      summary: List recordings
      description: |
        Returns recordings **visible to the owner of the API key**.

        If you want to access "all" recordings, use an admin user who is added to all restricted groups. Recordings with explicit `only_me` permission are only accessible by said user.

        Rate limits:
        - Global: 120 requests per minute per API key.
        - Endpoint-specific: 60 requests per minute per API key.
      parameters:
      - "$ref": "#/components/parameters/filter"
      - "$ref": "#/components/parameters/cursor"
      - "$ref": "#/components/parameters/limit"
      responses:
        '200':
          description: Recordings fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/recording-index-response"
        '400':
          "$ref": "#/components/responses/bad-request"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/recordings/{token}":
    get:
      tags:
      - Recordings
      operationId: getRecording
      x-mcp:
        enabled: true
        toolName: recordings_get
        title: Get recording details
        description: |
          Fetch one recording by token with detailed metadata and computed stats.
          Typical use case: opening one call after a token is known or selected from list results (for example: "open this recording", "show details for token X").
          Returns a single recording object including ownership, timing, and processing state.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 45000
      summary: Get recording details
      description: |
        Returns a single recording with detailed metadata and derived stats.

        Rate limits:
        - Global: 120 requests per minute per API key.
      parameters:
      - "$ref": "#/components/parameters/recording-token"
      responses:
        '200':
          description: Recording fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/recording-detail-response"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '404':
          "$ref": "#/components/responses/not-found"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/recordings/{token}/transcript":
    get:
      tags:
      - Recordings
      operationId: getRecordingTranscript
      x-mcp:
        enabled: true
        toolName: recordings_get_transcript
        title: Get recording transcript
        description: |
          Retrieve transcript content for a single recording, optionally translated via `lang`.
          Typical use case: reading, quoting, summarizing, or analyzing what was said in one call (for example: "show transcript", "translate transcript to de").
          Returns transcript paragraphs/sentences (or plain text format when requested).
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 20000
      summary: Get recording transcript
      description: |
        Returns the full transcript grouped into paragraphs and sentences.

        Use the optional `lang` query parameter to request a translated transcript.

        Rate limits:
        - Global: 120 requests per minute per API key.
      parameters:
      - "$ref": "#/components/parameters/recording-token"
      - "$ref": "#/components/parameters/transcript-language"
      - "$ref": "#/components/parameters/transcript-format"
      responses:
        '200':
          description: Transcript fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/recording-transcript-response"
            text/plain:
              schema:
                type: string
              examples:
                meetingLines:
                  summary: speaker-prefixed transcript lines
                  value: |
                    Host User:
                    Thanks for joining.
                    Let's review the agenda.
                    Customer Contact:
                    Sounds good, let's start.
        '202':
          "$ref": "#/components/responses/transcript-processing"
        '204':
          description: Transcript exists but is empty or too short.
        '400':
          "$ref": "#/components/responses/bad-request"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '404':
          "$ref": "#/components/responses/not-found"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/transcripts/batch":
    post:
      tags:
      - Recordings
      operationId: batchGetRecordingsTranscripts
      x-mcp:
        enabled: true
        toolName: recordings_batch_get_transcripts
        title: Get transcripts in batch
        description: |
          Retrieve transcripts for up to 100 recordings in one request.
          Typical use case: cross-call analysis over a known set of recording tokens (for example: "get transcripts for these 20 calls").
          This endpoint performs retrieval only and does not create, update, or delete data.
          Returns per-recording transcript payloads with per-item status so partial failures remain inspectable.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 60000
      summary: Get transcripts in batch
      description: |
        Returns transcripts for `n` recordings (`n` <= 100).
        Results are returned with a per-recording status.

        Rate limits:
        - Global: 120 requests per minute per API key.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/transcript-batch-request"
      responses:
        '200':
          description: Transcript batch fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/transcript-batch-response"
        '400':
          "$ref": "#/components/responses/bad-request"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/recordings/{token}/summaries":
    get:
      tags:
      - Recordings
      operationId: listRecordingSummaries
      x-mcp:
        enabled: true
        toolName: recordings_list_summaries
        title: List recording summaries
        description: |
          List AI-generated summaries attached to a recording.
          Typical use case: recap notes, highlights, or summary variants for a specific call (for example: "show the summary", "what are the key takeaways?").
          Returns summary records and metadata for the requested recording token.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 30000
      summary: List recording summaries
      description: |
        Returns generated summaries associated with the recording.

        Rate limits:
        - Global: 120 requests per minute per API key.
      parameters:
      - "$ref": "#/components/parameters/recording-token"
      responses:
        '200':
          description: Summaries fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/recording-summaries-response"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '404':
          "$ref": "#/components/responses/not-found"
        '429':
          "$ref": "#/components/responses/too-many-requests"
  "/recordings/{token}/scorecards":
    get:
      tags:
      - Recordings
      operationId: listRecordingScorecards
      x-mcp:
        enabled: true
        toolName: recordings_list_scorecards
        title: List recording scorecards
        description: |
          List non-deleted scorecards linked to a recording.
          Typical use case: coaching evaluation, rubric results, or scoring details for a call (for example: "show scorecard", "how did this call score?").
          Returns scorecard entries and associated scoring metadata for the recording token.
        readOnlyHint: true
        idempotentHint: true
        destructiveHint: false
        openWorldHint: false
        timeoutMs: 15000
      summary: List recording scorecards
      description: |
        Returns non-deleted scorecards associated with the recording.

        Rate limits:
        - Global: 120 requests per minute per API key.
      parameters:
      - "$ref": "#/components/parameters/recording-token"
      responses:
        '200':
          description: Scorecards fetched successfully.
          content:
            application/json:
              schema:
                "$ref": "#/components/schemas/recording-scorecards-response"
        '401':
          "$ref": "#/components/responses/unauthorized"
        '404':
          "$ref": "#/components/responses/not-found"
        '429':
          "$ref": "#/components/responses/too-many-requests"
webhooks:
  demo.scheduled:
    post:
      operationId: webhookDemoScheduled
      summary: demo.scheduled webhook
      description: |
        Sent when a demo gets scheduled.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-scheduled-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.rescheduled:
    post:
      operationId: webhookDemoRescheduled
      summary: demo.rescheduled webhook
      description: |
        Sent when a demo gets rescheduled.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-rescheduled-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.handovered:
    post:
      operationId: webhookDemoHandovered
      summary: demo.handovered webhook
      description: |
        Sent when a demo gets handed over to another host.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-handovered-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.canceled:
    post:
      operationId: webhookDemoCanceled
      summary: demo.canceled webhook
      description: |
        Sent when a demo gets canceled.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-canceled-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.started:
    post:
      operationId: webhookDemoStarted
      summary: demo.started webhook
      description: |
        Sent when a demo starts.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-started-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.ended:
    post:
      operationId: webhookDemoEnded
      summary: demo.ended webhook
      description: |
        Sent when a demo ends.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-ended-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.call_note_updated:
    post:
      operationId: webhookDemoCallNoteUpdated
      summary: demo.call_note_updated webhook
      description: |
        Sent when call notes are updated for a demo.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-call-note-updated-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  demo.event_response_updated:
    post:
      operationId: webhookDemoEventResponseUpdated
      summary: demo.event_response_updated webhook
      description: |
        Sent when event responses of attendees are updated.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-demo-event-response-updated-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  recording.uploaded:
    post:
      operationId: webhookRecordingUploaded
      summary: recording.uploaded webhook
      description: |
        Sent when a recording upload finished.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-recording-uploaded-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
  recording.transcription_postprocessed:
    post:
      operationId: webhookRecordingTranscriptionPostprocessed
      summary: recording.transcription_postprocessed webhook
      description: |
        Sent when recording transcription and post-processing are complete.

        To enable the Webhook API, please email support@demodesk.com with the endpoint urls on your side and which events to activate.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              "$ref": "#/components/schemas/webhook-recording-transcription-postprocessed-payload"
      responses:
        '200':
          description: Webhook accepted by your endpoint.
        default:
          description: Non-2xx responses are treated as delivery failures and retried.
            If webhooks keep failing, they get disabled automatically.
components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API key or OAuth token
      description: |
        Pass your API key or OAuth token as a Bearer token in the `Authorization` HTTP header.

        ```
        curl -H "Authorization: Bearer YOUR_API_KEY" https://demodesk.com/api/v2/recordings
        ```

        **Obtaining a key:** Generate an API key in your Demodesk account under
        *Settings > Integrations > Other*.

        **Permissions:** The key inherits the permissions of the user who created it.
        So when trying to access resources of your whole company, make sure to use the API key of an admin user who is
        member of all restricted groups.
  schemas:
    recording-group-item:
      type: object
      required:
      - groupId
      - groupName
      properties:
        groupId:
          type: string
          description: Internal group ID as string.
          examples:
          - '456'
        groupName:
          type: string
          description: Name of the group.
          examples:
          - Enterprise Sales
    current-user-item:
      type: object
      required:
      - id
      - firstName
      - lastName
      - email
      - role
      - locale
      - timeZone
      - groups
      properties:
        id:
          type: string
          description: Internal user id.
          examples:
          - '12345'
        firstName:
          type: string
          description: First name of the authenticated user.
          examples:
          - Max
        lastName:
          type: string
          description: Last name of the authenticated user.
          examples:
          - Mustermann
        email:
          type: string
          format: email
          description: Primary email of the authenticated user.
          examples:
          - max@example.com
        role:
          type: string
          description: Role of the authenticated user within the company.
          enum:
          - user
          - manager
          - company_admin
        locale:
          type: string
          description: Locale of the authenticated user.
          examples:
          - en
        timeZone:
          type: string
          description: IANA time zone of the authenticated user.
          examples:
          - Europe/Berlin
        groups:
          type: array
          description: Groups the authenticated user belongs to.
          items:
            "$ref": "#/components/schemas/recording-group-item"
    current-user-response:
      type: object
      required:
      - data
      properties:
        data:
          "$ref": "#/components/schemas/current-user-item"
    error-response:
      type: object
      required:
      - error
      properties:
        error:
          type: object
          required:
          - code
          - message
          - requestId
          properties:
            code:
              type: string
            message:
              type: string
            requestId:
              type: string
    user-list-item:
      type: object
      required:
      - id
      - firstName
      - lastName
      - email
      - role
      - locale
      - timeZone
      properties:
        id:
          type: string
          description: Internal user id.
          examples:
          - '12345'
        firstName:
          type: string
          description: First name of the user.
          examples:
          - Max
        lastName:
          type: string
          description: Last name of the user.
          examples:
          - Mustermann
        email:
          type: string
          format: email
          description: Primary email of the user.
          examples:
          - max@example.com
        role:
          type: string
          description: Role of the user within the company.
          enum:
          - user
          - manager
          - company_admin
        locale:
          type: string
          description: Locale of the user.
          examples:
          - en
        timeZone:
          type: string
          description: IANA time zone of the user.
          examples:
          - Europe/Berlin
    users-index-response:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/user-list-item"
        meta:
          type: object
          required:
          - hasNext
          - limit
          properties:
            hasNext:
              type: boolean
            limit:
              type: integer
            nextCursor:
              type:
              - string
              - 'null'
    recording-list-item:
      type: object
      required:
      - recordingToken
      - recordingId
      - demoId
      - userId
      - name
      - recordingWebUrl
      - temporaryDirectUrl
      - status
      - createdAt
      - updatedAt
      - demoStartDate
      - durationMs
      - postprocessingStatus
      - access
      properties:
        recordingToken:
          type: string
          description: Public recording token identifier.
        recordingId:
          type: string
          description: Internal recording id as string.
        demoId:
          type: string
          description: Internal demo id as string.
        userId:
          type: integer
          description: ID of the demo host user.
        name:
          type:
          - string
          - 'null'
        recordingWebUrl:
          type: string
          description: URL to the recording view in Demodesk.
        temporaryDirectUrl:
          type:
          - string
          - 'null'
          description: Direct link to the video file, signed with a temporary access
            token.
        status:
          type: string
          description: |
            Recording status.
            - `pending`: recording is still in progress or processing
            - `ready`: recording can be consumed
            - `failure`: recording failed
            - `cancelled`: recording never started, eg. because the bot was not admitted
            - `expired`: recording expired
          enum:
          - pending
          - ready
          - failure
          - cancelled
          - expired
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        demoStartDate:
          type:
          - string
          - 'null'
          format: date-time
        durationMs:
          type:
          - integer
          - 'null'
        postprocessingStatus:
          type:
          - string
          - 'null'
          description: 'Recording post-processing status. Post-processing includes
            transcription, participant data enrichment, meeting statistics, generating
            summaries, etc.

            '
          enum:
          - pending
          - done
          - failed
          - too_short
        access:
          type: string
          description: |
            Access permission level of the demo.
            - `company_wide`: visible to all company members
            - `selected_groups`: visible to members of assigned groups
            - `host_and_participants`: visible only to the host and participants
            - `host_only`: visible only to the host
          enum:
          - company_wide
          - selected_groups
          - host_and_participants
          - host_only
        groupIds:
          type: array
          description: IDs of groups assigned to the demo. Present in list responses
            only; detail responses use `groups` instead.
          items:
            type: string
    recording-index-response:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/recording-list-item"
        meta:
          type: object
          required:
          - hasNext
          - limit
          properties:
            hasNext:
              type: boolean
            limit:
              type: integer
            nextCursor:
              type:
              - string
              - 'null'
    recording-host-item:
      type: object
      description: The host of the demo, resolved inline so consumers don't need a
        follow-up users lookup.
      required:
      - userId
      - displayName
      - email
      properties:
        userId:
          type: string
          description: ID of the demo host user as string.
        displayName:
          type: string
          description: Human-readable name of the host.
        email:
          type: string
          description: Email address of the host.
    recording-meeting-location-item:
      type: object
      required:
      - kind
      - value
      properties:
        kind:
          type:
          - string
          - 'null'
        value:
          type:
          - string
          - 'null'
    recording-participant-item:
      type: object
      required:
      - participantId
      - displayName
      - email
      - permission
      - attended
      properties:
        participantId:
          type: string
        displayName:
          type: string
        email:
          type:
          - string
          - 'null'
        permission:
          type: string
          enum:
          - customer
          - team
          - host
        attended:
          type: boolean
    recording-statistics:
      type: object
      required:
      - engagementScore
      - feedbackScore
      properties:
        engagementScore:
          type:
          - integer
          - 'null'
          minimum: 0
          maximum: 10
        feedbackScore:
          type:
          - number
          - 'null'
          format: float
    recording-detail-item:
      allOf:
      - "$ref": "#/components/schemas/recording-list-item"
      - type: object
        required:
        - host
        - audioOnly
        - attendeeClassification
        - meetingLocation
        - participants
        - groups
        - statistics
        properties:
          host:
            description: The demo host, resolved inline. `null` when no host is assigned
              to the demo.
            oneOf:
            - "$ref": "#/components/schemas/recording-host-item"
            - type: 'null'
          audioOnly:
            type: boolean
          attendeeClassification:
            type:
            - string
            - 'null'
            enum:
            - internal_meeting
            - external_meeting
            - 'null'
          meetingLocation:
            "$ref": "#/components/schemas/recording-meeting-location-item"
          participants:
            type: array
            items:
              "$ref": "#/components/schemas/recording-participant-item"
          groups:
            type: array
            description: Groups assigned to the demo. Only populated when access is
              `selected_groups`.
            items:
              "$ref": "#/components/schemas/recording-group-item"
          statistics:
            "$ref": "#/components/schemas/recording-statistics"
    recording-detail-response:
      type: object
      required:
      - data
      properties:
        data:
          "$ref": "#/components/schemas/recording-detail-item"
    transcript-speaker:
      type: object
      required:
      - displayName
      properties:
        displayName:
          type:
          - string
          - 'null'
    transcript-sentence:
      type: object
      required:
      - startInSeconds
      - endInSeconds
      - text
      properties:
        startInSeconds:
          type: number
        endInSeconds:
          type: number
        text:
          type: string
    transcript-paragraph:
      type: object
      required:
      - startInSeconds
      - endInSeconds
      - speaker
      - sentences
      properties:
        startInSeconds:
          type: number
        endInSeconds:
          type: number
        speaker:
          anyOf:
          - "$ref": "#/components/schemas/transcript-speaker"
          - type: 'null'
        sentences:
          type: array
          items:
            "$ref": "#/components/schemas/transcript-sentence"
    transcript:
      type: object
      required:
      - language
      - paragraphs
      properties:
        language:
          type: string
        paragraphs:
          type: array
          items:
            "$ref": "#/components/schemas/transcript-paragraph"
    recording-transcript-response:
      type: object
      required:
      - data
      properties:
        data:
          "$ref": "#/components/schemas/transcript"
    transcript-batch-request:
      type: object
      required:
      - recordingTokens
      properties:
        recordingTokens:
          type: array
          minItems: 1
          maxItems: 100
          uniqueItems: true
          items:
            type: string
        lang:
          type: string
          pattern: "^[a-z]{2}(-[A-Z]{2})?$"
          description: 'Translate results to the provided language on-the-fly. Examples:
            `de`, `fr`, etc.'
        format:
          type: string
          enum:
          - json
          - plaintext
          default: json
          description: Whether you want structured data for every single sentence
            or the transcript merged into plain text.
    transcript-plaintext:
      type: object
      required:
      - language
      - text
      properties:
        language:
          type: string
        text:
          type: string
    transcript-batch-item:
      type: object
      required:
      - recordingToken
      - status
      - transcript
      properties:
        recordingToken:
          type: string
        status:
          type: string
          enum:
          - ready
          - processing
          - not_requested
          - empty
          - not_found
        transcript:
          oneOf:
          - "$ref": "#/components/schemas/transcript"
          - "$ref": "#/components/schemas/transcript-plaintext"
          - type: 'null'
    transcript-batch-response:
      type: object
      required:
      - data
      - meta
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/transcript-batch-item"
        meta:
          type: object
          required:
          - requestedCount
          properties:
            requestedCount:
              type: integer
              minimum: 1
    summary-list-item:
      type: object
      required:
      - summaryId
      - promptId
      - promptName
      - languageCode
      - content
      - htmlContent
      - createdAt
      - updatedAt
      properties:
        summaryId:
          type: string
        promptId:
          type:
          - string
          - 'null'
        promptName:
          type:
          - string
          - 'null'
        languageCode:
          type: string
        content:
          type: string
        htmlContent:
          type:
          - string
          - 'null'
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    recording-summaries-response:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/summary-list-item"
    scorecard-question-list-item:
      type: object
      required:
      - questionId
      - position
      - name
      - text
      - criteria
      - score
      - comment
      - rawTimestamps
      properties:
        questionId:
          type: string
        position:
          type: integer
          minimum: 0
        name:
          type:
          - string
          - 'null'
        text:
          type: string
        criteria:
          type:
          - string
          - 'null'
        score:
          type:
          - integer
          - 'null'
          minimum: 1
          maximum: 5
        comment:
          type:
          - string
          - 'null'
        rawTimestamps:
          type:
          - string
          - 'null'
    scorecard-list-item:
      type: object
      required:
      - scorecardId
      - templateId
      - templateName
      - score
      - comment
      - languageCode
      - giverUserId
      - receiverUserId
      - createdAt
      - updatedAt
      - questions
      properties:
        scorecardId:
          type: string
        templateId:
          type:
          - string
          - 'null'
        templateName:
          type: string
        score:
          type:
          - integer
          - 'null'
          minimum: 1
          maximum: 5
        comment:
          type:
          - string
          - 'null'
        languageCode:
          type:
          - string
          - 'null'
        giverUserId:
          type:
          - integer
          - 'null'
        receiverUserId:
          type: integer
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        questions:
          type: array
          items:
            "$ref": "#/components/schemas/scorecard-question-list-item"
    recording-scorecards-response:
      type: object
      required:
      - data
      properties:
        data:
          type: array
          items:
            "$ref": "#/components/schemas/scorecard-list-item"
    webhook-meta-event:
      type: object
      required:
      - action
      - apiVersion
      - createdAt
      properties:
        action:
          type: string
        apiVersion:
          type: string
          enum:
          - v1
        createdAt:
          type: string
          format: date-time
    webhook-crm-id:
      oneOf:
      - type: string
      - type: integer
      - type: 'null'
    webhook-demo-base-attributes:
      type: object
      required:
      - token
      - link
      - createdVia
      - createdAt
      - updatedAt
      - location
      - name
      - eventTypeName
      - playbookName
      - hostId
      - hostEmail
      - attendeeClassification
      - calendarOrganizerClassification
      - salesforceEventId
      - hubspotMeetingId
      - pipedriveActivityId
      - hubspotCompanyId
      - hubspotCompanyName
      - hubspotDealId
      - hubspotDealName
      - salesforceAccountId
      - salesforceAccountName
      - salesforceOpportunityId
      - salesforceOpportunityName
      - pipedriveDealId
      - pipedriveDealName
      - googleEventId
      - googleBeforeBufferEventId
      - googleAfterBufferEventId
      - office365EventId
      - office365BeforeBufferEventId
      - office365AfterBufferEventId
      - tokens
      properties:
        token:
          type: string
        link:
          type: string
        createdVia:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        location:
          type: string
        name:
          type: string
        eventTypeName:
          type:
          - string
          - 'null'
        playbookName:
          type:
          - string
          - 'null'
        hostId:
          type: integer
        hostEmail:
          type:
          - string
          - 'null'
        attendeeClassification:
          type:
          - string
          - 'null'
        calendarOrganizerClassification:
          type:
          - string
          - 'null'
        salesforceEventId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotMeetingId:
          "$ref": "#/components/schemas/webhook-crm-id"
        pipedriveActivityId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotCompanyId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotCompanyName:
          type:
          - string
          - 'null'
        hubspotDealId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotDealName:
          type:
          - string
          - 'null'
        salesforceAccountId:
          "$ref": "#/components/schemas/webhook-crm-id"
        salesforceAccountName:
          type:
          - string
          - 'null'
        salesforceOpportunityId:
          "$ref": "#/components/schemas/webhook-crm-id"
        salesforceOpportunityName:
          type:
          - string
          - 'null'
        pipedriveDealId:
          "$ref": "#/components/schemas/webhook-crm-id"
        pipedriveDealName:
          type:
          - string
          - 'null'
        googleEventId:
          type:
          - string
          - 'null'
        googleBeforeBufferEventId:
          type:
          - string
          - 'null'
        googleAfterBufferEventId:
          type:
          - string
          - 'null'
        office365EventId:
          type:
          - string
          - 'null'
        office365BeforeBufferEventId:
          type:
          - string
          - 'null'
        office365AfterBufferEventId:
          type:
          - string
          - 'null'
        tokens:
          type: object
          additionalProperties:
            oneOf:
            - type: string
            - type: number
            - type: boolean
            - type: 'null'
    webhook-demo-scheduled-attributes:
      allOf:
      - "$ref": "#/components/schemas/webhook-demo-base-attributes"
      - type: object
        required:
        - description
        - startDate
        - endDate
        - duration
        - participantEmail
        - participantFirstName
        - participantLastName
        - participantCompany
        - bookerEmail
        - publicCancellationUrl
        - publicReschedulingUrl
        properties:
          description:
            type:
            - string
            - 'null'
          startDate:
            type: string
            format: date-time
          endDate:
            type:
            - string
            - 'null'
            format: date-time
          duration:
            type: integer
          participantEmail:
            type:
            - string
            - 'null'
          participantFirstName:
            type:
            - string
            - 'null'
          participantLastName:
            type:
            - string
            - 'null'
          participantCompany:
            type:
            - string
            - 'null'
          bookerEmail:
            type:
            - string
            - 'null'
          publicCancellationUrl:
            type:
            - string
            - 'null'
          publicReschedulingUrl:
            type:
            - string
            - 'null'
    webhook-demo-scheduled-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.scheduled
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-scheduled-attributes"
    webhook-demo-rescheduled-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.rescheduled
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-scheduled-attributes"
    webhook-demo-handovered-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.handovered
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-scheduled-attributes"
    webhook-demo-canceled-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.canceled
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-scheduled-attributes"
    webhook-demo-started-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.started
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-base-attributes"
    webhook-demo-ended-attributes:
      allOf:
      - "$ref": "#/components/schemas/webhook-demo-base-attributes"
      - type: object
        required:
        - participantEmail
        - participantName
        - startDate
        - endDate
        - duration
        - notes
        - status
        properties:
          participantEmail:
            type:
            - string
            - 'null'
          participantName:
            type:
            - string
            - 'null'
          startDate:
            type: string
            format: date-time
          endDate:
            type:
            - string
            - 'null'
            format: date-time
          duration:
            type: integer
          notes:
            type:
            - string
            - 'null'
          status:
            type: string
    webhook-demo-ended-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.ended
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-ended-attributes"
    webhook-demo-call-note-updated-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.call_note_updated
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-ended-attributes"
    webhook-demo-event-response-updated-attributes:
      allOf:
      - "$ref": "#/components/schemas/webhook-demo-base-attributes"
      - type: object
        required:
        - event
        properties:
          event:
            type: object
            required:
            - start
            - end
            - attendees
            properties:
              start:
                type: object
                required:
                - dateTime
                properties:
                  dateTime:
                    type: string
                    format: date-time
              end:
                type: object
                required:
                - dateTime
                properties:
                  dateTime:
                    type: string
                    format: date-time
              attendees:
                type: array
                items:
                  type: object
                  required:
                  - email
                  - displayName
                  - responseStatus
                  properties:
                    email:
                      type: string
                    displayName:
                      type:
                      - string
                      - 'null'
                    responseStatus:
                      type: string
                      enum:
                      - none
                      - needsAction
                      - declined
                      - tentative
                      - accepted
    webhook-demo-event-response-updated-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - demo.event_response_updated
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - demos
            attributes:
              "$ref": "#/components/schemas/webhook-demo-event-response-updated-attributes"
    webhook-recording-base-attributes:
      type: object
      required:
      - demoId
      - token
      - url
      - temporaryVideoUrl
      - hostId
      - hostEmail
      - attendeeClassification
      - calendarOrganizerClassification
      - salesforceEventId
      - hubspotMeetingId
      - pipedriveActivityId
      - hubspotCompanyId
      - hubspotCompanyName
      - hubspotDealId
      - hubspotDealName
      - salesforceAccountId
      - salesforceAccountName
      - salesforceOpportunityId
      - salesforceOpportunityName
      - pipedriveDealId
      - pipedriveDealName
      properties:
        demoId:
          type: integer
        token:
          type: string
        url:
          type: string
        temporaryVideoUrl:
          type:
          - string
          - 'null'
        hostId:
          type: integer
        hostEmail:
          type:
          - string
          - 'null'
        attendeeClassification:
          type:
          - string
          - 'null'
        calendarOrganizerClassification:
          type:
          - string
          - 'null'
        salesforceEventId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotMeetingId:
          "$ref": "#/components/schemas/webhook-crm-id"
        pipedriveActivityId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotCompanyId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotCompanyName:
          type:
          - string
          - 'null'
        hubspotDealId:
          "$ref": "#/components/schemas/webhook-crm-id"
        hubspotDealName:
          type:
          - string
          - 'null'
        salesforceAccountId:
          "$ref": "#/components/schemas/webhook-crm-id"
        salesforceAccountName:
          type:
          - string
          - 'null'
        salesforceOpportunityId:
          "$ref": "#/components/schemas/webhook-crm-id"
        salesforceOpportunityName:
          type:
          - string
          - 'null'
        pipedriveDealId:
          "$ref": "#/components/schemas/webhook-crm-id"
        pipedriveDealName:
          type:
          - string
          - 'null'
    webhook-recording-uploaded-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - recording.uploaded
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - recordings
            attributes:
              "$ref": "#/components/schemas/webhook-recording-base-attributes"
    webhook-recording-transcription-postprocessed-attributes:
      allOf:
      - "$ref": "#/components/schemas/webhook-recording-base-attributes"
      - type: object
        required:
        - primaryAiSummaryPlaintext
        - primaryAiSummaryHtml
        - latestAiSummaryPlaintext
        - latestAiSummaryHtml
        properties:
          primaryAiSummaryPlaintext:
            type:
            - string
            - 'null'
          primaryAiSummaryHtml:
            type:
            - string
            - 'null'
          latestAiSummaryPlaintext:
            type:
            - string
            - 'null'
          latestAiSummaryHtml:
            type:
            - string
            - 'null'
    webhook-recording-transcription-postprocessed-payload:
      type: object
      required:
      - meta
      - data
      properties:
        meta:
          type: object
          required:
          - event
          properties:
            event:
              allOf:
              - "$ref": "#/components/schemas/webhook-meta-event"
              - type: object
                properties:
                  action:
                    type: string
                    enum:
                    - recording.transcription_postprocessed
        data:
          type: object
          required:
          - id
          - type
          - attributes
          properties:
            id:
              type: string
            type:
              type: string
              enum:
              - recordings
            attributes:
              "$ref": "#/components/schemas/webhook-recording-transcription-postprocessed-attributes"
  responses:
    unauthorized:
      description: API key is missing or invalid.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/error-response"
    too-many-requests:
      description: Rate limit exceeded.
      headers:
        Retry-After:
          description: Seconds until the next request is allowed.
          schema:
            type: integer
    bad-request:
      description: Request validation failed.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/error-response"
    not-found:
      description: Recording or related resource was not found.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/error-response"
    transcript-processing:
      description: Transcript is still being processed.
      content:
        application/json:
          schema:
            "$ref": "#/components/schemas/error-response"
  parameters:
    search:
      name: search
      in: query
      required: false
      description: 'Case-insensitive partial search across full name and email.

        '
      examples:
        byName:
          summary: Search by name
          value: max
        byEmail:
          summary: Search by email
          value: mustermann@example.com
      schema:
        type: string
    cursor:
      name: cursor
      in: query
      required: false
      description: Opaque cursor returned by a previous list response.
      schema:
        type: string
    limit:
      name: limit
      in: query
      required: false
      description: Page size for recordings list.
      schema:
        type: integer
        minimum: 1
        maximum: 100
        default: 100
    filter:
      name: filter
      in: query
      description: |
        Filter recordings by their properties.

        This uses Ransack-style keys in a deep-object parameter. Filter attributes use snake_case.
        Common operators include `eq`, `not_eq`, `cont`, `gteq`, `lteq`, and `in`.

        Common examples
        - `/api/v2/recordings?filter[status_eq]=pending` (allowed public values: `pending`, `ready`, `failure`, `cancelled`, `expired`)
        - `/api/v2/recordings?filter[postprocessing_status_eq]=done` (You most-likely want this - eg. transcribed, summaries generated, CRM synced, ...)
        - `/api/v2/recordings?filter[status_in][]=ready&filter[status_in][]=failure` (Ransack `in` operator with repeated array params)
        - `/api/v2/recordings?filter[created_at_gteq]=2025-01-01T00:00:00Z`
        - `/api/v2/recordings?filter[demo_id_eq]=123`
        - `/api/v2/recordings?filter[host_eq]=me` (recordings hosted by the current authenticated user)
        - `/api/v2/recordings?filter[host_eq]=host@example.com` (recordings hosted by a specific user)
        - `/api/v2/recordings?filter[host_in][]=me&filter[host_in][]=manager@example.com` (multiple hosts)
        - `/api/v2/recordings?filter[attendee_eq]=prospect@example.com` (recordings where this attendee joined)
        - `/api/v2/recordings?filter[attendee_in][]=me&filter[attendee_in][]=champion@example.com` (multiple attendees)
        - `/api/v2/recordings?filter[group_id_eq]=99` (for `access: company_wide` or `host_only` recordings: matches by host's group membership; for `access: selected_groups` recordings: matches by the demo's assigned groups)
        - `/api/v2/recordings?filter[group_id_in][]=99&filter[group_id_in][]=100` (multiple groups)
        - `/api/v2/recordings?filter[access_eq]=host_only` (allowed values: `company_wide`, `selected_groups`, `host_only`)

        They can be combined freely.
      required: false
      style: deepObject
      explode: true
      schema:
        type: object
        additionalProperties: false
        properties:
          created_at_eq:
            type: string
          created_at_not_eq:
            type: string
          created_at_lt:
            type: string
          created_at_lteq:
            type: string
          created_at_gt:
            type: string
          created_at_gteq:
            type: string
          created_at_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          created_at_not_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          created_at_cont:
            type: string
          updated_at_eq:
            type: string
          updated_at_not_eq:
            type: string
          updated_at_lt:
            type: string
          updated_at_lteq:
            type: string
          updated_at_gt:
            type: string
          updated_at_gteq:
            type: string
          updated_at_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          updated_at_not_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          updated_at_cont:
            type: string
          demo_start_date_eq:
            type: string
          demo_start_date_not_eq:
            type: string
          demo_start_date_lt:
            type: string
          demo_start_date_lteq:
            type: string
          demo_start_date_gt:
            type: string
          demo_start_date_gteq:
            type: string
          demo_start_date_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          demo_start_date_not_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          demo_start_date_cont:
            type: string
          duration_eq:
            type: string
          duration_not_eq:
            type: string
          duration_lt:
            type: string
          duration_lteq:
            type: string
          duration_gt:
            type: string
          duration_gteq:
            type: string
          duration_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          duration_not_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          duration_cont:
            type: string
          demo_id_eq:
            type: string
          demo_id_not_eq:
            type: string
          demo_id_lt:
            type: string
          demo_id_lteq:
            type: string
          demo_id_gt:
            type: string
          demo_id_gteq:
            type: string
          demo_id_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          demo_id_not_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          demo_id_cont:
            type: string
          host_eq:
            type: string
            description: Host selector. Accepts an email address or `me`.
            example: me
          host_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
            description: Host selectors. Each value accepts an email address or `me`.
            example:
            - me
            - host@example.com
          attendee_eq:
            type: string
            description: Attendee selector. Accepts an email address or `me`.
            example: attendee@example.com
          attendee_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
            description: Attendee selectors. Each value accepts an email address or
              `me`.
            example:
            - me
            - attendee@example.com
          status_eq:
            type: string
            enum:
            - pending
            - ready
            - failure
            - cancelled
            - expired
            example: ready
          status_not_eq:
            type: string
            enum:
            - pending
            - ready
            - failure
            - cancelled
            - expired
            example: failure
          status_in:
            oneOf:
            - type: string
              enum:
              - pending
              - ready
              - failure
              - cancelled
              - expired
            - type: array
              items:
                type: string
                enum:
                - pending
                - ready
                - failure
                - cancelled
                - expired
            example:
            - ready
            - failure
          status_not_in:
            oneOf:
            - type: string
              enum:
              - pending
              - ready
              - failure
              - cancelled
              - expired
            - type: array
              items:
                type: string
                enum:
                - pending
                - ready
                - failure
                - cancelled
                - expired
            example:
            - cancelled
            - expired
          postprocessing_status_eq:
            type: string
            enum:
            - pending
            - done
            - too_short
            - failed
            example: done
          postprocessing_status_not_eq:
            type: string
            enum:
            - pending
            - done
            - too_short
            - failed
            example: failed
          postprocessing_status_in:
            oneOf:
            - type: string
              enum:
              - pending
              - done
              - too_short
              - failed
            - type: array
              items:
                type: string
                enum:
                - pending
                - done
                - too_short
                - failed
            example:
            - done
            - too_short
          postprocessing_status_not_in:
            oneOf:
            - type: string
              enum:
              - pending
              - done
              - too_short
              - failed
            - type: array
              items:
                type: string
                enum:
                - pending
                - done
                - too_short
                - failed
            example:
            - pending
            - failed
          group_id_eq:
            type: string
          group_id_in:
            oneOf:
            - type: string
            - type: array
              items:
                type: string
          access_eq:
            type: string
            enum:
            - company_wide
            - selected_groups
            - host_only
            example: host_only
          access_not_eq:
            type: string
            enum:
            - company_wide
            - selected_groups
            - host_only
            example: selected_groups
          access_in:
            oneOf:
            - type: string
              enum:
              - company_wide
              - selected_groups
              - host_only
            - type: array
              items:
                type: string
                enum:
                - company_wide
                - selected_groups
                - host_only
            example:
            - company_wide
            - host_only
          access_not_in:
            oneOf:
            - type: string
              enum:
              - company_wide
              - selected_groups
              - host_only
            - type: array
              items:
                type: string
                enum:
                - company_wide
                - selected_groups
                - host_only
            example:
            - selected_groups
      examples:
        readyAndPostprocessedAfterToday:
          summary: post-processing done, after today
          value:
            status_eq: ready
            postprocessing_status_eq: done
            created_at_gteq: '2026-03-04T00:00:00Z'
        byDemoId:
          summary: by demo id
          value:
            demo_id_eq: '123'
        readyOrFailure:
          summary: status in ready or failure
          value:
            status_in:
            - ready
            - failure
        byHostMe:
          summary: by current user as host
          value:
            host_eq: me
        byHostEmail:
          summary: by host email
          value:
            host_eq: host@example.com
        byMultipleHosts:
          summary: by multiple hosts
          value:
            host_in:
            - me
            - manager@example.com
        byAttendeeEmail:
          summary: by attendee email
          value:
            attendee_eq: attendee@example.com
        byMultipleAttendees:
          summary: by multiple attendees
          value:
            attendee_in:
            - me
            - champion@example.com
        readyOnly:
          summary: ready recordings only
          value:
            status_eq: ready
        failureOnly:
          summary: failure recordings only
          value:
            status_eq: failure
        cancelledOnly:
          summary: cancelled recordings only
          value:
            status_eq: cancelled
        expiredOnly:
          summary: expired recordings only
          value:
            status_eq: expired
        processedOnly:
          summary: post-processing done
          value:
            postprocessing_status_eq: done
        tooShortOnly:
          summary: post-processing too short
          value:
            postprocessing_status_eq: too_short
        updatedSince:
          summary: updated since timestamp
          value:
            updated_at_gteq: '2025-01-01T00:00:00Z'
        dateWindow:
          summary: meeting date window
          value:
            demo_start_date_gteq: '2025-01-01T00:00:00Z'
            demo_start_date_lteq: '2025-01-31T23:59:59Z'
        minimumDuration:
          summary: minimum duration in ms
          value:
            duration_gteq: '1800000'
        byGroupId:
          summary: by group id
          value:
            group_id_eq: '99'
        byMultipleGroupIds:
          summary: by multiple group ids
          value:
            group_id_in:
            - '99'
            - '100'
        readyByGroupId:
          summary: ready recordings for a specific group
          value:
            status_eq: ready
            group_id_eq: '99'
        byAccessLevel:
          summary: by demo access level
          value:
            access_eq: host_only
    recording-token:
      name: token
      in: path
      required: true
      description: Public recording token identifier.
      schema:
        type: string
      example: d0584dc4e31be4a0
    transcript-language:
      name: lang
      in: query
      required: false
      schema:
        type: string
        pattern: "^[a-z]{2}(-[A-Z]{2})?$"
      description: Translate transcript on-the-fly to the provided language.
    transcript-format:
      name: format
      in: query
      required: false
      schema:
        type: string
        enum:
        - json
        - plaintext
        default: json
      description: Whether to return structured transcript JSON or plain text.
