Qualify

openapi: 3.0.0
info:
  termsOfService: cloud.telestream.net/terms
  contact:
    name: "Telestream, LLC."
    email: [email protected]
  license:
    name: Apache 2.0
    url: http://www.apache.org/licenses/LICENSE-2.0.html
  description: Qualify API
  version: 1.0.0
  title: Qualify API

security:
  - apiKey: []

servers:
  - url: "https://api.cloud.telestream.net/qualify/v1.0"

components:
  securitySchemes:
    apiKey:
      type: apiKey
      name: X-Api-Key
      in: header

  parameters:
    project-id:
      in: path
      name: project-id
      required: true
      schema:
        type: string
    template-id:
      in: path
      name: template-id
      required: true
      schema:
        type: string
    job-id:
      in: path
      name: job-id
      required: true
      schema:
        type: string
    packagelayout-id:
      in: path
      name: packagelayout-id
      required: true
      schema:
        type: string
    audiolayout-id:
      in: path
      name: audiolayout-id
      required: true
      schema:
        type: string

    project-filter:
      in: query
      name: project-id
      required: false
      schema:
        type: string
      description: "Filter by project id"

    pageDirection:
      in: query
      name: page_direction
      required: false
      schema:
        type: string
        enum: [after, before]
        default: after
    maxResults:
      in: query
      name: max_results
      required: false
      schema:
        type: integer
        minimum: 0
        maximum: 1000
        default: 30

    token:
      in: query
      name: token
      required: false
      schema:
        type: string
      description: "Token used for pagination, list next(next_token) or previous page (prev_token) "

  schemas:
    TemplateCollection:
      type: object
      properties:
        templates:
          type: array
          items:
            $ref: "#/components/schemas/Template"
        next_token:
          type: string
        prev_token:
          type: string

    Template:
      description: |
        Template holds configuration for multile quality control checks
      type: object
      required: ["id", "name", "tests", "created_at", "updated_at"]
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        package_layout:
          $ref: "#/components/schemas/PackageLayout"
        audio_layout:
          $ref: "#/components/schemas/AudioLayout"
        engine_version:
          type: string
          example: "2021.6"
        tests:
          type: object
          additionalProperties:
            type: object
          example:
            "caption/subtitle_test":
              {
                "608_present": false,
                "708_present": false,
                "cc1_presence": false,
                "cc2_presence": false,
                "cc3_presence": false,
                "cc4_presence": false,
                "teletext_page": 0,
                "caption_dropout": true,
                "caption_present": false,
                "service1_presence": false,
                "service2_presence": false,
                "service3_presence": false,
                "service4_presence": false,
                "service5_presence": false,
                "service6_presence": false,
                "teletext_presence": false,
                "no_caption_threshold": 10,
                "caption_dropout_duration_units": 0,
              }
            "silence":
              {
                "quiet": false,
                "silent": true,
                "digital": true,
                "threshold": 0,
                "audio_track": 1,
                "dolbye_program": 1,
              }

    ProjectSummary:
      type: object
      description: |
        Project summary
      properties:
        total:
          type: number
        in_progress:
          type: number
        status:
          type: object
          properties:
            cancelled:
              $ref: "#/components/schemas/ProjectSummaryStatusObj"
            downloading:
              $ref: "#/components/schemas/ProjectSummaryStatusObj"
            error:
              $ref: "#/components/schemas/ProjectSummaryStatusObj"
            processing:
              $ref: "#/components/schemas/ProjectSummaryStatusObj"
            queued:
              $ref: "#/components/schemas/ProjectSummaryStatusObj"
            success:
              $ref: "#/components/schemas/ProjectSummaryStatusObj"

    ProjectSummaryStatusObj:
      type: object
      properties:
        total:
          type: number
        state:
          $ref: "#/components/schemas/ProjectSummaryState"

    ProjectSummaryState:
      type: object
      properties:
        no_state:
          type: number
        passed:
          type: number
        reject:
          type: number
        warning:
          type: number

    AudioProgram:
      type: array
      items:
        type: integer
      example: [1, 2]

    AudioMapping:
      type: array
      items:
        $ref: "#/components/schemas/AudioProgram"

    AudioLayout:
      type: object
      description: |
        Map number of PCM channels to channel labels
      required: [id, name, created_at, updated_at, layout]
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        layout:
          type: array
          items:
            $ref: "#/components/schemas/AudioMapping"

    AudioLayoutCollection:
      type: object
      description: |
        Collection of audio layouts
      nullable: false
      properties:
        audio_layouts:
          type: array
          items:
            $ref: "#/components/schemas/AudioLayout"

    AudioLayoutCreateReq:
      type: object
      description: |
        Object used for audio layout creation requests
      nullable: true
      properties:
        name:
          type: string
          nullable: false
        layout:
          type: array
          items:
            $ref: "#/components/schemas/AudioMapping"

    AudioLayoutUpdateReq:
      type: object
      description: |
        Object used for audio layout update requests
      nullable: true
      properties:
        name:
          type: string
          nullable: true
        layout:
          type: array
          items:
            $ref: "#/components/schemas/AudioMapping"

    PackageLayout:
      type: object
      description: |
        Map number of PCM channels to channel labels
      required:
        [id, name, created_at, video_index, audio_indexes, subtitle_indexes]
      properties:
        id:
          type: string
        name:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        video_index:
          description: |
            Index of video track from ABR manifest file that will be used in checks
          type: integer
          format: int64
        audio_indexes:
          description: |
            Index of audio track from ABR manifest file that will be  used in checks
          type: array
          items:
            type: integer
            format: int64
        subtitle_indexes:
          description: |
            Index of subtitle track from ABR manifest file that will be used in check
          type: array
          items:
            type: integer
            format: int64

    PackageLayoutCollection:
      type: object
      description: |
        Collection of package layouts
      nullable: false
      properties:
        package_layouts:
          type: array
          items:
            $ref: "#/components/schemas/PackageLayout"

    PackageLayoutCreateReq:
      type: object
      properties:
        name:
          description: "User given name of package layout"
          type: string
          nullable: false
        video_index:
          type: integer
          nullable: false
        audio_indexes:
          type: array
          items:
            type: integer
            format: int32
          nullable: false
        subtitle_indexes:
          type: array
          items:
            type: integer
            format: int32
          nullable: false

    PackageLayoutUpdateReq:
      type: object
      properties:
        name:
          description: "User given name of package layout"
          type: string
          nullable: true
        video_index:
          type: integer
          nullable: true
        audio_indexes:
          type: array
          items:
            type: integer
            format: int32
          nullable: true
        subtitle_indexes:
          type: array
          items:
            type: integer
            format: int32
          nullable: true

    ProjectCollection:
      type: object
      properties:
        projects:
          type: array
          items:
            $ref: "#/components/schemas/Project"
        next_token:
          type: string
        prev_token:
          type: string

    Project:
      description: |
        Project is used to group many jobs and for connection with other services e.g. stores livesync, notifications or IAM
      type: object
      properties:
        id:
          readOnly: true
          description: "Unique project identifier"
          type: string
        name:
          description: "User given name of project"
          type: string
        created_at:
          readOnly: true
          type: string
          format: date-time
        updated_at:
          readOnly: true
          type: string
          format: date-time
        template_id:
          description: "Id of default template, when empty user have to add this template_id for each job request"
          type: string
          nullable: true
        template_name:
          type: string
          nullable: true
        store_id:
          description: "Store id used to upload input files to cloud"
          type: string
          nullable: true
        region:
          type: string
          nullable: true
        proxy:
          type: string
          nullable: false
        proxy_profile:
          type: string
          nullable: false
        proxy_factory_id:
          type: string
          nullable: true

    ProjectCreateReq:
      type: object
      properties:
        name:
          description: "User given name of project"
          type: string
          nullable: false
        template_id:
          description: "Id of default template, when empty user have to add this template_id for each job request"
          type: string
          nullable: true
        store_id:
          description: "Store id used to upload input files to cloud"
          type: string
          nullable: true
        path_format:
          description: "Path format for defined store"
          type: string
          nullable: true
          example: "/$date$/$id$"

        region:
          type: string
          nullable: true
        proxy:
          type: string
          nullable: false
          enum: [off, flip]
        proxy_profile:
          type: string
          nullable: false
          enum: [good, better, best, audio]
        proxy_factory_id:
          type: string
          nullable: true

    ProjectUpdateReq:
      type: object
      properties:
        name:
          description: "User given name of project"
          type: string
          nullable: false
        template_id:
          description: "Id of default template, when empty user have to add this template_id for each job request"
          type: string
          nullable: true
        store_id:
          description: "Store id used to upload input files to cloud"
          type: string
          nullable: true
        path_format:
          type: string
          nullable: true
        region:
          type: string
          nullable: true
        proxy:
          type: string
          nullable: false
          enum: [off, flip]
        proxy_profile:
          type: string
          nullable: false
          enum: [good, better, best, audio]
        proxy_factory_id:
          type: string
          nullable: true

    TemplateCreate:
      type: object
      required: [name, tests]
      properties:
        name:
          description: "User given name of a template"
          type: string
        audio_layout_id:
          description: "Id of audio layout to use"
          type: string
        package_layout_id:
          description: "Id of package layout to use"
          type: string
        engine_version:
          type: string
          example: "2021.6"
        aggregate_alerts:
          type: boolean
        aggregate_warning_limit:
          type: integer
        aggregate_error_limit:
          type: integer
        use_starttimecode:
          type: boolean
        tests:
          type: object
          additionalProperties:
            type: object
          example:
            "caption/subtitle_test":
              {
                "608_present": false,
                "708_present": false,
                "cc1_presence": false,
                "cc2_presence": false,
                "cc3_presence": false,
                "cc4_presence": false,
                "teletext_page": 0,
                "caption_dropout": true,
                "caption_present": false,
                "service1_presence": false,
                "service2_presence": false,
                "service3_presence": false,
                "service4_presence": false,
                "service5_presence": false,
                "service6_presence": false,
                "teletext_presence": false,
                "no_caption_threshold": 10,
                "caption_dropout_duration_units": 0,
              }
            "silence":
              {
                "quiet": false,
                "silent": true,
                "digital": true,
                "threshold": 0,
                "audio_track": 1,
                "dolbye_program": 1,
              }

    JobCreate:
      type: object
      properties:
        url:
          type: string
        template_id:
          description: "Template ID for processing this file, when empty default template form project will be used"
          type: string
          nullable: true
        template:
          $ref: "#/components/schemas/TemplateCreate"
        project_id:
          description: "Project ID under which job will be grouped, if empty default project will be used"
          type: string
          nullable: true
        payload:
          description: "User payload for the job"
          type: string
          nullable: true
        sidecars:
          type: array
          items:
            type: string

    JobCollection:
      type: object
      required: [jobs]
      properties:
        jobs:
          type: array
          items:
            $ref: "#/components/schemas/JobInfo"
        next_token:
          type: string
        prev_token:
          type: string

    JobWithTemplate:
      type: object
      required:
        [
          id,
          project_id,
          project_name,
          created_at,
          updated_at,
          status,
          progress,
          url,
          file_name,
          template,
        ]
      properties:
        id:
          type: string
        project_id:
          type: string
        project_name:
          type: string
        template_id:
          type: string
        template_name:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        state:
          description: "File state, indicated whether file passed test from template"
          type: string
          example: "warning"
        status:
          description: "File processing status, indicateds only what is currently happening with this file"
          example: "success"
          type: string
        progress:
          type: integer
        message:
          description: "More informative message than status"
          type: string
        url:
          type: string
          example: "http://examplec.com/file.mp4"
        payload:
          type: string
        alerts:
          type: array
          items:
            $ref: "#/components/schemas/Alert"
        alerts_summary:
          $ref: "#/components/schemas/AlertsSummary"
        file_info:
          type: object
        file_name:
          type: string
          description: "file name - fetched from url"
        graph_data_url:
          type: string
        sidecars:
          type: array
          items:
            type: string
        template:
          $ref: "#/components/schemas/Template"
    Job:
      type: object
      required:
        [
          id,
          project_id,
          project_name,
          created_at,
          updated_at,
          status,
          progress,
          url,
          file_name,
        ]
      properties:
        id:
          type: string
        project_id:
          type: string
        project_name:
          type: string
        template_id:
          type: string
        template_name:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        state:
          description: "File state, indicated whether file passed test from template"
          type: string
          example: "warning"
        status:
          description: "File processing status, indicateds only what is currently happening with this file"
          example: "success"
          type: string
        progress:
          type: integer
        message:
          description: "More informative message than status"
          type: string
        url:
          type: string
          example: "http://examplec.com/file.mp4"
        payload:
          type: string
        alerts:
          type: array
          items:
            $ref: "#/components/schemas/Alert"
        alerts_summary:
          $ref: "#/components/schemas/AlertsSummary"
        file_info:
          type: object
        file_name:
          type: string
          description: "file name - fetched from url"
        graph_data_url:
          type: string
        sidecars:
          type: array
          items:
            type: string
    JobInfo:
      type: object
      required:
        [
          id,
          project_id,
          project_name,
          created_at,
          updated_at,
          status,
          progress,
          url,
          file_name,
        ]
      properties:
        id:
          type: string
        project_id:
          type: string
        project_name:
          type: string
        template_id:
          type: string
        template_name:
          type: string
        created_at:
          type: string
          format: date-time
        updated_at:
          type: string
          format: date-time
        state:
          description: "File state, indicated whether file passed test from template"
          type: string
          example: "warning"
        status:
          description: "File processing status, indicateds only what is currently happening with this file"
          example: "success"
          type: string
        progress:
          type: integer
        message:
          description: "More informative message than status"
          type: string
        url:
          type: string
          example: "http://examplec.com/file.mp4"
        payload:
          type: string
        alerts_summary:
          $ref: "#/components/schemas/AlertsSummary"
        file_name:
          type: string
          description: "file name - fetched from url"
        sidecars:
          type: array
          items:
            type: string
    AlertsSummary:
      type: object
      required: [infos, warnings, rejects]
      properties:
        infos:
          type: integer
        warnings:
          type: integer
        rejects:
          type: integer
    JobProxy:
      type: object
      properties:
        id:
          type: string
        progress:
          type: number
          nullable: true
        status:
          type: string
        updated_at:
          type: string
          format: date-time
        url:
          type: string
        error_message:
          type: string
          nullable: true

    Alert:
      type: object
      properties:
        id:
          type: string
        description:
          type: string
        test_name:
          type: string
        level:
          type: string
          example: "warning"
        start:
          type: string
          description: first frame of alert
        end:
          type: string
          description: last frame of alert
        location:
          type: string

    Region:
      type: object
      properties:
        id:
          type: string
        provider:
          type: string
          description: |
            Provider name for region
            enum: gcp | aws | azure | oci
          example: aws
        region:
          type: string
          example: us-east-1
        default:
          type: boolean

