openapi: 3.0.0
info:
  title: Kwikk Public API
  version: 1.0.1 # Version updated
  description: |
    Read-only and management endpoints for Kwikk resources. 
    For POST/PUT: API key must be sent as `key` in the JSON body or form data.
    For GET/DELETE: API key can be sent as `X-Api-Key` header or `key` query parameter.
servers:
  - url: https://api.kwikk.se/public

paths:
  /button:
    get:
      summary: List Buttons
      tags: [Button]
      description: Retrieves a list of buttons, with optional filtering.
      operationId: listButtons
      parameters:
        - name: button_id
          in: query
          description: Filter by button ID.
          schema:
            type: integer
        - name: button_artno
          in: query
          description: Filter by partial match on button article number.
          schema:
            type: string
        - name: button_title
          in: query
          description: Filter by partial match on button title.
          schema:
            type: string
        - name: button_description
          in: query
          description: Filter by match on button description.
          schema:
            type: string
        - name: button_price_from
          in: query
          description: Filter by minimum price.
          schema:
            type: number
            format: double
        - name: button_price_to
          in: query
          description: Filter by maximum price.
          schema:
            type: number
            format: double
        - name: button_vat_from
          in: query
          description: Filter by minimum VAT.
          schema:
            type: number
            format: double
        - name: button_vat_to
          in: query
          description: Filter by maximum VAT.
          schema:
            type: number
            format: double
        - name: button_inactive
          in: query
          description: Filter by inactive status (0 for active, 1 for inactive).
          schema:
            type: integer
            enum: [0, 1]
        - name: tag_id
          in: query
          description: Filter buttons by a specific tag ID.
          schema:
            type: integer
        - name: tag_name
          in: query
          description: Filter buttons by a specific tag name (exact match).
          schema:
            type: string
        - $ref: '#/components/parameters/ResultsLimit'
        - $ref: '#/components/parameters/ResultsOffset'
        - $ref: '#/components/parameters/ResultsSortButton'
      responses:
        '200':
          description: An array of buttons.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Button'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError' # If filters yield no results
    put:
      summary: Create Button
      tags: [Button]
      description: Creates a new button.
      operationId: createButton
      requestBody:
        description: Button object to create.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ButtonInput'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ButtonInputForm'
      responses:
        '201':
          description: Button created successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResultWithId'
        '400':
          $ref: '#/components/responses/InvalidInputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /button/{buttonId}:
    get:
      summary: Get Button by ID
      tags: [Button]
      description: Retrieves a specific button by its ID.
      operationId: getButtonById
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
      responses:
        '200':
          description: A single button.
          content:
            application/json:
              schema:
                type: array # API currently returns a single item array
                items:
                  $ref: '#/components/schemas/Button'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
    put:
      summary: Update Button by ID
      tags: [Button]
      description: Updates an existing button.
      operationId: updateButtonById
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
      requestBody:
        description: Button object with fields to update.
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ButtonInput'
          application/x-www-form-urlencoded:
            schema:
              $ref: '#/components/schemas/ButtonInputForm'
      responses:
        '200':
          description: Button updated successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResultWithId'
        '400':
          $ref: '#/components/responses/InvalidInputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
    delete:
      summary: Delete Button by ID
      tags: [Button]
      description: Deletes/archives a specific button.
      operationId: deleteButtonById
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
        - $ref: '#/components/parameters/ApiKeyQueryOrHeader' # Key for DELETE
      responses:
        '200':
          description: Button deleted/archived successfully.
          content:
            application/json:
              schema: # Define success message structure
                type: object
                properties:
                  status:
                    type: string
                    example: "success"
                  message:
                    type: string
                    example: "Button archived." # Or "Button deleted."
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '501':
          $ref: '#/components/responses/NotImplementedError'


  /button/artno/{artno}:
    get:
      summary: Get Button by Article Number
      tags: [Button]
      description: Retrieves a specific button by its exact article number.
      operationId: getButtonByArtno
      parameters:
        - name: artno
          in: path
          required: true
          description: Article number of the button.
          schema:
            type: string
      responses:
        '200':
          description: A single button.
          content:
            application/json:
              schema:
                type: array # API currently returns a single item array
                items:
                  $ref: '#/components/schemas/Button'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /button/count:
    get:
      summary: Get Total Button Count
      tags: [Button]
      description: Retrieves the total number of buttons for the user.
      operationId: getButtonsCount
      responses:
        '200':
          description: Total button count.
          content:
            application/json:
              schema:
                type: object
                properties:
                  count:
                    type: integer
                    example: 150
        '401':
          $ref: '#/components/responses/UnauthorizedError'

  /button/{buttonId}/sold_count:
    get:
      summary: Get Button Sold Count
      tags: [Button]
      description: Retrieves the sold count for a specific button (identified by ID or article number passed as buttonId).
      operationId: getButtonSoldCount
      parameters:
        - name: buttonId # Can be numeric ID or artno string
          in: path
          required: true
          description: ID or Article Number of the button.
          schema:
            oneOf:
              - type: integer
              - type: string
      responses:
        '200':
          description: Sold count for the button.
          content:
            application/json:
              schema:
                type: object
                properties:
                  button_identifier:
                    oneOf:
                      - type: integer
                      - type: string
                    example: 123
                  sold_count:
                    type: integer
                    example: 75
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /button/{buttonId}/tags:
    get:
      summary: Get Tags for a Button
      tags: [Button, Tag]
      operationId: getTagsForButton
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
      responses:
        '200':
          description: An array of tags associated with the button.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Tag'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
    post:
      summary: Add Tag to Button
      tags: [Button, Tag]
      operationId: addTagToButton
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
                - tag_id
              properties:
                key:
                  type: string
                  description: API Key.
                tag_id:
                  type: integer
                  description: ID of the tag to add.
      responses:
        '200':
          description: Tag added successfully.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag' # Returns the added tag or updated list
        '400':
          $ref: '#/components/responses/InvalidInputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError' # Button or Tag not found
        '501':
          $ref: '#/components/responses/NotImplementedError'

  /button/{buttonId}/tags/{tagId}:
    delete:
      summary: Remove Tag from Button
      tags: [Button, Tag]
      operationId: removeTagFromButton
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
        - $ref: '#/components/parameters/TagIdPath'
        - $ref: '#/components/parameters/ApiKeyQueryOrHeader'
      responses:
        '204':
          description: Tag removed successfully.
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError' # Button or Tag not found
        '501':
          $ref: '#/components/responses/NotImplementedError'

  /button/{buttonId}/dlcs:
    get:
      summary: Get DLCs for a Button
      tags: [Button, DLC]
      operationId: getDLCsForButton
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
      responses:
        '200':
          description: An array of DLC IDs associated with the button.
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string # Assuming DLC IDs are strings, adjust if objects
                  example: ["dlc_id_1", "dlc_id_2"]
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
    post:
      summary: Add DLC to Button
      tags: [Button, DLC]
      operationId: addDLCToButton
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
                - dlc_id
              properties:
                key:
                  type: string
                dlc_id:
                  type: string # Assuming DLC ID is a string
                  description: ID of the DLC to add.
      responses:
        '200':
          description: DLC added successfully.
        '400':
          $ref: '#/components/responses/InvalidInputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '501':
          $ref: '#/components/responses/NotImplementedError'

  /button/{buttonId}/dlcs/{dlcId}:
    delete:
      summary: Remove DLC from Button
      tags: [Button, DLC]
      operationId: removeDLCFromButton
      parameters:
        - $ref: '#/components/parameters/ButtonIdPath'
        - $ref: '#/components/parameters/DlcIdPath'
        - $ref: '#/components/parameters/ApiKeyQueryOrHeader'
      responses:
        '204':
          description: DLC removed successfully.
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '501':
          $ref: '#/components/responses/NotImplementedError'

  /order:
    get:
      summary: List Orders
      tags: [Order]
      parameters:
        $ref: '#/components/parameters/OrderFilters'
      responses:
        '200':
          description: Array of Order
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Order'
  /order/{order_id}:
    get:
      summary: Get Order by ID
      tags: [Order]
      parameters:
        - $ref: '#/components/parameters/order_id'
      responses:
        '200':
          description: Single Order in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Order'

  /download:
    get:
      summary: List Downloads
      tags: [Download]
      parameters:
        $ref: '#/components/parameters/DownloadFilters'
      responses:
        '200':
          description: Array of Download
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Download'
  /download/{download_id}:
    get:
      summary: Get Download by ID
      tags: [Download]
      parameters:
        - $ref: '#/components/parameters/download_id'
      responses:
        '200':
          description: Single Download in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Download'

  /register:
    get:
      summary: List Registers
      tags: [Register]
      parameters:
        $ref: '#/components/parameters/RegisterFilters'
      responses:
        '200':
          description: Array of Register
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Register'
    put:
      summary: Create or update Register
      tags: [Register]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterInput'
      responses:
        '200':
          description: Operation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResult'
  /register/{register_id}:
    get:
      summary: Get Register by ID
      tags: [Register]
      parameters:
        - $ref: '#/components/parameters/register_id'
      responses:
        '200':
          description: Single Register in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Register'
    put:
      summary: Update Register by ID
      tags: [Register]
      parameters:
        - $ref: '#/components/parameters/register_id'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/RegisterInput'
      responses:
        '200':
          description: Operation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResult'

  /repeat:
    get:
      summary: List Repeating Payments (Deprecated)
      tags: [RepeatingPayment_Deprecated]
      deprecated: true
      parameters:
        $ref: '#/components/parameters/RepeatFilters'
      responses:
        '200':
          description: Array of Repeat
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Repeat'
  /repeat/{repeating_id}:
    get:
      summary: Get Repeating Payment by ID (Deprecated)
      tags: [RepeatingPayment_Deprecated]
      deprecated: true
      parameters:
        - $ref: '#/components/parameters/repeating_id'
      responses:
        '200':
          description: Single Repeat in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Repeat'

  /subscription:
    get:
      summary: List Subscriptions
      tags: [Subscription]
      parameters:
        $ref: '#/components/parameters/SubscriptionFilters'
      responses:
        '200':
          description: Array of Subscription
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subscription'
  /subscription/{subscription_id}:
    get:
      summary: Get Subscription by ID
      tags: [Subscription]
      parameters:
        - $ref: '#/components/parameters/subscription_id'
      responses:
        '200':
          description: Single Subscription in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Subscription'

  /discount:
    get:
      summary: List Discounts
      tags: [Discount]
      parameters:
        $ref: '#/components/parameters/DiscountFilters'
      responses:
        '200':
          description: Array of Discount
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Discount'
  /discount/{discount_id}:
    get:
      summary: Get Discount by ID
      tags: [Discount]
      parameters:
        - $ref: '#/components/parameters/discount_id'
      responses:
        '200':
          description: Single Discount in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Discount'

  /discountCode:
    get:
      summary: List Discount Codes
      tags: [DiscountCode]
      parameters:
        $ref: '#/components/parameters/DiscountCodeFilters'
      responses:
        '200':
          description: Array of DiscountCode
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DiscountCode'
    put:
      summary: Create Discount Code
      tags: [DiscountCode]
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/DiscountCodeInput'
      responses:
        '200':
          description: Operation result
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/OperationResult'
  /discountCode/{discount_code_id}:
    get:
      summary: Get Discount Code by ID
      tags: [DiscountCode]
      parameters:
        - $ref: '#/components/parameters/discount_code_id'
      responses:
        '200':
          description: Single DiscountCode in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DiscountCode'
      
  /repeat_pauses: # Or /repeatPause
    get:
      summary: List Repeat Pauses
      tags: [RepeatPause]
      parameters:
        $ref: '#/components/parameters/RepeatPauseFilters'
      responses:
        '200':
          description: Array of RepeatPause
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RepeatPause'
  /repeat_pauses/{repeat_pause_id}: # Or /repeatPause/{id}
    get:
      summary: Get Repeat Pause by ID
      tags: [RepeatPause]
      parameters:
        - $ref: '#/components/parameters/repeat_pause_id'
      responses:
        '200':
          description: Single RepeatPause in array
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/RepeatPause'

  /tags:
    get:
      summary: List Tags
      tags: [Tag]
      operationId: listTags
      responses:
        '200':
          description: An array of tags.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/Tag'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
    post:
      summary: Create Tag
      tags: [Tag]
      operationId: createTag
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
                - name
              properties:
                key:
                  type: string
                name:
                  type: string
                  description: Name of the tag to create.
      responses:
        '201':
          description: Tag created.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '400':
          $ref: '#/components/responses/InvalidInputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '501':
          $ref: '#/components/responses/NotImplementedError'

  /tags/{tagId}:
    get:
      summary: Get Tag by ID
      tags: [Tag]
      operationId: getTagById
      parameters:
        - $ref: '#/components/parameters/TagIdPath'
      responses:
        '200':
          description: A single tag.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
    put:
      summary: Update Tag by ID
      tags: [Tag]
      operationId: updateTagById
      parameters:
        - $ref: '#/components/parameters/TagIdPath'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - key
                - name
              properties:
                key:
                  type: string
                name:
                  type: string
                  description: New name for the tag.
      responses:
        '200':
          description: Tag updated.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Tag'
        '400':
          $ref: '#/components/responses/InvalidInputError'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '501':
          $ref: '#/components/responses/NotImplementedError'
    delete:
      summary: Delete Tag by ID
      tags: [Tag]
      operationId: deleteTagById
      parameters:
        - $ref: '#/components/parameters/TagIdPath'
        - $ref: '#/components/parameters/ApiKeyQueryOrHeader'
      responses:
        '204':
          description: Tag deleted.
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'
        '501':
          $ref: '#/components/responses/NotImplementedError'

  /tax_classes:
    get:
      summary: List Tax Classes
      tags: [TaxClass]
      operationId: listTaxClasses
      responses:
        '200':
          description: An array of tax classes.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/TaxClass'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '501':
          $ref: '#/components/responses/NotImplementedError' # Marked as planned

  /tax_classes/{taxClassId}:
    get:
      summary: Get Tax Class by ID
      tags: [TaxClass]
      operationId: getTaxClassById
      parameters:
        - $ref: '#/components/parameters/TaxClassIdPath'
      responses:
        '200':
          description: A single tax class.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TaxClass'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /bookkeeping_classes:
    get:
      summary: List Bookkeeping Classes
      tags: [BookkeepingClass]
      operationId: listBookkeepingClasses
      responses:
        '200':
          description: An array of bookkeeping classes.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/BookkeepingClass'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '501':
          $ref: '#/components/responses/NotImplementedError' # Marked as planned

  /bookkeeping_classes/{bookkeepingClassId}:
    get:
      summary: Get Bookkeeping Class by ID
      tags: [BookkeepingClass]
      operationId: getBookkeepingClassById
      parameters:
        - $ref: '#/components/parameters/BookkeepingClassIdPath'
      responses:
        '200':
          description: A single bookkeeping class.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/BookkeepingClass'
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '404':
          $ref: '#/components/responses/NotFoundError'

  /dlcs:
    get:
      summary: List All Available DLCs
      tags: [DLC]
      description: Retrieves a list of all DLCs that can be associated with buttons.
      operationId: listAllDLCs
      responses:
        '200':
          description: An array of DLCs.
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/DLC' # A full DLC object if available
        '401':
          $ref: '#/components/responses/UnauthorizedError'
        '501':
          $ref: '#/components/responses/NotImplementedError' # Marked as planned

