openapi: 3.0.3
info:
  title: Product API
  version: 1.0.0
  description: This API allows managing products, prices, taxes, and coupons.
  contact:
    name: Support
    email: info@epilot.cloud
    url: https://help.epilot.cloud
tags:
- name: Product
  description: Product operations
- name: Price
  description: Price operations
- name: Tax
  description: Tax operations
- name: Coupon
  description: Coupon operations
- name: product_schema
  x-displayName: Product
  description: |
    <SchemaDefinition schemaRef="#/components/schemas/Product" />
- name: price_schema
  x-displayName: Price
  description: |
    <SchemaDefinition schemaRef="#/components/schemas/Price" />
- name: tax_schema
  x-displayName: Tax
  description: |
    <SchemaDefinition schemaRef="#/components/schemas/Tax" />
- name: coupon_schema
  x-displayName: Coupon
  description: |
    <SchemaDefinition schemaRef="#/components/schemas/Coupon" />
x-tagGroups:
- name: APIs
  tags:
  - Product
  - Price
  - Tax
  - Coupon
- name: Schemas
  tags:
  - product_schema
  - price_schema
  - tax_schema
  - coupon_schema
security:
- EpilotAuth: []
- EpilotOrg: []
servers:
- url: https://product.sls.epilot.io
- url: https://product.sls.epilot.io
  description: Production server
