openapi: 3.0.1

info:
  title: "Online Thing Catalog API"
  description: "The Online Thing Catalog API is the backend API for the Online Thing Catalog, a service that allows users to upload, manage and share products in the catalog."
  version: 1.0.0

servers:
  - description: OTC API PROD
    url: https://api.ac-onlinecatalog.horizoncloud.io
  - description: OTC API INT
    url: https://api.ac-onlinecatalog.horizonint.cloud
  - description: OTC API DEV
    url: https://api.ac-onlinecatalog.horizondev.cloud

paths:
  /api/v1/me/info:
    get:
      summary: Greeting for the API with a timestamp
      description: >
        Returns a short Greeting with a timestamp. 

        This endpoint is mostly used for testing purposes. To see if the authorization works for example.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.ui.basic
      responses:
        200:
          description: Greeting with a timestamp
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/productArray"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Info
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/products:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/versionParamOptional"
      - $ref: "#/components/parameters/stateParamOptional"
      - $ref: "#/components/parameters/isPublicParamOptional"
    get:
      summary: Returns all products of a domain
      description: >
        Returns all products of a domain, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Products retrieved successfully.

            Response contains all products of the domain.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/productArray"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Products
    post:
      summary: Add a product to your catalog domain by uploading a zip file containing a product
      description: |
        The uploaded zip file is extracted and its content pushed to S3.
        
        Simultaneously, it is processed and added to the catalog database.
      security:
        - lambdaAuthorizer: [ ]
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.create
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              oneOf:
                - $ref: "#/components/schemas/scope"
      responses:
        201:
          description: |
            Returns 201 Created status when the handling was successful.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Products
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/products/{productName}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/productNameParam"
      - $ref: "#/components/parameters/stateParamOptional"
      - $ref: "#/components/parameters/isPublicParamOptional"
    get:
      summary: Returns a single product in all available versions
      description: >
        Returns a single product in all available versions. The state and visibility can be filtered by the query parameters.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Products retrieved successfully.

            Response contains the product in all versions.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/productArray"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Products
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST,DELETE,PATCH,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/products/{productName}/{productVersion}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/productNameParam"
      - $ref: "#/components/parameters/versionParamPath"
    get:
      summary: Returns a single product in the given version.
      description: >
        Returns a single product in the given version.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Product retrieved successfully.

            Response contains the product.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/product"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Products
    patch:
      summary: Update a product state
      description: Updates the state attribute for the specified product
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/stateUpdateRequestBody"
      responses:
        200:
          description: |
            Product state updated successfully.
        202:
          description: |
            Product was not updated because update state was the same.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Products
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST,DELETE,PATCH,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
    get:
      summary: Returns a specific customer item
      description: >
        Returns a specific customer item.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: subscription.customer.read
      responses:
        200:
          description: |
            Customer retrieved successfully.

            Response contains the customers details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/customerResponseBody"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Customers
    post:
      summary: Create a new customer
      description: Creates a new catalog customer in OTC
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/customerCreateRequestBody"
      responses:
        201:
          description: |
            Returns 201 Created status when the creation was successful.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Customers
    patch:
      summary: Update customers data
      description: Partial update of customer attributes
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              anyOf:
                - $ref: "#/components/schemas/nameUpdateRequestBody"
                - $ref: "#/components/schemas/subscriptionUpdateRequestBody"
                - $ref: "#/components/schemas/activeUpdateRequestBody"
              oneOf:
                - $ref: "#/components/schemas/etagUpdateRequestBody"
              additionalProperties: false
      responses:
        200:
          description: |
            Customer name updated successfully.

            Response the new customer struct.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/customerResponseBody"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Customers
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/usergroups:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
    post:
      summary: Add a user group
      description: Creates a new user group for a customer with optional partition access and role assignments.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: user.user-group.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/userGroupCreateRequestBody"
      responses:
        201:
          description: User group created successfully.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - User Groups
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/usergroups/{userGroupId}:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
      - $ref: "#/components/parameters/userGroupIdParam"
    patch:
      summary: Update a user group
      description: >
        Partially updates a user group for a customer. Supports updating name, description,
        and managing relationships (authorizedAs, hasAccessTo, hasMembers) with add/remove operations.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/userGroupPatchRequestBody"
      responses:
        204:
          description: User group updated successfully (no content).
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - User Groups
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,PATCH'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/invitations:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
    post:
      summary: Invite a user
      description: Sends an invitation to a user for a customer, optionally assigning them to user groups.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: user.invite.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/invitationCreateRequestBody"
      responses:
        201:
          description: Invitation created successfully.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Invitations
    get:
      summary: Get all invitations
      description: Returns all invitations for a customer.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: user.invite.read
      responses:
        200:
          description: Invitations retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/invitationsGetResponseBody"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Invitations
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/invitations/{invitationId}:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
      - $ref: "#/components/parameters/invitationIdParam"
    patch:
      summary: Resend an invitation
      description: Resends an existing invitation to a user.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: user.invite.update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/resendInvitationRequestBody"
      responses:
        204:
          description: Invitation resent successfully (no content).
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Invitations
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,PATCH'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/machines:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
    post:
      summary: Create a machine user
      description: Creates a machine user for a customer.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: user.machines.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/invitationCreateRequestBody"
      responses:
        201:
          description: Machine user created successfully.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Machines
    get:
      summary: Get all machine users
      description: Returns all machine users for a customer.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: user.machines.read
      responses:
        200:
          description: Machine Users retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/invitationsGetResponseBody"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Machines
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/domains:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
    get:
      summary: Returns all domains a customer has access to
      description: >
        Returns all domains to which the customer with the corresponding customerId has access to.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.list
      responses:
        200:
          description: |
            Domains retrieved successfully.

            Response contains all domains the customer has access to.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/domainArray"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Domains
    post:
      summary: Add a domain to the db
      description: Creates a domain for a specific customer
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/domainCreateRequestBody"
      responses:
        201:
          description: |
            Returns 201 Created status when the creation was successful.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Domains
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/domain:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Returns a specific domain item
      description: >
        Returns a specific domain item.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.read
      responses:
        200:
          description: |
            Domain retrieved successfully.

            Response contains the domains details.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/domain"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Domains
    patch:
      summary: Update a domains name
      description: Updates a domains name attribute in the db
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/nameUpdateRequestBody"
      responses:
        200:
          description: |
            Domain name updated successfully.

            Response the new domain struct.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/domain"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Domains
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,PATCH'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/domain/versions:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Returns all versions available for a domain
      description: >
        Returns all versions available for a domain
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.read
      responses:
        200:
          description: |
            Domain versions retrieved successfully.

            Response contains the domain versions available.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/domainVersionArray"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Domains
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/domain/meta:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/versionParamOptional"
      - $ref: "#/components/parameters/stateParamOptional"
      - $ref: "#/components/parameters/isPublicParamOptional"
    get:
      summary: Returns all meta of a domain
      description: >
        Returns all meta of a domain, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Metas retrieved successfully.

            Response contains all metas of the domain.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/metaArray"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Meta
    post:
      summary: Add metadata to S3 by uploading a zip file
      description: |
        The uploaded zip file is extracted and its content pushed to S3.

        The sync lambda will take care of adding the DB entries.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.create
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              oneOf:
                - $ref: "#/components/schemas/scopeMeta"
      responses:
        201:
          description: |
            Returns 201 Created status when the upload and extracting to S3 was successful.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Meta
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/domain/meta/{productName}/{productVersion}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/productNameParam"
      - $ref: "#/components/parameters/versionParamPath"
      - $ref: "#/components/parameters/stateParamOptional"
      - $ref: "#/components/parameters/isPublicParamOptional"
    get:
      summary: Returns a single meta in the given version.
      description: >
        Returns a single meta in the given version.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Meta retrieved successfully.

            Response contains the meta.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/meta"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Meta
    patch:
      summary: Update a meta state
      description: Updates the state attribute for the specified meta
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/stateUpdateRequestBody"
      responses:
        200:
          description: |
            Meta state updated successfully.
        202:
          description: |
            Meta was not updated because update state was the same.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Meta
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,PATCH'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS
  /api/v1/partitions/{partitionId}/domain/templates:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Getting all descriptor templates a user has access to
      description: >
        Returns all templates, provided the user has access to the associated domain/partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.read
      responses:
        200:
          description: Templates retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/templatesResponse"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Template

  /api/v1/partitions/{partitionId}/domain/templates/{templateType}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/templateTypeParam"
    get:
      summary: Getting all descriptor templates of a specific type a user has access to
      description: >
        Returns all templates of a specific type, provided the user has access to the associated domain/partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.read
      responses:
        200:
          description: Templates retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/templatesResponse"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Template

  /api/v1/partitions/{partitionId}/domain/templates/{templateType}/{templateName}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/templateTypeParam"
      - $ref: "#/components/parameters/templateNameParam"
    post:
      summary: Add descriptor template to domain
      description: |
        The descriptor template will be added to the domain in the db and used for the generation of the domain descriptors.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.update
      requestBody:
        required: true
        content:
          multipart/form-data:
            schema:
              oneOf:
                - $ref: "#/components/schemas/domainTemplate"
      responses:
        201:
          description: |
            Returns 201 Created status when the upload was successful.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Template
    get:
      summary: Getting a descriptor template a user has access to
      description: >
        Returns a template, provided the user has access to the associated domain/partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.read
      responses:
        200:
          description: Template retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/templateResponse"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Template
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,POST'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/domain/templates/{templateType}/{templateName}/default:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/templateTypeParam"
      - $ref: "#/components/parameters/templateNameParam"
    put:
      summary: Sets a descriptor template default attribute to true or false
      description:
        The descriptor template default attribute will be set to the provided value in the db and used for the generation of the domain descriptors accordingly.
        If a template is set to default, it will be used as default template for the generation of the domain descriptors. There can only be one default template per template type and domain.
        If a template is set to non-default, it can still be used for the generation of the domain descriptors but it will not be the default template.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.update
      responses:
        200:
          description: |
            Template active attribute updated successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/templateResponse"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Template

  /api/v1/partitions/{partitionId}/domain/templates/{templateType}/{templateName}/active:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/templateTypeParam"
      - $ref: "#/components/parameters/templateNameParam"
      - $ref: "#/components/parameters/templateIsActiveParam"
    put:
      summary: Sets a descriptor template active attribute to true or false
      description:
        The descriptor template active attribute will be set to the provided value in the db and used for the generation of the domain descriptors accordingly.
        If a template is set to inactive, it will not be used for the generation of the domain descriptors but will still be stored in the db.
        If a template is set to active, it can be used for the generation of the domain descriptors.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.domain.update
      responses:
        200:
          description: |
            Template active attribute updated successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/templateResponse"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Template

  /api/v1/customers/{customerId}/scopes:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
    get:
      summary: Getting all the scopes a customer has access to
      description: >
        Returns all scopes of a customer to which the customer with the corresponding customerId has access to.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.list
      parameters:
        - $ref: "#/components/parameters/customerIdParam"
      responses:
        200:
          description: |
            Scopes retrieved successfully.

            Response contains all scopes the customer has access to.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopesResponse"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    post:
      summary: Add a scope to the db
      description: Creates a scope for a specific customer
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.create
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/scope"
      responses:
        201:
          description: |
            Returns 201 Created status when the upload and extracting to S3 was successful.
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST,GET'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Getting a scope a user has access to
      description: >
        Returns a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.read
      responses:
        200:
          description: Scope retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeResponse"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    patch:
      summary: Update a scope's name
      description: Updates a scope's name attribute in the db
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/nameUpdateRequestBody"
      responses:
        200:
          description: |
            Scope name updated successfully.

            Respond with the new scope struct.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/domain"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,PATCH'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/all:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Getting all domains, products and metas of a scope
      description: >
        Returns all domains, products and metas of a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.read
      responses:
        200:
          description: Scope details retrieved successfully.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeAll"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/domains:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Returns all domains of a scope
      description: >
        Returns all domains of a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.read
      responses:
        200:
          description: |
            Domains retrieved successfully.

            Response contains all domains within a scope.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeDomains"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    put:
      summary: Add a domain into a scope
      description: Add a domain into a scope
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      requestBody:
        required: true
        content:
          application/json:
            schema:
              oneOf:
                - $ref: "#/components/schemas/domainToScopeRequestBody"
      responses:
        200:
          description: |
            Added domain to scope. It is now possible to get products from the newly added domain.

            Respond with the new scope-domain struct.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeDomain"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/products:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Returns all products of a scope
      description: >
        Returns all products of a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Products retrieved successfully.

            Response contains all products in the scope.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeProducts"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,DELETE'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/metas:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
    get:
      summary: Returns all metas of a scope
      description: >
        Returns all metas of a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Metas retrieved successfully.

            Response contains all metas in the scope.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeMetas"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,DELETE'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/domains/{domainUuid}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/domainUuidParam"
    delete:
      summary: Remove a domain from a scope
      description: Remove a domain from a scope
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      responses:
        204:
          description: Removed a domain from a scope
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,DELETE'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/products/{domainUuid}/{productName}/{productVersion}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/domainUuidParam"
      - $ref: "#/components/parameters/productNameParam"
      - $ref: "#/components/parameters/versionParamPath"
    get:
      summary: Getting a product of a scope by domain, product name and version
      description: >
        Returns a specific version of a product within a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: Greeting with a timestamp
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeProduct"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    put:
      summary: Add a product to a scope
      description: Add a product to a scope
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      responses:
        200:
          description: |
            Added a product to scope.

            Respond with the new scope-product struct.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeProduct"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    delete:
      summary: Remove a product from a scope
      description: Remove a product from a scope
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      responses:
        204:
          description: Removed a product from a scope
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,DELETE,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/partitions/{partitionId}/scope/metas/{domainUuid}/{productName}/{productVersion}:
    parameters:
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/domainUuidParam"
      - $ref: "#/components/parameters/productNameParam"
      - $ref: "#/components/parameters/versionParamPath"
    get:
      summary: Returns a specific meta of a product version within a scope
      description: >
        Returns a specific meta of a product version within a scope, provided the user has access to the associated partition.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.product.read
      responses:
        200:
          description: |
            Meta retrieved successfully.

            Response contains the meta of a scope product.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeMeta"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    put:
      summary: Add meta data to a scope
      description: Add meta data to a scope
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      responses:
        200:
          description: |
            Added meta data to scope.

            Respond with the new scope-meta struct.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/scopeMeta"
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    delete:
      summary: Remove meta data from a scope
      description: Remove meta data from a scope
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: otc.catalog.scope.update
      responses:
        204:
          description: Removed meta data from a scope
        400:
          $ref: "#/components/responses/badRequest"
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        408:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Scopes
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,GET,DELETE,PUT'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

  /api/v1/customers/{customerId}/partitions/{partitionId}/scope/share/{targetCustomerId}:
    parameters:
      - $ref: "#/components/parameters/customerIdParam"
      - $ref: "#/components/parameters/partitionIdParam"
      - $ref: "#/components/parameters/targetCustomerIdParam"
    post:
      summary: Share a scope
      description: Share a scope related partition with another customer.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: subscription.partitions.update
      responses:
        204:
          description: Share established (no content).
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Partition sharing
    delete:
      summary: Unshare a partition
      description: Unshare a partition with another customer.
      security:
        - lambdaAuthorizer: []
      x-amazon-apigateway-integration:
        uri: "${rm_api_lambda_function_uri}"
        passthroughBehavior: when_no_match
        httpMethod: POST
        type: aws_proxy
      x-api-permission: subscription.partitions.update
      responses:
        204:
          description: |
            Returns 204 No Content when the unsharing was successful.
        401:
          $ref: "#/components/responses/unauthorized"
        403:
          $ref: "#/components/responses/forbidden"
        404:
          $ref: "#/components/responses/notFound"
        500:
          $ref: "#/components/responses/internalError"
      tags:
        - Partition sharing
    options:
      # allow cors
      responses:
        200:
          description: "200 response"
          headers:
            Access-Control-Allow-Origin:
              schema:
                type: "string"
            Access-Control-Allow-Methods:
              schema:
                type: "string"
            Access-Control-Allow-Credentials:
              schema:
                type: "string"
            Access-Control-Allow-Headers:
              schema:
                type: "string"
          content: {}
      x-amazon-apigateway-integration:
        responses:
          default:
            statusCode: "200"
            responseParameters:
              method.response.header.Access-Control-Allow-Credentials: "'false'"
              method.response.header.Access-Control-Allow-Methods: "'OPTIONS,POST,DELETE'"
              method.response.header.Access-Control-Allow-Headers: "'Content-Type,X-Amz-Date,Authorization,X-Api-Key,X-Amz-Security-Token,X-Amz-User-Agent'"
              method.response.header.Access-Control-Allow-Origin: "'*'"
            responseTemplates:
              application/json:
                "#set($origin = $input.params(\"Origin\"))\n#if($origin\
                \ == \"\") #set($origin = $input.params(\"origin\")) #end\n#if($origin.matches(\"\
                .*\")) #set($context.responseOverride.header.Access-Control-Allow-Origin\
                \ = $origin) #end"
        passthroughBehavior: "when_no_match"
        requestTemplates:
          application/json: "{statusCode:200}"
        contentHandling: "CONVERT_TO_TEXT"
        type: "mock"
      tags:
        - CORS