components:
  parameters:
    ButtonIdPath:
      name: buttonId
      in: path
      required: true
      description: Numeric ID of the button.
      schema:
        type: integer
    TagIdPath:
      name: tagId
      in: path
      required: true
      description: Numeric ID of the tag.
      schema:
        type: integer
    TaxClassIdPath:
      name: taxClassId
      in: path
      required: true
      description: Numeric ID of the tax class.
      schema:
        type: integer
    BookkeepingClassIdPath:
      name: bookkeepingClassId
      in: path
      required: true
      description: Numeric ID of the bookkeeping class.
      schema:
        type: integer
    DlcIdPath:
      name: dlcId
      in: path
      required: true
      description: Identifier of the DLC.
      schema:
        type: string # Or integer if numeric
    ResultsLimit:
      name: results_limit
      in: query
      description: Maximum number of results to return.
      schema:
        type: integer
        minimum: 1
        maximum: 1000
        default: 20
    ResultsOffset:
      name: results_offset
      in: query
      description: Number of results to skip for pagination.
      schema:
        type: integer
        minimum: 0
        default: 0
    ResultsSortButton:
      name: results_sort
      in: query
      description: Sort order for button results.
      schema:
        type: string
        enum:
          - button_id
          - button_artno
          - button_title
          - button_price
          - button_id_desc
          - button_artno_desc
          - button_title_desc
          - button_price_desc
    ApiKeyQueryOrHeader: # For DELETE and potentially GET where body is not typical
      # This is a conceptual parameter; actual implementation needs one for query and one for header
      # For simplicity, this is a placeholder. Real OpenAPI would list `key` (query) and `X-Api-Key` (header).
      name: key_or_x-api-key
      in: query # or header
      description: API Key for authentication. (Provide as 'key' in query or 'X-Api-Key' in header for GET/DELETE)
      schema:
        type: string
      # required: true # Implicitly required for protected endpoints

    # ... (Keep existing OrderFilters, DownloadFilters, etc. from original file)
    # The following Filter objects are now filled from the original kwikk.swagger.yml
    OrderFilters:
      name: OrderFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for orders
    DownloadFilters:
      name: DownloadFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for downloads
    RegisterFilters:
      name: RegisterFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for registers
    RepeatFilters:
      name: RepeatFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for repeating payments (deprecated)
    SubscriptionFilters:
      name: SubscriptionFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for subscriptions
    DiscountFilters:
      name: DiscountFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for discounts
    DiscountCodeFilters:
      name: DiscountCodeFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for discount codes
    RepeatPauseFilters:
      name: RepeatPauseFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for repeat pauses
    RequestFilters:
      name: RequestFilters
      in: query
      schema:
        type: object
      style: form
      explode: true
      description: Filtering parameters for requests
    # Path parameters from original for completeness
    order_id: { name: order_id, in: path, required: true, schema: { type: integer }}
    download_id: { name: download_id, in: path, required: true, schema: { type: integer }}
    register_id: { name: register_id, in: path, required: true, schema: { type: integer }}
    repeating_id: { name: repeating_id, in: path, required: true, schema: { type: integer }}
    subscription_id: { name: subscription_id, in: path, required: true, schema: { type: integer }}
    discount_id: { name: discount_id, in: path, required: true, schema: { type: integer }}
    discount_code_id: { name: discount_code_id, in: path, required: true, schema: { type: integer }}
    repeat_pause_id: { name: repeat_pause_id, in: path, required: true, schema: { type: integer }}


  schemas:
    ApiKeyMixin: # For ButtonInput and other inputs
      type: object
      properties:
        key:
          type: string
          description: User's API Key.
      required:
        - key

    Button:
      type: object
      properties:
        button_id:
          type: integer
          example: 1
        button_artno:
          type: string
          example: "PROD001"
        button_title:
          type: string
          example: "Awesome Product"
        button_description:
          type: string
          nullable: true
          example: "This is a truly awesome product."
        button_price:
          type: number
          format: double
          example: 99.99
        button_vat: # Primary VAT field (e.g. percentage or main amount)
          type: number
          format: double
          example: 25.00 
        button_vat_amount_static: # Specific static VAT amount
          type: number
          format: double
          nullable: true
          example: 19.99
        button_maxsales:
          type: integer
          nullable: true
          example: 100
        button_anonymous:
          type: integer
          enum: [0, 1]
          example: 0
        button_shipping_standard:
          type: number
          format: double
          nullable: true
          example: 5.00
        button_shipping_express:
          type: number
          format: double
          nullable: true
          example: 10.00
        button_image_url:
          type: string
          format: url
          nullable: true
          example: "https://example.com/image.jpg"
        button_bare:
          type: integer
          enum: [0, 1]
          example: 0
        button_btntext:
          type: string
          nullable: true
          example: "Buy Now!"
        button_inactive:
          type: integer
          enum: [0, 1]
          example: 0
        button_archived:
          type: integer
          enum: [0, 1]
          example: 0
        button_ticket_settings: # Can be stringified JSON or object
          oneOf:
            - type: object
              # Define structure if known, e.g.:
              # properties:
              #   ticket_mode: { type: string }
              #   max_scans: { type: integer }
            - type: string
          nullable: true
          description: JSON string or object for ticket settings.
        button_lifetime:
          type: string # Or integer if it's always days
          nullable: true
          example: "30 days"
        button_timeframe: # Can be stringified JSON or object
          oneOf:
            - type: object
            - type: string
          nullable: true
          description: JSON string or object for time restrictions.
        button_deadline:
          type: string
          format: date-time # Or date
          nullable: true
        button_max_scans:
          type: integer
          nullable: true
        button_config_settings: # Can be stringified JSON or object
          oneOf:
            - type: object
            - type: string
          nullable: true
          description: JSON string or object for config settings.
        button_repeating_payment_settings: # Can be stringified JSON or object
          oneOf:
            - type: object
            - type: string
          nullable: true
          description: JSON string or object for repeating payment settings.
        button_repeating_payment_note:
          type: string
          nullable: true
        button_created:
          type: string
          format: date-time
        button_updated:
          type: string
          format: date-time
        button_tax_class_id:
          type: integer
          nullable: true
        button_bookkeeping_class_id:
          type: integer
          nullable: true
        button_payment_request_id:
          type: integer
          nullable: true
        button_form_config_id:
          type: integer
          nullable: true
        button_payment_methods_override:
          type: string
          nullable: true
          example: "SWISH,CARD_EU"
        button_css_class_override:
          type: string
          nullable: true
        button_ga_category:
          type: string
          nullable: true
        button_ga_action:
          type: string
          nullable: true
        button_ga_label:
          type: string
          nullable: true
        button_ga_value: # Could be string or number
          oneOf:
            - type: string
            - type: number
          nullable: true
        button_folder_id:
          type: integer
          nullable: true
        button_image_bank_id:
          type: integer
          nullable: true
        button_justcart: # Added based on documentation.php
          type: integer
          enum: [0,1]
          nullable: true
        button_just_add_to_cart_text:
          type: string
          nullable: true
        button_og_title: # Added based on documentation.php
          type: string
          nullable: true
        tags: # If API returns array of IDs for button GET
          type: array
          items:
            type: integer
          nullable: true
          description: Array of Tag IDs associated with the button.
        # If API returns full tag objects:
        # tags:
        #   type: array
        #   items:
        #     $ref: '#/components/schemas/Tag'
        #   nullable: true
        button_html:
          type: string
          readOnly: true # Generated value
        button_link:
          type: string
          format: url
          readOnly: true
        button_qr:
          type: string
          format: url
          readOnly: true
        button_qr_html:
          type: string
          readOnly: true
          
    ButtonInput:
      allOf: # Inherits API Key
        - $ref: '#/components/schemas/ApiKeyMixin'
        - type: object
          properties: # Fields from Button that are writable
            button_artno:
              type: string
            button_title:
              type: string
            button_description:
              type: string
              nullable: true
            button_price:
              type: number
              format: double
            button_vat:
              type: number
              format: double
            button_vat_amount_static:
              type: number
              format: double
              nullable: true
            button_maxsales:
              type: integer
              nullable: true
            button_anonymous:
              type: integer
              enum: [0, 1]
            button_shipping_standard:
              type: number
              format: double
              nullable: true
            button_shipping_express:
              type: number
              format: double
              nullable: true
            button_image_url:
              type: string
              format: url
              nullable: true
            button_bare:
              type: integer
              enum: [0, 1]
            button_btntext:
              type: string
              nullable: true
            button_inactive:
              type: integer
              enum: [0, 1]
            button_archived:
              type: integer
              enum: [0, 1]
            button_ticket_settings:
              oneOf: [{type: object}, {type: string}]
              nullable: true
            button_lifetime:
              type: string # Or integer
              nullable: true
            button_timeframe:
              oneOf: [{type: object}, {type: string}]
              nullable: true
            button_deadline:
              type: string
              format: date-time # Or date
              nullable: true
            button_max_scans:
              type: integer
              nullable: true
            button_config_settings:
              oneOf: [{type: object}, {type: string}]
              nullable: true
            button_repeating_payment_settings:
              oneOf: [{type: object}, {type: string}]
              nullable: true
            button_repeating_payment_note:
              type: string
              nullable: true
            button_tax_class_id:
              type: integer
              nullable: true
            button_bookkeeping_class_id:
              type: integer
              nullable: true
            button_payment_request_id:
              type: integer
              nullable: true
            button_form_config_id:
              type: integer
              nullable: true
            button_payment_methods_override:
              type: string
              nullable: true
            button_css_class_override:
              type: string
              nullable: true
            button_ga_category:
              type: string
              nullable: true
            button_ga_action:
              type: string
              nullable: true
            button_ga_label:
              type: string
              nullable: true
            button_ga_value:
              oneOf: [{type: string}, {type: number}]
              nullable: true
            button_folder_id:
              type: integer
              nullable: true
            button_image_bank_id:
              type: integer
              nullable: true
            button_justcart:
              type: integer
              enum: [0,1]
              nullable: true
            button_just_add_to_cart_text:
              type: string
              nullable: true
            button_og_title:
              type: string
              nullable: true
            tags: # For PUT, expect array of tag IDs
              type: array
              items:
                type: integer
              nullable: true
              description: Array of Tag IDs to associate.

    ButtonInputForm: # For application/x-www-form-urlencoded
      allOf:
        - $ref: '#/components/schemas/ApiKeyMixin' # Includes 'key'
        - type: object
          properties: # Same as ButtonInput, but all will be strings
            button_artno: { type: string }
            button_title: { type: string }
            # ... all other fields from ButtonInput, ensure type: string
            # JSON fields like button_ticket_settings should be stringified JSON
            button_ticket_settings: { type: string, description: "Stringified JSON object for ticket settings." }
            tags: { type: string, description: "Comma-separated list of Tag IDs, e.g., '1,2,3'" }


    OperationResult:
      type: object
      properties:
        method:
          type: string
          example: "create"
        status:
          type: string
          example: "success"
        return_value: # Can be ID or message
          oneOf:
            - type: integer
            - type: string
          example: 123

    OperationResultWithId: # More specific for create/update
      type: object
      properties:
        method:
          type: string
          enum: [create, update]
        status:
          type: string
          enum: [success, error]
        return_value: # Typically the ID of the created/updated resource
          type: integer
        message: # Optional message
          type: string
          nullable: true
          
    Tag:
      type: object
      properties:
        id:
          type: integer
          example: 1
        name:
          type: string
          example: "Summer Collection"

    TaxClass:
      type: object
      properties:
        tax_class_id: # Assuming field names from class.api getTaxClass
          type: integer
          example: 1
        name: # tax_class_name?
          type: string
          example: "Standard Rate"
        percentage: # tax_class_percentage?
          type: number
          format: double
          example: 25.00
      # Add other fields if returned by API

    BookkeepingClass:
      type: object
      properties:
        bookkeeping_class_id: # Assuming field names from class.api getBookkeepingClass
          type: integer
          example: 1
        name: # bookkeeping_class_name?
          type: string
          example: "Domestic Sales"
      # Add other fields if returned by API

    DLC: # Schema for GET /dlcs (list all)
      type: object
      properties:
        id: # dlc_id?
          type: string # Or integer
          example: "ebook_chapter1"
        name:
          type: string
          example: "E-Book Chapter 1"
        # Add other relevant DLC properties

    # ... (Keep existing Order, Download, Register, etc. schemas from original file)
    # The following Schema objects are now filled from the original kwikk.swagger.yml
    Order:
      type: object
      properties:
        order_id:
          type: integer
        order_artnr:
          type: string
        customer_name:
          type: string
      required:
        - order_id
    Download:
      type: object
      properties:
        download_id:
          type: integer
        download_title:
          type: string
      required:
        - download_id
    Register:
      type: object
      properties:
        register_id:
          type: integer
        register_name_first:
          type: string
      required:
        - register_id
    RegisterInput:
      type: object
      additionalProperties: true
    Repeat:
      type: object
      properties: {} # Empty as per original
    Subscription:
      type: object
      properties:
        subscription_id:
          type: integer
      required: [subscription_id]
    Discount:
      type: object
      properties:
        discount_id:
          type: integer
      required: [discount_id]
    DiscountCode:
      type: object
      properties:
        discount_code_id:
          type: integer
      required: [discount_code_id]
    DiscountCodeInput:
      type: object
      required:
        - discount_code_discounts_id
        - discount_code_code_string
      properties:
        discount_code_discounts_id:
          type: integer
        discount_code_code_string:
          type: string
    RepeatPause:
      type: object
      properties:
        repeat_pause_id:
          type: integer
      required: [repeat_pause_id]
    
  responses:
    UnauthorizedError:
      description: API key is missing, invalid, or disabled.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: array
                items:
                  type: object
                  properties:
                    code:
                      type: string
                      example: "101"
                    info:
                      type: string
                      example: "Access Error: No API key provided."
    NotFoundError:
      description: The requested resource was not found.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: array
                items:
                  type: object
                  properties:
                    code:
                      type: string
                      example: "401" # Or 404 from HTTP status
                    info:
                      type: string
                      example: "Results Error: No results found."
    InvalidInputError:
      description: The request body or parameters are invalid.
      content:
        application/json:
          schema:
            type: object
            properties:
              error: # Or a more specific error structure
                type: string
                example: "Invalid input for field X."
    NotImplementedError:
      description: This functionality is planned but not yet implemented.
      content:
        application/json:
          schema:
            type: object
            properties:
              error:
                type: array
                items:
                  type: object
                  properties:
                    code:
                      type: string
                      example: "501"
                    info:
                      type: string
                      example: "Functionality not implemented."