paths:
  /v1/coupon:
    post:
      operationId: createCoupon
      summary: createCoupon
      description: Create a new coupon entity
      tags:
      - Coupon
      requestBody:
        $ref: '#/components/requestBodies/CouponCreateRequest'
      responses:
        '201':
          $ref: '#/components/responses/CouponResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/coupon/{couponId}:
    get:
      operationId: getCoupon
      summary: getCoupon
      description: Read a specific coupon entity by a given id
      tags:
      - Coupon
      parameters:
      - $ref: '#/components/parameters/CouponIdPathParam'
      - $ref: '#/components/parameters/HydrateQueryParam'
      - $ref: '#/components/parameters/StrictQueryParam'
      responses:
        '200':
          $ref: '#/components/responses/CouponResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    delete:
      operationId: deleteCoupon
      summary: deleteCoupon
      description: Delete a specific coupon entity by a given id
      tags:
      - Coupon
      parameters:
      - $ref: '#/components/parameters/CouponIdPathParam'
      responses:
        '200':
          $ref: '#/components/responses/CouponResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    patch:
      operationId: patchCoupon
      summary: patchCoupon
      description: Partially update a specific coupon entity's properties by a given id and a given payload
      tags:
      - Coupon
      parameters:
      - $ref: '#/components/parameters/CouponIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/CouponPatchRequest'
      responses:
        '200':
          $ref: '#/components/responses/CouponResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    put:
      operationId: updateCoupon
      summary: updateCoupon
      description: Completly replace a specific coupon entity's properties by a given id and a given payload
      tags:
      - Coupon
      parameters:
      - $ref: '#/components/parameters/CouponIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/CouponUpdateRequest'
      responses:
        '200':
          $ref: '#/components/responses/CouponResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/tax:
    post:
      operationId: createTax
      summary: createTax
      description: Create a new tax entity
      tags:
      - Tax
      requestBody:
        $ref: '#/components/requestBodies/TaxCreateRequest'
      responses:
        '201':
          $ref: '#/components/responses/TaxResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/tax/{taxId}:
    get:
      operationId: getTax
      summary: getTax
      description: Read a specific tax entity by a given id
      tags:
      - Tax
      parameters:
      - $ref: '#/components/parameters/TaxIdPathParam'
      - $ref: '#/components/parameters/HydrateQueryParam'
      - $ref: '#/components/parameters/StrictQueryParam'
      responses:
        '200':
          $ref: '#/components/responses/TaxResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    delete:
      operationId: deleteTax
      summary: deleteTax
      description: Delete a specific tax entity by a given id
      tags:
      - Tax
      parameters:
      - $ref: '#/components/parameters/TaxIdPathParam'
      responses:
        '200':
          $ref: '#/components/responses/TaxResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    patch:
      operationId: patchTax
      summary: patchTax
      description: Partially update a specific tax entity's properties by a given id and a given payload
      tags:
      - Tax
      parameters:
      - $ref: '#/components/parameters/TaxIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/TaxPatchRequest'
      responses:
        '200':
          $ref: '#/components/responses/TaxResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    put:
      operationId: updateTax
      summary: updateTax
      description: Completly replace a specific tax entity's properties by a given id and a given payload
      tags:
      - Tax
      parameters:
      - $ref: '#/components/parameters/TaxIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/TaxUpdateRequest'
      responses:
        '200':
          $ref: '#/components/responses/TaxResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/price:
    post:
      operationId: createPrice
      summary: createPrice
      description: Create a new price entity
      tags:
      - Price
      requestBody:
        $ref: '#/components/requestBodies/PriceCreateRequest'
      responses:
        '201':
          $ref: '#/components/responses/PriceResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/price/{priceId}:
    get:
      operationId: getPrice
      summary: getPrice
      description: Read a specific price entity by a given id
      tags:
      - Price
      parameters:
      - $ref: '#/components/parameters/PriceIdPathParam'
      - $ref: '#/components/parameters/HydrateQueryParam'
      - $ref: '#/components/parameters/StrictQueryParam'
      responses:
        '200':
          $ref: '#/components/responses/PriceResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    delete:
      operationId: deletePrice
      summary: deletePrice
      description: Delete a specific price entity by a given id
      tags:
      - Price
      parameters:
      - $ref: '#/components/parameters/PriceIdPathParam'
      responses:
        '200':
          $ref: '#/components/responses/PriceResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    patch:
      operationId: patchPrice
      summary: patchPrice
      description: Partially update a specific price entity's properties by a given id and a given payload
      tags:
      - Price
      parameters:
      - $ref: '#/components/parameters/PriceIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/PricePatchRequest'
      responses:
        '200':
          $ref: '#/components/responses/PriceResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    put:
      operationId: updatePrice
      summary: updatePrice
      description: Completly replace a specific price entity's properties by a given id and given payload
      tags:
      - Price
      parameters:
      - $ref: '#/components/parameters/PriceIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/PriceUpdateRequest'
      responses:
        '200':
          $ref: '#/components/responses/PriceResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/product:
    post:
      operationId: createProduct
      summary: createProduct
      description: Create a new product entity
      tags:
      - Product
      requestBody:
        $ref: '#/components/requestBodies/ProductCreateRequest'
      responses:
        '201':
          $ref: '#/components/responses/ProductResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/product/{productId}:
    get:
      operationId: getProduct
      summary: getProduct
      description: Read a specific product entity by a given id
      tags:
      - Product
      parameters:
      - $ref: '#/components/parameters/ProductIdPathParam'
      - $ref: '#/components/parameters/HydrateQueryParam'
      - $ref: '#/components/parameters/StrictQueryParam'
      responses:
        '200':
          $ref: '#/components/responses/ProductResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    delete:
      operationId: deleteProduct
      summary: deleteProduct
      description: Delete a specific product entity by a given id
      tags:
      - Product
      parameters:
      - $ref: '#/components/parameters/ProductIdPathParam'
      responses:
        '200':
          $ref: '#/components/responses/ProductResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    patch:
      operationId: patchProduct
      summary: patchProduct
      description: Partially update a specific product entity's properties by a given id and a given payload
      tags:
      - Product
      parameters:
      - $ref: '#/components/parameters/ProductIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/ProductPatchRequest'
      responses:
        '200':
          $ref: '#/components/responses/ProductResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    put:
      operationId: updateProduct
      summary: updateProduct
      description: Completly replace a specific product entity's properties by a given id and given payload
      tags:
      - Product
      parameters:
      - $ref: '#/components/parameters/ProductIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/ProductUpdateRequest'
      responses:
        '200':
          $ref: '#/components/responses/ProductResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/product-recommendation:
    post:
      operationId: createProductRecommendation
      summary: createProductRecommendation
      description: Create a new product recommendation entity
      tags:
      - Product Recommendation
      requestBody:
        $ref: '#/components/requestBodies/ProductRecommendationCreateRequest'
      responses:
        '201':
          $ref: '#/components/responses/ProductRecommendationResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
  /v1/product-recommendation/{productRecommendationId}:
    get:
      operationId: getProductRecommendation
      summary: getProductRecommendation
      description: Read a specific product recommendation entity by a given id
      tags:
      - Product Recommendation
      parameters:
      - $ref: '#/components/parameters/ProductRecommendationIdPathParam'
      - $ref: '#/components/parameters/HydrateQueryParam'
      - $ref: '#/components/parameters/StrictQueryParam'
      responses:
        '200':
          $ref: '#/components/responses/ProductRecommendationResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    patch:
      operationId: patchProductRecommendation
      summary: patchProductRecommendation
      description: Partially update a specific product recommendation entity's properties by a given id and a given payload
      tags:
      - Product Recommendation
      parameters:
      - $ref: '#/components/parameters/ProductRecommendationIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/ProductRecommendationPatchRequest'
      responses:
        '200':
          $ref: '#/components/responses/ProductRecommendationResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    put:
      operationId: updateProductRecommendation
      summary: updateProductRecommendation
      description: Completly replace a specific product recommendation entity's properties by a given id and given payload
      tags:
      - Product Recommendation
      parameters:
      - $ref: '#/components/parameters/ProductRecommendationIdPathParam'
      requestBody:
        $ref: '#/components/requestBodies/ProductRecommendationUpdateRequest'
      responses:
        '200':
          $ref: '#/components/responses/ProductRecommendationResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
    delete:
      operationId: deleteProductRecommendation
      summary: deleteProductRecommendation
      description: Delete a specific product recommendation entity by a given id
      tags:
      - Product Recommendation
      parameters:
      - $ref: '#/components/parameters/ProductRecommendationIdPathParam'
      responses:
        '200':
          $ref: '#/components/responses/ProductRecommendationResponse'
        '400':
          $ref: '#/components/responses/ClientErrorResponse'
        '500':
          $ref: '#/components/responses/ServerErrorResponse'