components:
  schemas:
    customerId:
      type: string
      description: Unique identifier of a customer
      example: e8bdea2f-0f07-4a07-b19a-1f86d7848369
    customerCreateRequestBody:
      type: object
      required:
        - subscription
      properties:
        name:
          type: string
          example: sysaut
          description: The name of the customer to be created
        subscription:
          type: string
          example: 7581c183-1d39-4609-90c1-9f8206141377
          description: The subscription id of this customer
        active:
          type: boolean
          example: true
          description: Whether the subscription is active or not
    userGroupCreateRequestBody:
      type: object
      required:
        - name
      properties:
        name:
          type: string
          example: TestUserGroup
          description: The name of the user group
        description:
          type: string
          example: The test user group
          description: A description for the user group
        hasAccessTo:
          type: array
          description: Partitions this user group should have access to
          items:
            $ref: "#/components/schemas/relationshipItem"
        authorizedAs:
          type: array
          description: Roles this user group should be authorized as
          items:
            $ref: "#/components/schemas/relationshipItem"
    relationshipItem:
      type: object
      required:
        - type
        - id
      properties:
        type:
          type: string
          example: Partition
          description: The type of the related resource (e.g. Partition, Role)
        id:
          type: string
          example: 6cefc7ae-61a7-485b-ab0d-88ef436077b3
          description: The unique identifier of the related resource
    userGroupPatchRequestBody:
      type: object
      properties:
        name:
          type: string
          example: CustomerAdministrator
          description: The updated name of the user group
        description:
          type: string
          example: Customer Administrator for managing user groups
          description: The updated description of the user group
        authorizedAs:
          type: array
          description: Roles to add or remove from this user group
          items:
            $ref: "#/components/schemas/patchRelationshipItem"
        hasAccessTo:
          type: array
          description: Partitions to add or remove access for this user group
          items:
            $ref: "#/components/schemas/patchRelationshipItem"
        hasMembers:
          type: array
          description: Users/MachineUsers to add or remove from this user group
          items:
            $ref: "#/components/schemas/patchRelationshipItem"
    patchRelationshipItem:
      type: object
      required:
        - id
        - type
        - meta
      properties:
        id:
          type: string
          example: 6cefc7ae-61a7-485b-ab0d-88ef436077b3
          description: The unique identifier of the related resource
        type:
          type: string
          example: Partition
          description: The type of the related resource (e.g. Partition, Role, User, MachineUser)
        meta:
          type: object
          required:
            - op
          properties:
            op:
              type: string
              enum:
                - add
                - remove
              example: add
              description: The operation to perform (add or remove)
    resendInvitationRequestBody:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          example: user@example.com
          description: The email address of the invitation recipient
        name:
          type: string
          example: Xaver Tester
          description: The name of the invitation recipient
        language:
          type: string
          example: en
          description: The language for the invitation
    invitationCreateRequestBody:
      type: object
      required:
        - email
      properties:
        email:
          type: string
          example: user@example.com
          description: The email address of the user to invite
        name:
          type: string
          example: Xaver Tester
          description: The name of the user to invite
        language:
          type: string
          example: en
          description: The language for the invitation
        InvitedTo:
          type: array
          description: User groups to invite the user to
          items:
            $ref: "#/components/schemas/relationshipItem"
    invitationsGetResponseBody:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: "#/components/schemas/invitationItem"
    invitationItem:
      type: object
      properties:
        id:
          type: string
          example: 94a373df-f719-553b-9418-6b814eabc683
          description: Unique identifier of the invitation
        type:
          type: string
          example: Invitation
        attributes:
          type: object
          properties:
            customerId:
              type: string
            firstSendByUserId:
              type: string
            firstSentByUserName:
              type: string
            key:
              type: string
            language:
              type: string
            lastSentByUserId:
              type: string
            lastSentByUserName:
              type: string
            recipientEmail:
              type: string
            recipientName:
              type: string
            sender:
              type: string
            state:
              type: string
              example: pending
        meta:
          type: object
          properties:
            createdAt:
              type: string
              format: date-time
            expiresAt:
              type: string
              format: date-time
            lastSentAt:
              type: string
              format: date-time
            updatedAt:
              type: string
              format: date-time
        relationships:
          type: object
          properties:
            InvitedTo:
              type: object
              properties:
                data:
                  type: array
                  items:
                    $ref: "#/components/schemas/relationshipItem"
    customerResponseBody:
      type: object
      description: Customer object containing all the requested information
      properties:
        pk:
          type: string
          example: CUSTOMER|e8bdea2f-0f07-4a07-b19a-1f86d7848369
          description: The partition key of the customer item
        sk:
          type: string
          example: CUSTOMER|e8bdea2f-0f07-4a07-b19a-1f86d7848369
          description: The sort key of the customer item
        name:
          type: string
          example: sysaut
          description: The name of the customer
        ns:
          type: string
          example: CUSTOMER
          description: Namespace
        subscription:
          type: string
          example: 7581c183-1d39-4609-90c1-9f8206141377
          description: The subscription id of this customer
        etag:
          type: integer
          example: 1
          description: Entity tag for versioning
    scopeId:
      type: string
      description: Unique identifier of a scope
      example: 6cefc7ae-61a7-485b-ab0d-88ef436077b3
    partitionId:
      type: string
      description: |
        Unique identifier of a partition. Context-dependent value that represents either a domain ID 
        (for domain-related operations) or a scope ID (for scope-related operations).
      example: 6cefc7ae-61a7-485b-ab0d-88ef436077b3
    domainId:
      type: string
      description: Unique identifier of a domain
      example: 6cefc7ae-61a7-485b-ab0d-88ef436077b3
    domainArray:
      type: array
      description: Multiple domains at once.
      minItems: 1
      items:
        $ref: "#/components/schemas/domain"
    domain:
      type: string
      description: Domain of a product
      example: sa
    domainVersionArray:
      type: array
      description: Multiple domain versions at once.
      items:
        $ref: "#/components/schemas/domainVersion"
    domainVersion:
      type: object
      description: An object describing a specific version of a domain
      properties:
        pk:
          type: string
          description: Partition key
        sk:
          type: string
          description: Sort key
        domain:
          type: string
          description: The domain of the domain version item
        version:
          type: integer
          description: The version of the domain version item
        ns:
          type: string
          description: Namespace
        etag:
          type: integer
          description: Entity tag for versioning
    domainTemplate:
      type: object
      description: The descriptor-template for this domain, a valid json schema
    templatesResponse:
      type: array
      description: An array of template objects
      items:
        $ref: "#/components/schemas/templateResponse"
    templateResponse:
      type: object
      description: The response containing the descriptor-template for a domain
      properties:
        pk:
          type: string
          description: Partition key
        sk:
          type: string
          description: Sort key
        active:
          type: boolean
          description: Whether the template is active or not
        name:
          type: string
          description: The name of the template
        domain:
          type: string
          description: The domain of the template
        ns:
          type: string
          description: Namespace
        default:
          type: boolean
          description: Whether this template is the default template for this domain or not
        template:
          type: object
          description: The descriptor-template for this domain, a valid json schema
        templateType:
          type: string
          description: The type of the template, can be either "MANIFEST" or "MODEL"
        etag:
          type: integer
          description: Entity tag for versioning
    domainCreateRequestBody:
      type: object
      required:
        - name
        - domain
        - distributor
        - descriptor-template
      properties:
        name:
          type: string
          example: Smart Automation
          description: The name of the domain to be created
        domain:
          type: string
          example: sa
          description: The domain id of the domain to be created
        distributor:
          type: string
          example: provider
          description: The type of domain to be created. Can be either "provider" or "system"
    nameUpdateRequestBody:
      type: object
      required:
        - name
        - etag
      properties:
        name:
          type: string
          example: Smart Automation
          description: The new name
        etag:
          type: number
          example: 12345678
          description: Entity tag for versioning
    subscriptionUpdateRequestBody:
      type: object
      required:
        - subscription
      properties:
        subscription:
          type: string
          example: 7581c183-1d39-4609-90c1-9f8206141377
          description: The new subscription id
    activeUpdateRequestBody:
      type: object
      required:
        - active
      properties:
        active:
          type: boolean
          example: true
          description: The new active status
    stateUpdateRequestBody:
      type: object
      required:
        - state
        - etag
      properties:
        state:
          type: string
          example: test
          description: the new state
        etag:
          type: number
          example: 12345678
          description: Entity tag for versioning
    domainToScopeRequestBody:
      type: object
      required:
        - domainUuid
        - privateAccess
      properties:
        domainUuid:
          type: string
          example: b9cfb905-f80d-426b-b065-c9374ed183a9
          description: The domain uuid
        privateAccess:
          type: boolean
          example: true
          description: Whether you have private access to the domain or not
    error:
      type: object
      required:
        - status
        - title
        - type
      properties:
        status:
          type: integer
          example: 400
          description: The HTTP status of the error
        title:
          type: string
          example: Summary of the error
          description: A short and easy readable summary of the problem
        type:
          type: string
          example: Generic Error
          description: An application-specific error code
        detail:
          type: string
          example: Detailing the specifics of this single occurrence of this error
          description: A human-readable explanation specific to this occurrence of the problem.
        id:
          type: string
          example: 2b9dfc64-aeb2-4335-hb47-fa3f270d2975
          description: A unique identifier for this particular occurrence of the problem
    etagUpdateRequestBody:
      type: object
      required:
        - etag
      properties:
        etag:
          type: integer
          example: 12345678
          description: Entity tag for versioning
      description: Entity tag for versioning
      example:
        etag: 12345678
    greeting:
      type: object
      description: Greeting with a timestamp
      properties:
        message:
          type: string
          example: Thank you for using the AC Onlinecatalog!
          description: The greeting text
        receivedAt:
          type: string
          example: 2024-02-28 10:00:00.437225772 +0000 UTC m=+0.063325012
          description: exact timestamp of calling the API
    scope:
      type: object
      description: Scope object containing all the requested information
      properties:
        name:
          type: string
          example: My Scope
          description: The name of the scope
        scope:
          type: string
          example: sca
          description: Unique identifier of a scope
        mode:
          type: string
          example: latest
          description: Preferred update mode for scope
    scopeProduct:
      type: object
      description: Scope-Product object containing all relevant information,
      properties:
        pk:
          type: string
          example: SCOPE|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Partition key (scope pk)
        sk:
          type: string
          example: DOMAIN|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Sort key (product sk)
        ns:
          type: string
          example: SCOPE
          description: Namespace
        type:
          type: string
          example: meta
          description: Indicator that it's a meta item
        scope:
          type: string
          example: lcas
          description: Unique identifier of a scope
        state:
          type: string
          example: released
          description: State of the meta data
        version:
          type: integer
          example: 3276800
          description: Version as uint64
        origin:
          type: string
          example: DOMAIN|b9cfb905-f80d-426b-b065-c9374ed183a9|0.50.0|
          description: The PartitionKey of the "real" meta in the domain
        etag:
          type: integer
          example: 12345678
          description: Entity tag for versioning
        descriptor:
          type: object
          description: the product descriptor
    scopeProducts:
      type: array
      description: Multiple products at once. Can"t be empty.
      minItems: 1
      items:
        $ref: "#/components/schemas/scopeProduct"
    scopeMeta:
      type: object
      description: Scope-Meta object containing all relevant information,
      properties:
        pk:
          type: string
          example: SCOPE|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Partition key (scope pk)
        sk:
          type: string
          example: DOMAIN|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Sort key (meta sk)
        ns:
          type: string
          example: SCOPE
          description: Namespace
        type:
          type: string
          example: meta
          description: Indicator that it's a meta item
        scope:
          type: string
          example: lcas
          description: Unique identifier of a scope
        state:
          type: string
          example: released
          description: State of the meta data
        version:
          type: integer
          example: 3276800
          description: Version as uint64
        origin:
          type: string
          example: DOMAIN|b9cfb905-f80d-426b-b065-c9374ed183a9|0.50.0|
          description: The PartitionKey of the "real" meta in the domain
        etag:
          type: integer
          example: 12345678
          description: Entity tag for versioning
        meta:
          type: object
          description: the actual meta data
    scopeMetas:
      type: array
      description: Multiple metas at once.
      items:
        $ref: "#/components/schemas/scopeMeta"
    scopeDomain:
      type: object
      description: Scope-Domain object containing all relevant information,
      properties:
        pk:
          type: string
          example: SCOPE|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Partition key (scope pk)
        sk:
          type: string
          example: DOMAIN|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Sort key (domain pk)
        ns:
          type: string
          example: SCOPE
          description: Namespace
        name:
          type: string
          example: plug and play
          description: The name of the scope
        scope:
          type: string
          example: lcas
          description: Unique identifier of a scope
        domain:
          type: string
          example: sa
          description: Unique identifier of a domain
        owner:
          type: string
          example: CUSTOMER|b9cfb905-f80d-426b-b065-c9374ed183a9|
          description: Customer PK that owns the domain
        accessor:
          type: string
          example: private
          description: Determines whether you have private or public domain access
        etag:
          type: integer
          example: 12345678
          description: Entity tag for versioning
    scopeDomains:
      type: array
      description: Multiple scope domains at once.
      items:
        $ref: "#/components/schemas/scopeDomain"
    scopeResponse:
      type: object
      description: Scope object containing all relevant information,
      properties:
        pk:
          type: string
          description: Partition key
        sk:
          type: string
          description: Sort key
        ns:
          type: string
          description: Namespace
        name:
          type: string
          description: The name of the scope
        scope:
          type: string
          description: Unique identifier of a scope
        mode:
          type: string
          description: Preferred update mode for scope
        autoupdate:
          type: boolean
          description: Whether auto-updates are enabled
        etag:
          type: integer
          description: Entity tag for versioning
    scopesResponse:
      type: array
      description: An array of scope objects
      items:
        $ref: "#/components/schemas/scopeResponse"
    scopeAll:
      type: object
      description: All products, domains and metas of a scope
      properties:
        products:
          $ref: "#/components/schemas/scopeProducts"
        domains:
          $ref: "#/components/schemas/scopeDomains"
        metas:
          $ref: "#/components/schemas/scopeMetas"
    meta:
      type: object
      description: Meta object containing all the requested information
      properties:
        pk:
          type: string
          example: inventory-latest
          description: The meta version in a human-readable way
        sk:
          $ref: "#/components/schemas/metaName"
        domain:
          $ref: "#/components/schemas/domain"
        version:
          type: integer
          example: 2752512
          description: The version encoded as an integer for easy processing
    product:
      type: object
      description: Product object containing all the requested information
      properties:
        pk:
          type: string
          example: inventory-latest
          description: The product version in a human-readable way
        sk:
          $ref: "#/components/schemas/productName"
        domain:
          $ref: "#/components/schemas/domain"
        descriptor:
          type: object
          description: The product"s descriptor and general information about the product
        modifiedTime:
          type: string
          example: 2024-01-31T10:48:06Z
          description: When the product got last updated
        version:
          type: integer
          example: 2752512
          description: The version encoded as an integer for easy processing
    metaArray:
      type: array
      description: Multiple metas at once.
      minItems: 0
      items:
        $ref: "#/components/schemas/meta"
    productArray:
      type: array
      description: Multiple products at once. Can"t be empty.
      minItems: 1
      items:
        $ref: "#/components/schemas/product"
    productDownload:
      type: object
      description: Product download object containing identifying data for the product and a temporary download link
      properties:
        pk:
          type: string
          example: inventory-latest
          description: The product version in a human-readable way
        sk:
          $ref: "#/components/schemas/productName"
        version:
          type: integer
          example: 2752512
          description: The version encoded as an integer for easy processing
        download-link:
          type: string
          example: Presigned S3 Download link
          description: The temporary access url for the zip file in the S3 bucket.
    metaName:
      type: string
      example: lcas:equipmentTypes
      description: The meta name
    productName:
      type: string
      example: CXE200
      description: The product name
    version:
      type: string
      description: Version of a product. Can also be "latest".
      example: 0.41.0
    state:
      type: string
      description: State of a product
      example: released
    public:
      type: boolean
      description: Visibility of a product. True means public.
      example: true
  parameters:
    customerIdParam:
      name: customerId
      in: path
      description: Unique identifier of a customer
      required: true
      schema:
        $ref: "#/components/schemas/customerId"
    targetCustomerIdParam:
      name: targetCustomerId
      in: path
      description: Unique identifier of a customer
      required: true
      schema:
        $ref: "#/components/schemas/customerId"
    userGroupIdParam:
      name: userGroupId
      in: path
      description: Unique identifier of a user group
      required: true
      schema:
        type: string
        example: 6cefc7ae-61a7-485b-ab0d-88ef436077b3
    invitationIdParam:
      name: invitationId
      in: path
      description: Unique identifier of an invitation
      required: true
      schema:
        type: string
        example: 94a373df-f719-553b-9418-6b814eabc683
    partitionIdParam:
      name: partitionId
      in: path
      description: |
        Unique identifier of a partition. This parameter represents either:
        - A **domain ID** for domain-related endpoints (e.g., /partitions/{partitionId}/products, /partitions/{partitionId}/domain/*)
        - A **scope ID** for scope-related endpoints (e.g., /partitions/{partitionId}/scope, /partitions/{partitionId}/scope/*)

        The specific meaning depends on the endpoint context - domain endpoints expect a domain UUID, while scope endpoints expect a scope UUID.
      required: true
      schema:
        $ref: "#/components/schemas/partitionId"
    scopeIdParam:
      name: scopeId
      in: path
      description: Unique identifier of a scope
      required: true
      schema:
        $ref: "#/components/schemas/scopeId"
    domainNameParam:
      name: domainName
      in: path
      description: Domain of a product
      required: true
      schema:
        $ref: "#/components/schemas/domain"
    domainUuidParam:
      name: domainUuid
      in: path
      description: Domain of a product
      required: true
      schema:
        $ref: "#/components/schemas/domainId"
    templateTypeParam:
      name: templateType
      in: path
      description: The template type, e.g. "MANIFEST" or "MODEL"
      required: true
      schema:
        type: string
    templateNameParam:
      name: templateName
      in: path
      description: Template name, unique inside a domain
      required: true
      schema:
        type: string
    templateIsActiveParam:
      name: isactive
      in: query
      description: Whether the template is active or not
      required: true
      schema:
        type: boolean
    versionParamPath:
      name: productVersion
      in: path
      description: Version filter for the products
      required: true
      schema:
        $ref: "#/components/schemas/version"
    versionParamOptional:
      name: version
      in: query
      description: Version filter for the products
      required: false
      schema:
        $ref: "#/components/schemas/version"
    stateParamOptional:
      name: state
      in: query
      description: State filter for the products
      required: false
      schema:
        $ref: "#/components/schemas/state"
    isPublicParamOptional:
      name: public
      in: query
      description: Visibility filter for the products
      required: false
      schema:
        $ref: "#/components/schemas/public"
    productNameParam:
      name: productName
      in: path
      description: Name of a product
      required: true
      schema:
        $ref: "#/components/schemas/productName"
  responses:
    badRequest:
      description: One or more of the required parameters are missing and/or invalid
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/error"
    forbidden:
      description: Forbidden, the user is not granted access to the requested resource
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/error"
    internalError:
      description: Internal Error
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/error"
    notFound:
      description: Requested resource not found, The server can"t find the requested resource
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/error"
    unauthorized:
      description: Unauthorized user, the JWT Bearer Token is either missing or invalid
      content:
        application/problem+json:
          schema:
            $ref: "#/components/schemas/error"
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JSON Web Token to be used
    lambdaAuthorizer:
      type: apiKey
      name: Authorization
      in: header
      x-amazon-apigateway-authtype: custom
      x-amazon-apigateway-authorizer:
        authorizerUri: "${lambdaauthorizer_lambda_function_uri}"
        authorizerCredentials: "${role_arn}"
        authorizerResultTtlInSeconds: 0
        type: request
        identitySource: method.request.header.Authorization, context.httpMethod, context.path

security:
  - bearerAuth: []

tags:
  - name: Customers
    description: Everything about Customers
  - name: Products
    description: Everything about Products
  - name: Domains
    description: Everything about Domains
  - name: Scopes
    description: Everything about Scopes
  - name: Meta
    description: Everything about Metadata
  - name: Partition sharing
    description: Share and unshare partitions with other customers
  - name: Template
    description: Everything about descriptor-templates for domains and scopes
  - name: Info
    description: Everything about this API
  - name: User Groups
    description: Everything about user groups
  - name: Invitations
    description: Everything about user invitations
  - name: CORS
    description: Config for API Gateway to allow CORS