security:
  - ApiKeyAuth: [] # Define ApiKeyAuth in securitySchemes if you want to use global security

securitySchemes:
  ApiKeyAuth: # Example, if you want to formally define it for tools.
              # Actual key check is done in backend logic based on header/query/body.
    type: apiKey
    in: header # One of the common ways, but your API supports multiple
    name: X-Api-Key 
    description: "API Key for authentication. Can also be provided as 'key' in query parameters for GET/DELETE, or 'key' in JSON/form body for POST/PUT."

# Global tag definitions for grouping paths in UI tools
tags:
  - name: Button
    description: Operations related to payment buttons
  - name: Tag
    description: Operations related to tags for buttons
  - name: TaxClass
    description: Operations related to tax classes
  - name: BookkeepingClass
    description: Operations related to bookkeeping classes
  - name: DLC
    description: Operations related to Downloadable Content
  - name: Order
    description: Operations related to orders
  - name: Download
    description: Operations related to downloads and download links
  - name: Register
    description: Operations related to customer registers
  - name: Subscription
    description: Operations related to subscriptions (replaces deprecated Repeat)
  - name: Discount
    description: Operations related to discounts
  - name: DiscountCode
    description: Operations related to discount codes
  - name: RepeatPause
    description: Operations related to subscription pauses
  - name: RepeatingPayment_Deprecated
    description: Deprecated operations related to repeating payments 