components:
  securitySchemes:
    EpilotAuth:
      type: http
      scheme: bearer
      description: Authorization header with epilot OAuth2 bearer token
      bearerFormat: JWT
    EpilotOrg:
      description: Overrides the target organization to allow shared tenantaccess
      name: x-epilot-org-id
      in: header
      type: apiKey
  schemas:
    BaseError:
      type: object
      properties:
        status:
          type: integer
          example: 404
        message:
          type: string
          example: Entity not found
      required:
      - status
      - message
    ServerError:
      $ref: '#/components/schemas/BaseError'
    ClientError:
      $ref: '#/components/schemas/BaseError'
    BaseUUID:
      type: string
      format: uuid
      example: 123e4567-e89b-12d3-a456-426614174000
    BaseTags:
      type: array
      nullable: true
      items:
        type: string
    BasePurpose:
      type: array
      nullable: true
      items:
        type: string
    BaseRelation:
      type: object
      properties:
        $relation:
          type: array
          items:
            type: object
            properties:
              entity_id:
                $ref: '#/components/schemas/BaseUUID'
              _tags:
                $ref: '#/components/schemas/BaseTags'
      required:
      - $relation
    BaseEntityOwner:
      description: |
        The user / organization owning this entity.

        Note: Owner implicitly has access to the entity regardless of ACLs.
      type: object
      properties:
        org_id:
          type: string
          example: '123'
        user_id:
          type: string
          example: '123'
      required:
      - org_id
    BaseEntityAcl:
      type: object
      description: Access control list (ACL) for an entity. Defines sharing access to external orgs or users.
      properties:
        view:
          type: array
          items:
            type: string
            example: org:456
        edit:
          type: array
          items:
            type: string
            example: org:456
        delete:
          type: array
          items:
            type: string
            example: org:456
    BaseSystemFields:
      type: object
      properties:
        _tags:
          $ref: '#/components/schemas/BaseTags'
        _purpose:
          $ref: '#/components/schemas/BasePurpose'
        _files:
          $ref: '#/components/schemas/BaseRelation'
        _manifest:
          type: array
          description: Manifest ID used to create/update the entity
          items:
            type: string
            format: uuid
            example: 123e4567-e89b-12d3-a456-426614174000
        __additional:
          type: object
          description: Additional fields that are not part of the schema
          additionalProperties: true
          nullable: true
          example: {}
    BaseSystemReadonlyFields:
      type: object
      properties:
        _id:
          $ref: '#/components/schemas/BaseUUID'
        _schema:
          readOnly: true
          type: string
        _org:
          type: string
          description: Organization Id the entity belongs to
          readOnly: true
        _tags:
          $ref: '#/components/schemas/BaseTags'
        _files:
          $ref: '#/components/schemas/BaseRelation'
        _owners:
          type: array
          readOnly: true
          items:
            $ref: '#/components/schemas/BaseEntityOwner'
        _title:
          readOnly: true
          type: string
        _created_at:
          readOnly: true
          type: string
          format: date-time
        _updated_at:
          readOnly: true
          type: string
          format: date-time
        _acl:
          $ref: '#/components/schemas/BaseEntityAcl'
    BaseSystemFieldsRequired:
      type: object
      required:
      - _schema
      - _org
    BaseTax:
      type: object
      properties:
        _schema:
          type: string
          enum:
          - tax
        active:
          type: boolean
        description:
          type: string
        region:
          type: string
          example: DE
        rate:
          oneOf:
          - type: string
          - type: number
        type:
          type: string
          enum:
          - VAT
          - Custom
    BaseTaxRequired:
      type: object
      required:
      - active
      - region
      - rate
      - type
    Tax:
      allOf:
      - $ref: '#/components/schemas/BaseSystemReadonlyFields'
      - $ref: '#/components/schemas/BaseTax'
      - $ref: '#/components/schemas/BaseTaxRequired'
      - $ref: '#/components/schemas/BaseSystemFieldsRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
    TaxCreate:
      allOf:
      - $ref: '#/components/schemas/BaseTax'
      - $ref: '#/components/schemas/BaseTaxRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
    BaseCoupon:
      type: object
      properties:
        _schema:
          type: string
          enum:
          - coupon
        name:
          type: string
        description:
          type: string
        type:
          type: string
          enum:
          - fixed
          - percentage
        category:
          type: string
          enum:
          - discount
          - cashback
        percentage_value:
          type: string
          description: Use if type is set to percentage. The percentage to be discounted, represented as a whole integer.
        fixed_value:
          description: Use if type is set to fixed. The fixed amount in cents to be discounted, represented as a whole integer.
          type: number
        fixed_value_decimal:
          description: Use if type is set to fixed. The unit amount in cents to be discounted, represented as a decimal string with at most 12 decimal places.
          type: string
        fixed_value_currency:
          description: Use if type is set to fixed. Three-letter ISO currency code, in lowercase.
          oneOf:
          - $ref: '#/components/schemas/Currency'
        cashback_period:
          type: string
          description: The cashback period, for now it's limited to either 0 months or 12 months
          enum:
          - '0'
          - '12'
        active:
          type: boolean
        requires_promo_code:
          type: boolean
          description: Whether the coupon requires a promo code to be applied
        prices:
          $ref: '#/components/schemas/BaseRelation'
        promo_codes:
          type: array
          items:
            $ref: '#/components/schemas/PromoCode'
        promo_code_usage:
          type: object
          additionalProperties:
            type: number
          description: Map of ids of promo codes with their usage count
    BaseCouponRequired:
      type: object
      required:
      - name
      - type
      - category
      - active
    Coupon:
      allOf:
      - $ref: '#/components/schemas/BaseSystemReadonlyFields'
      - $ref: '#/components/schemas/BaseCoupon'
      - $ref: '#/components/schemas/BaseCouponRequired'
      - $ref: '#/components/schemas/BaseSystemFieldsRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
    CouponCreate:
      allOf:
      - $ref: '#/components/schemas/BaseCoupon'
      - $ref: '#/components/schemas/BaseCouponRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
    TaxPatch:
      allOf:
      - $ref: '#/components/schemas/BaseTax'
      - $ref: '#/components/schemas/BaseSystemFields'
    CouponPatch:
      allOf:
      - $ref: '#/components/schemas/BaseCoupon'
      - $ref: '#/components/schemas/BaseSystemFields'
    BasePrice:
      type: object
      properties:
        _schema:
          type: string
          enum:
          - price
        active:
          type: boolean
          description: Whether the price can be used for new purchases.
        description:
          type: string
          description: A brief description of the price.
        long_description:
          type: string
          description: A detailed description of the price. This is shown on the order document and order table. Multi-line supported.
        type:
          type: string
          description: One of `one_time` or `recurring` depending on whether the price is for a one-time purchase or a recurring (subscription) purchase.
          enum:
          - one_time
          - recurring
          default: one_time
        pricing_model:
          type: string
          description: |
            Describes how to compute the price per period. Either `per_unit`, `tiered_graduated` or `tiered_volume`.
            - `per_unit` indicates that the fixed amount (specified in unit_amount or unit_amount_decimal) will be charged per unit in quantity
            - `tiered_graduated` indicates that the unit pricing will be computed using tiers attribute. The customer pays the price per unit in every range their purchase rises through.
            - `tiered_volume` indicates that the unit pricing will be computed using tiers attribute. The customer pays the same unit price for all purchased units.
            - `tiered_flatfee` While similar to tiered_volume, tiered flat fee charges for the same price (flat) for the entire range instead using the unit price to multiply the quantity.
          enum:
          - per_unit
          - tiered_volume
          - tiered_graduated
          - tiered_flatfee
          default: per_unit
        price_components:
          description: A set of [price](/api/pricing#tag/simple_price_schema) components that define the composite price.
          type: object
          properties:
            $relation:
              type: array
              items:
                $ref: '#/components/schemas/PriceComponentRelation'
          required:
          - $relation
        unit_amount:
          description: The unit amount in cents to be charged, represented as a whole integer if possible.
          type: number
        unit_amount_decimal:
          description: The unit amount in cents to be charged, represented as a decimal string with at most 12 decimal places.
          type: string
        unit_amount_currency:
          description: Three-letter ISO currency code, in lowercase.
          oneOf:
          - $ref: '#/components/schemas/Currency'
        is_composite_price:
          description: The flag for prices that contain price components.
          type: boolean
        tiers:
          description: |
            Defines an array of tiers. Each tier has an upper bound, an unit amount and a flat fee.
          type: array
          items:
            $ref: '#/components/schemas/PriceTier'
        is_tax_inclusive:
          type: boolean
          default: false
          description: Specifies whether the price is considered `inclusive` of taxes or not.
        price_display_in_journeys:
          description: Defines the way the price amount is display in epilot journeys.
          type: string
          enum:
          - show_price
          - show_as_starting_price
          - show_as_on_request
        billing_duration_amount:
          description: The billing period duration
          type: number
        billing_duration_unit:
          description: The billing period duration unit
          type: string
          nullable: true
          enum:
          - weeks
          - months
          - years
          - null
        notice_time_amount:
          description: The notice period duration
          type: number
        notice_time_unit:
          description: The notice period duration unit
          type: string
          nullable: true
          enum:
          - weeks
          - months
          - years
          - null
        termination_time_amount:
          description: The termination period duration
          type: number
        termination_time_unit:
          description: The termination period duration unit
          type: string
          nullable: true
          enum:
          - weeks
          - months
          - years
          - null
        renewal_duration_amount:
          description: The renewal period duration
          type: number
        renewal_duration_unit:
          description: The renewal period duration unit
          type: string
          nullable: true
          enum:
          - weeks
          - months
          - years
          - null
        variable_price:
          description: The flag for prices that can be influenced by external variables such as user input.
          type: boolean
          default: false
        unit:
          description: The unit of measurement used for display purposes and possibly for calculations when the price is variable.
          type: string
        tax:
          $ref: '#/components/schemas/BaseRelation'
    PriceTier:
      type: object
      properties:
        up_to:
          type: number
          nullable: true
        flat_fee_amount:
          type: number
        flat_fee_amount_decimal:
          type: string
        unit_amount:
          type: number
        unit_amount_decimal:
          type: string
        display_mode:
          $ref: '#/components/schemas/PriceTierDisplayMode'
    PriceTierDisplayMode:
      type: string
      enum:
      - hidden
      - on_request
    Currency:
      type: string
      description: |
        Three-letter ISO currency code, in lowercase. Must be a supported currency.
        ISO 4217 CURRENCY CODES as specified in the documentation: https://www.iso.org/iso-4217-currency-codes.html
      example: EUR
    BasePriceRequired:
      type: object
      required:
      - active
      - type
    PromoCode:
      type: object
      required:
      - id
      - code
      properties:
        id:
          type: string
          description: The id of the promo code
        code:
          type: string
          description: The code of the promo code
        has_usage_limit:
          type: boolean
          description: Whether the promo code has a usage limit
        usage_limit:
          type: number
          nullable: true
          description: The usage limit of the promo code
    Price:
      allOf:
      - $ref: '#/components/schemas/BaseSystemReadonlyFields'
      - $ref: '#/components/schemas/BasePrice'
      - $ref: '#/components/schemas/BasePriceRequired'
      - $ref: '#/components/schemas/BaseSystemFieldsRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
    PriceCreate:
      allOf:
      - $ref: '#/components/schemas/BasePrice'
      - $ref: '#/components/schemas/BasePriceRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
    PricePatch:
      allOf:
      - $ref: '#/components/schemas/BasePrice'
      - $ref: '#/components/schemas/BaseSystemFields'
    BaseProduct:
      type: object
      properties:
        _schema:
          type: string
          enum:
          - product
        active:
          type: boolean
        price_options:
          $ref: '#/components/schemas/BaseRelation'
        product_images:
          $ref: '#/components/schemas/BaseRelation'
        product_downloads:
          $ref: '#/components/schemas/BaseRelation'
        _availability_files:
          $ref: '#/components/schemas/BaseRelation'
        name:
          type: string
          description: The description for the product
        categories:
          type: array
          items:
            type: string
          description: The categories of the product
        internal_name:
          type: string
          description: Not visible to customers, only in internal tables
        code:
          type: string
          description: The product code
        type:
          type: string
          description: |
            The type of Product:

            | type | description |
            |----| ----|
            | `product` | Represents a physical good |
            | `service` | Represents a service or virtual product |
          enum:
          - product
          - service
          default: product
        description:
          type: string
          description: A description of the product. Multi-line supported.
        feature:
          type: array
          items: {}
    BaseProductRequired:
      type: object
      required:
      - name
      - type
      - active
    Product:
      allOf:
      - $ref: '#/components/schemas/BaseSystemReadonlyFields'
      - $ref: '#/components/schemas/BaseProduct'
      - $ref: '#/components/schemas/BaseProductRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
      - $ref: '#/components/schemas/BaseSystemFieldsRequired'
    ProductCreate:
      allOf:
      - $ref: '#/components/schemas/BaseProduct'
      - $ref: '#/components/schemas/BaseSystemFields'
      - $ref: '#/components/schemas/BaseProductRequired'
    ProductPatch:
      allOf:
      - $ref: '#/components/schemas/BaseProduct'
      - $ref: '#/components/schemas/BaseSystemFields'
    PriceComponentRelation:
      type: object
      properties:
        entity_id:
          description: The id of the price component
          type: string
        _tags:
          type: array
          description: An arbitrary set of tags attached to the composite price - component relation
          items:
            type: string
    ProductRecommendation:
      allOf:
      - $ref: '#/components/schemas/BaseSystemReadonlyFields'
      - $ref: '#/components/schemas/BaseProductRecommendation'
      - $ref: '#/components/schemas/BaseProductRecommendationRequired'
      - $ref: '#/components/schemas/BaseSystemFields'
      - $ref: '#/components/schemas/BaseSystemFieldsRequired'
    ProductRecommendationCreate:
      allOf:
      - $ref: '#/components/schemas/BaseProductRecommendation'
      - $ref: '#/components/schemas/BaseSystemFields'
      - $ref: '#/components/schemas/BaseProductRecommendationRequired'
    ProductRecommendationPatch:
      allOf:
      - $ref: '#/components/schemas/BaseProductRecommendation'
      - $ref: '#/components/schemas/BaseSystemFields'
    BaseProductRecommendation:
      type: object
      properties:
        _schema:
          type: string
          enum:
          - product_recommendation
        source_price:
          type: object
          description: Price being used as source
          properties:
            $relation:
              type: array
              items:
                $ref: '#/components/schemas/BaseRelation'
        source_product:
          type: object
          description: Product being used as source
          properties:
            $relation:
              type: array
              items:
                $ref: '#/components/schemas/BaseRelation'
        type:
          type: string
          description: Type of product recommendation
          enum:
          - change
          - cross-sell
          - up-sell
        offers:
          type: array
          items:
            $ref: '#/components/schemas/Offer'
    BaseProductRecommendationRequired:
      type: object
      required:
      - type
    ProductRecommendationSearch:
      description: Product recommendations request payload
      type: object
      properties:
        product_recommendation_ids:
          type: array
          items:
            type: string
            description: Product recommendation id
        catalog_item:
          type: object
          description: The catalog item to be used as source for the recommendation
          properties:
            product_id:
              type: string
              description: Product id
            price_id:
              type: string
              description: Product id
        contract_id:
          type: string
          description: The contract id to be used as source for the recommendation
    Offer:
      type: object
      properties:
        product_id:
          type: string
        price_id:
          type: string
        target_id:
          type: string
  parameters:
    HydrateQueryParam:
      name: hydrate
      in: query
      required: false
      description: Hydrates entities in relations when passed true
      schema:
        type: boolean
        default: false
    StrictQueryParam:
      name: strict
      in: query
      required: false
      description: When passed true, the response will contain only fields that match the schema, with non-matching fields included in `__additional`
      schema:
        type: boolean
        default: false
    TaxIdPathParam:
      name: taxId
      description: The tax id
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/BaseUUID'
    CouponIdPathParam:
      name: couponId
      description: The coupon id
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/BaseUUID'
    PriceIdPathParam:
      name: priceId
      description: The price id
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/BaseUUID'
    ProductIdPathParam:
      name: productId
      description: The product id
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/BaseUUID'
    ProductRecommendationIdPathParam:
      name: productRecommendationId
      description: The product recommendation id
      in: path
      required: true
      schema:
        $ref: '#/components/schemas/BaseUUID'
  requestBodies:
    CouponCreateRequest:
      description: Coupon to create
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CouponCreate'
    TaxCreateRequest:
      description: Tax to create
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TaxCreate'
    TaxPatchRequest:
      description: Tax to patch
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TaxPatch'
    CouponPatchRequest:
      description: Coupon to patch
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CouponPatch'
    TaxUpdateRequest:
      description: Tax to update
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/TaxCreate'
    CouponUpdateRequest:
      description: Coupon to update
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/CouponCreate'
    PriceCreateRequest:
      description: Price to create
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PriceCreate'
    PricePatchRequest:
      description: Price to patch
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PricePatch'
    PriceUpdateRequest:
      description: Price to update
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/PriceCreate'
    ProductCreateRequest:
      description: Product to create
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductCreate'
    ProductPatchRequest:
      description: Product to patch
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductPatch'
    ProductUpdateRequest:
      description: Product to update
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductCreate'
    ProductRecommendationCreateRequest:
      description: Product recommendation to create
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductRecommendationCreate'
    ProductRecommendationPatchRequest:
      description: Product recommendation to patch
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductRecommendationPatch'
    ProductRecommendationUpdateRequest:
      description: Product recommendation to update
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductRecommendationCreate'
    ProductRecommendationSearchRequest:
      description: Product recommendation search request
      required: true
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductRecommendationSearch'
  responses:
    ClientErrorResponse:
      description: Any error based on client data errors
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ClientError'
    ServerErrorResponse:
      description: Any error based on the server-side
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ServerError'
    TaxResponse:
      description: Tax entity response
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Tax'
    CouponResponse:
      description: Coupon entity response
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Coupon'
    PriceResponse:
      description: Price entity with id
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Price'
    ProductResponse:
      description: Product entity response
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Product'
    ProductRecommendationResponse:
      description: Product recommendations request payload
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ProductRecommendation'