paths:
  /regions:
    get:
      tags:
        - QC
      operationId: list_regions
      summary: "List all available regions"
      responses:
        200:
          description: |

          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: "#/components/schemas/Region"
  /engine_versions:
    get:
      tags:
        - QC
      operationId: list_engine_versions
      summary: "List all available engine versions"
      responses:
        200:
          description: |

          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
  /templates:
    get:
      tags:
        - QC
      operationId: list_templates
      parameters:
        - $ref: "#/components/parameters/token"
      summary: "List all available templates under account"
      responses:
        200:
          description: |
            list of templates
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/TemplateCollection"
    post:
      tags:
        - QC
      operationId: CreateTemplate
      summary: "Create template"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TemplateCreate"
      responses:
        201:
          description: |
            created template
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Template"
        404:
          description: |
            associated object not found

  /templates/{template-id}:
    parameters:
      - $ref: "#/components/parameters/template-id"
    get:
      tags:
        - QC
      operationId: get_template
      summary: "Get template"
      responses:
        200:
          description: "Show template"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Template"
        404:
          description: "template not found"
    put:
      tags:
        - QC
      operationId: UpdateTemplate
      summary: "Update template"
      description: |
        Updated a template. It is a FULL update, meaning if some parameter is not provided, it will be set to its zero/null value
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/TemplateCreate"
      responses:
        200:
          description: "Updated template"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Template"
        404:
          description: "template or any of the associated objects not found"
    delete:
      tags:
        - QC
      operationId: delete_template
      summary: "Delete template"
      responses:
        204:
          description: "Delete template"
        404:
          description: "template not found"
  /templates/{template-id}/duplicate:
    parameters:
      - $ref: "#/components/parameters/template-id"
    post:
      tags:
        - QC
      operationId: DuplicateTemplate
      summary: "Duplicate Template"
      responses:
        201:
          description: |
            created template
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Template"
        404:
          description: |
            associated object not found

  /projects:
    get:
      tags:
        - QC
      operationId: list_projects
      summary: "List projects"
      responses:
        200:
          description: "Collection of projects"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectCollection"
    post:
      tags:
        - QC
      operationId: create_project
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProjectCreateReq"

      summary: "Create a new project"
      responses:
        200:
          description: "Created project"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Project"

  /projects/{project-id}:
    get:
      tags:
        - QC
      operationId: get_project
      parameters:
        - $ref: "#/components/parameters/project-id"
      summary: "Get project"
      responses:
        200:
          description: "Show project"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Project"
    put:
      tags:
        - QC
      operationId: update_project
      description: |
        Updated a project. It is a FULL update, meaning if some parameter is not provided, it will be set to its zero/null value
      parameters:
        - $ref: "#/components/parameters/project-id"
      summary: "Update project"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ProjectUpdateReq"
      responses:
        200:
          description: "Update OK"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectCreateReq"
        404:
          description: "project or any of the associated objects not found"
    delete:
      tags:
        - QC
      operationId: delete_project
      parameters:
        - $ref: "#/components/parameters/project-id"
      summary: "Delete project"
      responses:
        204:
          description: "Delete project"
        404:
          description: "Not found"

  /projects/{project-id}/summary:
    get:
      tags:
        - QC
      operationId: get_project_summary
      parameters:
        - $ref: "#/components/parameters/project-id"
      summary: "Get project summary"
      responses:
        200:
          description: "Project summary"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ProjectSummary"

  /jobs:
    get:
      tags:
        - QC
      operationId: ListJobs
      parameters:
        - $ref: "#/components/parameters/maxResults"
        - $ref: "#/components/parameters/pageDirection"
        - $ref: "#/components/parameters/token"
        - $ref: "#/components/parameters/project-filter"
      summary: "List all jobs"
      responses:
        200:
          description: "List jobs"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JobCollection"
    post:
      tags:
        - QC
      operationId: CreateJob
      summary: "Create new job"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/JobCreate"
      responses:
        201:
          description: "Created job"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JobWithTemplate"

  /jobs/{job-id}:
    get:
      tags:
        - QC
      operationId: ReadJob
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Get job"
      responses:
        200:
          description: "Get job"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Job"
        404:
          description: "Not found"
    delete:
      tags:
        - QC
      operationId: delete_job
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Delete job"
      responses:
        204:
          description: "Delete job"
        404:
          description: "Not found"

  /jobs/{job-id}/reports:
    get:
      tags:
        - QC
      operationId: get_job_reports
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Get job"
      responses:
        200:
          description: "Get job"
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                example:
                  - "https://telestream.s3.amazonaws.com/qualify/reports/report.pdf?param1=value1&param2=value2"

        404:
          description: "Not found"
  /jobs/{job-id}/cancel:
    put:
      tags:
        - QC
      operationId: cancel_job
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Cancel job"
      responses:
        200:
          description: "Cancelled job"
        404:
          description: "Not found"

  /jobs/{job-id}/restart:
    put:
      tags:
        - QC
      operationId: restart_job
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Restart job"
      responses:
        200:
          description: "Restarted job"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Job"
        404:
          description: "Not found"

  /jobs/{job-id}/proxy:
    post:
      tags:
        - QC
      operationId: create_proxy
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Create job proxy"
      responses:
        200:
          description: "Scheduled job proxy creation (or proxy is off)"
        404:
          description: "Not found"
    get:
      tags:
        - QC
      operationId: get_proxy
      parameters:
        - $ref: "#/components/parameters/job-id"
      summary: "Get job proxy"
      responses:
        200:
          description: "Scheduled job proxy creation (or proxy is off)"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/JobProxy"
        404:
          description: "Not found"

  /package_layouts:
    get:
      tags:
        - QC
      operationId: list_package_layouts
      parameters:
        - $ref: "#/components/parameters/token"
      summary: "List all available package layouts under account"
      responses:
        200:
          description: |
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageLayoutCollection"
    post:
      tags:
        - QC
      operationId: create_package_layout
      summary: "Create new package layout"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PackageLayoutCreateReq"
      responses:
        201:
          description: "Created package layout"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageLayout"

  /package_layouts/{packagelayout-id}:
    get:
      tags:
        - QC
      operationId: get_package_layout
      parameters:
        - $ref: "#/components/parameters/packagelayout-id"
      summary: "Get package layout"
      responses:
        200:
          description: "Get package layout"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageLayout"
        404:
          description: "Not found"
    patch:
      tags:
        - QC
      operationId: update_package_layout
      parameters:
        - $ref: "#/components/parameters/packagelayout-id"
      summary: "Update package layout"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/PackageLayoutUpdateReq"
      responses:
        200:
          description: "Updated package layout"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/PackageLayout"
        404:
          description: "Not found"
    delete:
      tags:
        - QC
      operationId: delete_package_layout
      parameters:
        - $ref: "#/components/parameters/packagelayout-id"
      summary: "Delete package layout"
      responses:
        204:
          description: "Deleted package layout"
        404:
          description: "Not found"

  /audio_layouts:
    get:
      tags:
        - QC
      operationId: list_audio_layouts
      parameters:
        - $ref: "#/components/parameters/token"
      summary: "List all available audio layouts under account"
      responses:
        200:
          description: |
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AudioLayoutCollection"
    post:
      tags:
        - QC
      operationId: create_audio_layout
      summary: "Create new audio layout"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AudioLayoutCreateReq"
      responses:
        201:
          description: "Created audio layout"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AudioLayout"

  /audio_layouts/{audiolayout-id}:
    get:
      tags:
        - QC
      operationId: get_audio_layout
      parameters:
        - $ref: "#/components/parameters/audiolayout-id"
      summary: "Get audio layout"
      responses:
        200:
          description: "Get audio layout"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AudioLayout"
        404:
          description: "Not found"
    patch:
      tags:
        - QC
      operationId: update_audio_layout
      parameters:
        - $ref: "#/components/parameters/audiolayout-id"
      summary: "Update audio layout"
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/AudioLayoutUpdateReq"
      responses:
        200:
          description: "Updated package layout"
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/AudioLayout"
        404:
          description: "Not found"
    delete:
      tags:
        - QC
      operationId: delete_audio_layout
      parameters:
        - $ref: "#/components/parameters/audiolayout-id"
      summary: "Delete audio layout"
      responses:
        204:
          description: "Deleted audio layout"
        404:
          description: "Not found"