components:
  schemas:
    CommentCompany:
      type: object
      properties:
        id:
          type: integer
        message:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
    CompanySortData:
      type: object
      properties:
        id:
          type: integer
        companyName:
          type: string
        responsibleId:
          type: integer
        address:
          type: string
        annualBusinessVolume:
          type: integer
        currency:
          type: string
    Company:
      type: object
      properties:
        id:
          type: integer
        companyName:
          type: string
        responsibleId:
          type: integer
        address:
          type: string
        annualBusinessVolume:
          type: integer
        currency:
          type: string
        messengers:
          type: array
          items:
            $ref: '#/components/schemas/Messenger'
        phones:
          type: array
          items:
            $ref: '#/components/schemas/Phone'
        emails:
          type: array
          items:
            $ref: '#/components/schemas/Email'
        attributes:
          type: array
          items:
            $ref: '#/components/schemas/Attribute'
        contacts:
          type: array
        attachments:
          type: array
          items:
            $ref: '#/components/schemas/AttachmentResource'
        createdAt:
          type: string
        updatedAt:
          type: string
    History:
      type: object
      properties:
        eventType:
          type: string
        eventData:
          type: array
        date:
          type: string
    Email:
      type: object
      properties:
        id:
          type: integer
        isMain:
          type: boolean
        email:
          type: string
    Phone:
      type: object
      properties:
        id:
          type: integer
        isMain:
          type: boolean
        phone:
          type: string
    Messenger:
      type: object
      properties:
        id:
          type: integer
        typeId:
          type: integer
        login:
          type: string
    AttachmentResource:
      type: object
      properties:
        id:
          type: integer
        link:
          type: array
        entityId:
          type: integer
        entityType:
          type: string
        createdAt:
          type: string
        updatedAt:
          type: string
    Pipeline:
      type: object
      properties:
        id:
          type: integer
          description: Pipeline ID
        userId:
          type: integer
          description: ID of the user who created the pipeline
        name:
          type: string
          description: Pipeline name
        status:
          $ref: '#/components/schemas/DefaultStatusProperty'
        order:
          type: integer
          description: Pipelines order
        steps:
          type: array
          items:
            $ref: '#/components/schemas/Step'
        settings:
          type: array
          items:
            $ref: '#/components/schemas/Setting'
    Step:
      type: object
      properties:
        id:
          type: integer
          description: Step ID
        pipelineId:
          type: integer
          description: Pipeline ID
        name:
          type: string
          description: Step name
        order:
          type: integer
          description: Step order
        status:
          $ref: '#/components/schemas/DefaultStatusProperty'
        color:
          type: string
          enum:
            - '#000000'
            - black
          description: Step color
        addEndHours:
          type: integer
          enum:
            - null
            - 1
            - 2
            - 3
            - 4
            - 5
            - 6
            - 8
            - 9
            - 10
          description: Add number of hours or null
        notifyIn:
          type: string
          enum:
            - '0'
            - 15min
            - 30min
            - 1h
            - 2h
            - 3h
            - 6h
            - 12h
            - 24h
            - 2d
            - 3d
            - 4d
            - 5d
            - 6d
            - 7d
          description: Time notification
    Setting:
      type: object
      properties:
        name:
          type: string
          description: Setting name
        value:
          type: string
          description: Setting value
    Deal:
      type: object
      properties:
        id:
          type: integer
          description: Deal ID
        pipelineId:
          type: integer
          description: Pipeline ID
        status:
          $ref: '#/components/schemas/DealStatusProperty'
        stepId:
          type: integer
          description: Pipeline step ID
        responsibleId:
          type: integer
          description: >-
            ID of the responsible for the deal user. Can be obtained in the “Get
            list of invited users” method
        number:
          type: integer
          description: >-
            Deal number, the number is generated automatically according to the
            order in which deal was created. Used in deal name if a custom value
            has not been specified
        name:
          type: string
          description: Deal name
        price:
          type: number
          description: Deal price
        currency:
          type: string
          description: 'Deal currency. Example: UAH, USD, EUR'
        profit:
          type: number
          description: Deal profit in major currency units
        hasExpense:
          type: boolean
          description: Shows if the deal has at least one expense
        order:
          type: integer
          description: Deal order
        sourceType:
          $ref: '#/components/schemas/DealSourceType'
        sourceId:
          type: integer
          description: ID of external source
        history:
          items:
            $ref: '#/components/schemas/DealHistory'
        comments:
          items:
            $ref: '#/components/schemas/DealComment'
        attributes:
          items:
            $ref: '#/components/schemas/DealAttributeValue'
        expiration:
          $ref: '#/components/schemas/DealExpiration'
        attachments:
          $ref: '#/components/schemas/EntityAttachment'
        tasks:
          type: array
          items:
            type: integer
        createdAt:
          type: string
          format: date-time
          description: >-
            The date and time the transaction was created. Output in YYYY-MM-DD
            hh:mm:ss format with fractions of a second and time zone
        updatedAt:
          type: string
          format: date-time
          description: >-
            The date and time the transaction information was last updated.
            Output in YYYY-MM-DD hh:mm:ss format with fractions of a second and
            time zone
    DealDetailed:
      type: object
      properties:
        id:
          type: integer
          description: Deal ID
        pipelineId:
          type: integer
          description: Pipeline ID
        status:
          $ref: '#/components/schemas/DealStatusProperty'
        stepId:
          type: integer
          description: Pipeline step ID
        responsibleId:
          type: integer
          description: >-
            ID of the responsible for the deal user. Can be obtained in the “Get
            list of invited users” method
        number:
          type: integer
          description: >-
            Deal number, the number is generated automatically according to the
            order in which deal was created. Used in deal name if a custom value
            has not been specified
        name:
          type: string
          description: Deal name
        price:
          type: number
          description: Deal price
        currency:
          type: string
          description: 'Deal currency. Example: UAH, USD, EUR'
        profit:
          type: number
          description: Deal profit in major currency units
        hasExpense:
          type: boolean
          description: Shows if the deal has at least one expense
        order:
          type: integer
          description: Deal order
        sourceType:
          $ref: '#/components/schemas/DealSourceType'
        sourceId:
          type: integer
          description: ID of external source
        createdAt:
          type: string
          format: date-time
          description: >-
            The date and time the transaction was created. Output in YYYY-MM-DD
            hh:mm:ss format with fractions of a second and time zone
        updatedAt:
          type: string
          format: date-time
          description: >-
            The date and time the transaction information was last updated.
            Output in YYYY-MM-DD hh:mm:ss format with fractions of a second and
            time zone
        history:
          $ref: '#/components/schemas/DealHistory'
        comments:
          $ref: '#/components/schemas/DealComment'
        attributes:
          $ref: '#/components/schemas/DealAttributeValue'
    DealType:
      type: object
      properties:
        id:
          type: integer
          description: ''
        name:
          type: string
          description: ''
        status:
          type: integer
          description: ''
    DealSourceType:
      type: object
      properties:
        id:
          type: integer
          description: ''
        name:
          type: string
          description: ''
    DealComment:
      type: object
      properties:
        id:
          type: integer
        userId:
          type: integer
        eventData:
          type: object
          properties:
            text:
              type: string
        status:
          type: integer
        eventTime:
          type: string
        createdAt:
          type: string
        updatedAt:
          type: string
        attachments:
          items:
            $ref: '#/components/schemas/EntityAttachment'
        childCount:
          type: integer
        childUsers:
          type: array
          items:
            type: integer
    Source:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
    DealHistory:
      type: object
      properties:
        id:
          type: integer
        userId:
          type: integer
        eventData:
          type: array
        eventType:
          type: string
        eventTime:
          type: string
          format: date-time
        currentData:
          type: object
          properties:
            contactFirstName:
              type: string
            contactLastName:
              type: string
    MessengerType:
      type: object
      properties:
        id:
          $ref: '#/components/schemas/MessengerTypeProperty'
        name:
          type: string
          description: Messenger name
    Payment:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        price:
          $ref: '#/components/schemas/PaymentOrderPrice'
        status:
          type: integer
        orderId:
          type: string
        paymentDescription:
          type:
            - string
            - 'null'
        paymentMethod:
          type: string
          enum:
            - Fondy
            - YooMoney
            - PayPal
        createdAt:
          type: string
          format: date-time
        promoCode:
          type: string
        promoCodeDiscount:
          type: number
    UserPaymentData:
      type: object
      properties:
        id:
          type: integer
        userId:
          type: integer
        contactId:
          type: integer
        dealId:
          type: integer
        status:
          type: integer
        firstName:
          type: string
        lastName:
          type: string
        name:
          type: string
        responsibleId:
          type: integer
        price:
          type: object
          properties:
            amount:
              type: integer
            currency:
              type: string
        description:
          type: string
        merchantName:
          type: string
        merchantUuid:
          type: string
        paymentMethod:
          type: string
        promoCode:
          type: string
        promoCodeDiscount:
          type: string
        createdAt:
          type: string
        externalContactId:
          type: string
        paymentItems:
          type: array
          items:
            properties:
              name:
                type: string
              productId:
                type: string
              type:
                type: integer
                enum:
                  - 1 (product)
                  - 2 (crmProduct)
                  - 3 (delivery)
              quantity:
                type: string
              amount:
                type: integer
    Contact:
      type: object
      properties:
        id:
          type: integer
          description: Contact ID
        userId:
          type: integer
          description: ID of user who created the contact
        sourceType:
          type: string
          enum:
            - manually
            - chatbot
            - subscription_form
            - landing
            - a360
            - payments
        responsibleId:
          type: integer
          description: >-
            ID of user responsible for the contact. Can be obtained in the “Get
            list of invited users” method
        firstName:
          type: string
          description: Contact first name
        lastName:
          type: string
          description: Contact last name
        dealsQty:
          type: integer
        externalContactId:
          type: string
        comments:
          items:
            $ref: '#/components/schemas/ContactComment'
        tags:
          items:
            $ref: '#/components/schemas/ContactTag'
        phones:
          items:
            $ref: '#/components/schemas/ContactPhone'
        emails:
          items:
            $ref: '#/components/schemas/ContactEmail'
        messengers:
          items:
            $ref: '#/components/schemas/ContactMessenger'
        attributes:
          items:
            $ref: '#/components/schemas/ContactAttributeValue'
        history:
          items:
            $ref: '#/components/schemas/ContactHistory'
        tasks:
          type: array
          items:
            type: integer
        createdAt:
          type: string
          format: date-time
          description: >-
            The date and time the contact was created. Output in YYYY-MM-DD
            hh:mm:ss format with fractions of a second and time zone
        updatedAt:
          type: string
          format: date-time
        attachments:
          $ref: '#/components/schemas/EntityAttachment'
    ContactComment:
      type: object
      properties:
        id:
          type: integer
        userId:
          type: integer
        text:
          type: string
        createdAt:
          type: string
          format: date-time
        updatedAt:
          type: string
          format: date-time
        attachments:
          $ref: '#/components/schemas/EntityAttachment'
        childCount:
          type: integer
        childUsers:
          type: array
          items:
            type: integer
    ContactHistory:
      type: object
      properties:
        id:
          type: integer
        userId:
          type: integer
        contactId:
          type: integer
        eventType:
          type: string
        eventTime:
          type: string
          format: date-time
        eventData:
          type: object
          properties:
            dealName:
              type: string
    ContactPhone:
      type: object
      properties:
        id:
          type: integer
          description: Contact phone ID
        phone:
          type: string
        isMain:
          type: boolean
    ContactEmail:
      type: object
      properties:
        id:
          type: integer
          description: Email address ID
        email:
          type: string
          description: Email address
        isMain:
          type: boolean
          description: Determines whether the email address is the main one
    ContactMessenger:
      type: object
      properties:
        id:
          type: integer
          description: ID of the added messenger
        typeId:
          type: integer
          description: Messenger type
        login:
          type: string
          description: Contact login in the specified messenger
        botId:
          type: string
          description: External bot ID
        contactId:
          type: string
          description: External contact ID
        status:
          type: integer
        chatbotUrl:
          type: string
          description: URL of the chatbot from which the contact was received
        isMainChatbot:
          type: boolean
          description: Determine if chatbot messenger is the main one
    ContactTag:
      type: object
      properties:
        id:
          type: integer
          description: Tag ID
        name:
          type: string
          description: Tag name
        colorText:
          type: string
        colorBackground:
          type: string
        contactCount:
          type: integer
          description: Number of contacts associated with the tag
        taskCount:
          type: integer
          description: Number of tasks associated with a tag
    ContactAttribute:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        status:
          type: integer
          description: |-
            | Status
            * 0 — inactive (deleted by user) * 1 — active * 2 — hidden
        order:
          type: integer
        options:
          type: array
          items:
            oneOf:
              - type: string
              - type: integer
          description: Items of "List" field type
    Attribute:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        status:
          type: integer
        type:
          type: integer
        mandatory:
          type: boolean
        order:
          type: integer
        options:
          type: array
          items:
            oneOf:
              - type: string
              - type: integer
    ContactAttributeValue:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        status:
          type: integer
          description: |-
            | Status
            * 0 — inactive (deleted by user) * 1 — active * 2 — hidden
        type:
          type: integer
        mandatory:
          type: boolean
        contactCardShow:
          type: boolean
        order:
          type: integer
        options:
          type: array
          items:
            oneOf:
              - type: string
              - type: integer
          description: Items of "List" field type
        value:
          properties:
            type:
              type: string
              description: Field type
            value:
              type: string
              description: Field value
          description: ''
        default:
          type: boolean
          description: ''
    DealAttribute:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        status:
          $ref: '#/components/schemas/DefaultStatusProperty'
        type:
          type: integer
          description: ''
        mandatory:
          type: boolean
          description: ''
        order:
          type: integer
        options:
          type: array
          items:
            oneOf:
              - type: string
              - type: integer
          description: Items of "List" field type
    DealAttributeValue:
      type: object
      properties:
        id:
          type: integer
        pipelineId:
          type: integer
        name:
          type: string
        status:
          type: integer
        type:
          type: integer
        mandatory:
          type: boolean
        order:
          type: integer
        options:
          type: array
          description: Items of "List" field type
          items:
            oneOf:
              - type: string
              - type: integer
        value:
          properties:
            value:
              type: string
    Comment:
      type: object
      properties:
        id:
          type: integer
          description: ''
        userId:
          type: integer
          description: ''
        text:
          type: string
          description: ''
        status:
          type: integer
          description: ''
        createdAt:
          type: string
          format: date-time
          description: ''
        updatedAt:
          type: string
          format: date-time
          description: ''
    User:
      type: object
      properties:
        id:
          type: integer
        firstname:
          type: string
          description: User first name
        lastname:
          type: string
          description: User last name
        email:
          type: string
          description: Email
        avatar:
          type: string
          description: Link to profile picture
        lang:
          type: string
          description: >-
            The interface language set in the interface of the invited user. Can
            be: en_US, es_MX, fr_FR, pt_BR, ru_RU, tr_TR, uk_UA
        timezone:
          type: integer
          description: Time zone set in user settings
        currency:
          type: string
          description: Currency set in settings
    ContactsAutocomplete:
      type: array
      items:
        properties:
          id:
            type: integer
          firstName:
            type: string
          lastName:
            type: string
          email:
            type: string
          phone:
            type: string
    DealsAutocomplete:
      type: array
      items:
        properties:
          id:
            type: integer
          name:
            type: string
          responsibleId:
            type: number
          stepId:
            type: number
    TaskAutocomplete:
      type: array
      items:
        properties:
          id:
            type: integer
          name:
            type: string
          responsibleId:
            type: integer
          boardId:
            type: integer
          stepId:
            type: integer
          observers:
            type: array
    TaskTotals:
      type: object
      properties:
        total:
          type: integer
        steps:
          type: array
          items:
            properties:
              stepId:
                type: integer
              total:
                type: integer
    TasksAttribute:
      type: array
      items:
        properties:
          attributeId:
            type: integer
          value:
            type: string
            example: string or number or array
    Attributes:
      type: object
      properties:
        type:
          type: integer
          enum:
            - 1
            - 2
            - 3
            - 4
            - 5
            - 6
        name:
          type: string
        status:
          type: boolean
        value:
          type: array
          items:
            $ref: '#/components/schemas/AttributeValue'
    AttributeValue:
      type: object
      properties:
        id:
          type: number
        value:
          type: string
    TaskRepeats:
      type: object
      properties:
        type:
          type: integer
          description: |
            Repetition frequency

            * 1 - daily
            * 2 - weekly
            * 3 - monthly
            * 4 - yearly
        startDate:
          type: string
          format: date-time
          description: Format - 2021-11-25 13:38
        endSetting:
          type: object
          properties:
            type:
              type: string
              description: |
                * byDate - Complete task on the specified date
                * byCount - Complete task after task performs "byCount" times
            value:
              description: Has Date type if "byDate" type, Number if "byCount"
        setting:
          type: object
          properties:
            everyDay:
              type: number
            days:
              type: array
              description: Array of ordinal days of the week
              example: '[1, 3, 5] - repeat every Monday, Wednesday and Friday'
            everyWeekOfMonth:
              type: integer
              description: Ordinal number of week of the month (from 1 to 4)
            numberOfMonth:
              type: object
              properties:
                everyDay:
                  type: integer
                  description: Ordinal number of the day of the month
                everyMonth:
                  type: integer
                  description: Ordinal number of the month
            dayOfMonth:
              type: object
              properties:
                dayOfWeek:
                  type: integer
                  description: Ordinal day of the week
                everyMonth:
                  type: integer
                  description: Ordinal month of the year
                everyWeek:
                  type: integer
                  description: Ordinal number of week of the month (from 1 to 4)
    TasksConnection:
      type: object
      properties:
        tasks:
          $ref: '#/components/schemas/TaskAutocomplete'
        deals:
          $ref: '#/components/schemas/DealsAutocomplete'
        contacts:
          $ref: '#/components/schemas/ContactsAutocomplete'
        subTasks:
          $ref: '#/components/schemas/TaskAutocomplete'
    TaskComment:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        taskId:
          type: integer
        userId:
          type: integer
        body:
          type: string
        createdAt:
          type: string
        updatedAt:
          type: string
        attachments:
          items:
            $ref: '#/components/schemas/EntityAttachment'
        childCount:
          type: integer
        childUsers:
          type: array
          items:
            type: integer
    TaskAttachment:
      type: object
      properties:
        id:
          type: integer
        link:
          type: string
        taskId:
          type: integer
    TaskChecklist:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        taskId:
          type: integer
        isDone:
          type: boolean
        items:
          $ref: '#/components/schemas/ChecklistItems'
    ChecklistItems:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        order:
          type: number
        isDone:
          type: boolean
    TaskTag:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        colorText:
          type: string
        colorBackground:
          type: string
    Pagination:
      type: object
      properties:
        currentPage:
          type: integer
        lastPage:
          type: integer
        perPage:
          type: integer
        total:
          type: integer
    Tasks:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        userId:
          type: integer
        responsibleId:
          type: integer
        parentId:
          type: integer
        boardId:
          type: integer
        stepId:
          type: integer
        priority:
          type: integer
        order:
          type: integer
        description:
          type: integer
        alert:
          type: string
          description: >-
            Notify before task expires (when notification is enabled). Allowed
            values - 0(not selected), 15min, 30min, 1h, 2h, 3h, 6h, 12h, 24h,
            2d, 3d, 4d, 5d, 6d, 7d
        repeat:
          type: integer
        startAt:
          type: string
          description: Format - 2021-11-25 13:38
        finishAt:
          type: string
          description: Format - 2021-11-25 13:38
        observers:
          type: array
          items:
            type: integer
        checklists:
          $ref: '#/components/schemas/TaskChecklist'
        attachments:
          $ref: '#/components/schemas/EntityAttachment'
        attributes:
          $ref: '#/components/schemas/Attributes'
        comments:
          $ref: '#/components/schemas/TaskComment'
        histories:
          $ref: '#/components/schemas/TaskHistory'
        tags:
          $ref: '#/components/schemas/TaskTag'
        deals:
          type: array
          description: Array of deal IDs
        tasks:
          type: array
          description: Array of task IDs
        contacts:
          type: array
          description: Array of contact IDs
        subTasks:
          type: array
          description: Array of task IDs
        updatedDaysAt:
          type: number
        createdDaysAt:
          type: number
        createdAt:
          type: string
        updatedAt:
          type: string
    Boards:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        userId:
          type: integer
        order:
          type: integer
        steps:
          $ref: '#/components/schemas/BoardSteps'
        settings:
          $ref: '#/components/schemas/BoardSettings'
        attributes:
          $ref: '#/components/schemas/BoardAttribute'
    BoardAttribute:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        type:
          type: integer
        mandatory:
          type: boolean
        options:
          type: array
          default:
            - 1
            - 2
        status:
          type: integer
        order:
          type: integer
    BoardSettings:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        value:
          type: string
        boardId:
          type: number
    BoardSteps:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
        color:
          type: string
        order:
          type: integer
        boardId:
          type: integer
    EntityFilterList:
      type: array
      items:
        properties:
          attributeId:
            type: integer
            description: Attribute ID (optional)
          name:
            type: string
            description: Attribute/Field name
          isFilterable:
            type: boolean
            description: Is attribute filterable
    TaskHistory:
      type: object
      properties:
        id:
          type: integer
        taskId:
          type: integer
        eventTime:
          type: string
        eventType:
          type: string
        eventData:
          type: object
        userId:
          type: number
    TelephonyCall:
      type: object
      properties:
        id:
          type: integer
        integrationId:
          type: integer
        integrationGroupId:
          type: integer
        responsibleId:
          type: integer
        phone:
          type: string
          description: Contact phone, used in this call
        callDuration:
          type: integer
          description: Duration of the call
        callType:
          type: integer
          description: Type of the call (0 - incoming, 1 - outgoing)
        state:
          type: integer
          description: State of the call (1 - pending, 2 - successful, 3 - failed)
        callRecordLink:
          type: string
          description: Link to call record
        createdAt:
          type: string
          format: date-time
          example: 2022-06-28 18:17
        contact:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            firstName:
              type: string
            lastName:
              type: string
        deal:
          type:
            - object
            - 'null'
          properties:
            id:
              type: integer
            name:
              type: string
    EntityAttachment:
      type: object
      properties:
        id:
          type: integer
        link:
          type: string
        entityId:
          type: number
        entityType:
          type: string
        createdAt:
          type: string
        updatedAt:
          type: string
    DealExpiration:
      type: object
      properties:
        date:
          type: string
          format: date
          description: Deal expiration date
        time:
          type:
            - string
            - 'null'
          format: time
          description: Deal expiration time
        dateTime:
          type: string
          format: date-time
          description: Deal expiration DateTime
        notificationEnabled:
          type: boolean
          description: Is notification enabled
        notifyIn:
          type:
            - string
            - 'null'
          description: >-
            Notify before deal expires (when notification is enabled). Allowed
            values - 0(not selected), 15min, 30min, 1h, 2h, 3h, 6h, 12h, 24h,
            2d, 3d, 4d, 5d, 6d, 7d
        expired:
          type: boolean
          description: The deal has expired
        expires_within_day:
          type: boolean
          description: The deal expires within 24 hours
    IntegerSourceTypeProperty:
      type: integer
      description: >-
        | * 1 - chatbot * 2 - manually * 3 - subscription_form * 4 - landing * 5
        - a360 * 6 - payments * 7 - import * 8 - public_api * 9 - education * 10
        - integration * 11 - popup * 12 - emailService
    TaskPriorityProperty:
      type: integer
      description: |-
        | Task priority
        * 1 - low * 2 - middle * 3 - high
    DealStatusProperty:
      type: integer
      description: >-
        | Step status

        * 0 — inactive (deleted by user) * 1 — active * 2 - completed deal as
        “Unsuccessful” * 3 - completed deal as “Successful”
    DefaultStatusProperty:
      type: integer
      description: |-
        | Status
        * 0 — inactive (deleted by user) * 1 — active
    MessengerTypeProperty:
      type: integer
      description: >-
        | Messenger type. Possible values: * 1 — Telegram * 2 — Facebook * 4 —
        Instagram * 5 — WhatsApp * 6 — Viber
    AttributesProperty:
      type: array
      description: Filter by attributes only
      items:
        type: object
        properties:
          id:
            type: string
            description: Attribute ID
          expression:
            $ref: '#/components/schemas/FilterExpressionProperty'
          value:
            maxLength: 255
            description: Can have string value or array of strings
    FilterExpressionProperty:
      type: string
      description: >-
        | Possible values:

        - eq (=) - neq (!=) - gt (>) - gte (>=) - lt (<) - lte (<=) - like - in
        (check among list of values).
    ManagerSettings:
      type: object
      properties:
        sectionId:
          type: integer
        responsibleId:
          type: integer
    CustomTab:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
          description: Custom tab name
        userId:
          type: integer
          description: Custom tab owner
        isVisible:
          type: boolean
          description: Indicates whether the entity is visible to users
        isDefault:
          type: boolean
          description: Indicates whether the entity is default and cannot be changed
        type:
          type: integer
          enum:
            - 0
            - 1
          description: 0 - attributes, 1 - integration
        entityType:
          type: integer
          enum:
            - 0
            - 1
            - 2
            - 3
          description: 0 - contact, 1 - pipeline, 2 - board, 3 - company
        entityId:
          type: integer
          description: Related entity ID. Only for boards and pipelines
    CustomTabWithAttribute:
      type: object
      properties:
        id:
          type: integer
        name:
          type: string
          description: Custom tab name
        userId:
          type: integer
          description: Custom tab owner
        isVisible:
          type: boolean
          description: Indicates whether the entity is visible to users
        isDefault:
          type: boolean
          description: Indicates whether the entity is default and cannot be changed
        type:
          type: integer
          enum:
            - 0
            - 1
          description: 0 - attributes, 1 - integration
        entityType:
          type: integer
          enum:
            - 0
            - 1
            - 2
            - 3
          description: 0 - contact, 1 - pipeline, 2 - board, 3 - companies
        entityId:
          type: integer
          description: Related entity ID. Only for boards and pipelines
        attributes:
          type: array
          items:
            type: object
            properties:
              attributeId:
                type: integer
              attributeType:
                type: integer
    PaymentOrderPrice:
      type: object
      properties:
        amount:
          type: string
        currency:
          type: string
  requestBodies:
    DealFilter:
      content:
        application/json:
          schema:
            properties:
              limit:
                type: integer
                default: 10
                description: Limit on the number of records displayed. Default value — 10
              offset:
                type: integer
                default: 0
                description: Offset — 0
              sortBy:
                type: object
                properties:
                  fieldName:
                    type: string
                    example: id
                  direction:
                    type: string
                    example: desc
                description: >-
                  Sorting direction. Possible values: asc — ascending order;
                  desc — descending order.
                enum:
                  - asc
                  - desc
              filter:
                type: array
                description: Filter by deal fields (example "id", "stepId" ...)
                items:
                  type: object
                  properties:
                    name:
                      type: string
                      description: >-
                        | Deal field name (for example "id"). Can not filter by
                        attributes. For filtering by attributes use "attributes"
                        property. Possible values:

                        - id - pipelineId - status - stepId - name -
                        responsibleId - number - Deal number - price - currency
                        - Deal currency. Accepts values in the form of UAH, USD,
                        EUR - sourceType - Contact source - sourceId - Custom
                        source ID of the deal from an external source -
                        createdAt - updatedAt
                    expression:
                      $ref: '#/components/schemas/FilterExpressionProperty'
                    value:
                      maxLength: 255
                      description: Can have string value or array of strings
              unlimited:
                type: boolean
                description: Return all active deals without limit
              email:
                type: string
                description: Email address of the contact where you need to find deals
              phone:
                type: string
                description: Phone number of the contact you need to use to find deals
              firstName:
                type: string
                description: Name of the contact by whom you want to find deals
              lastName:
                type: string
                description: Filter by contact last name
              name:
                type: string
                description: Filter by deal name
              completionDateFrom:
                type: string
                description: Deal completion date from
              completionDateTo:
                type: string
                description: Deal completion date to
              pipelineIds:
                type: array
                description: Filter by pipeline Ids
                example: '[1,2,3]'
                items:
                  type: integer
              attributes:
                $ref: '#/components/schemas/AttributesProperty'
              expiration:
                type: integer
                description: >-
                  Filter by deal expiration date (1 - without date, 2 - overdue,
                  3 - within day, 4 - within week, 5 - within month)
    FilterTelephonyCalls:
      content:
        application/json:
          schema:
            type: object
            properties:
              from:
                type: string
                format: date-time
                description: Date from
              to:
                type: string
                format: date-time
                description: Date to
              responsibleIds:
                type: array
                description: List of responsible user IDs
                items:
                  type: integer
              callType:
                type: integer
                description: Type of the call (0 - incoming, 1 - outgoing)
              state:
                type: integer
                description: State of the call (pending - 1, successful - 2, failed - 3)
              integrationGroupId:
                type: integer
              contactFirstName:
                type: string
              contactLastName:
                type: string
              contactEmail:
                type: string
              contactPhone:
                type: string
    AttachmentBody:
      content:
        application/json:
          schema:
            type: object
            properties:
              link:
                type: string
                example: /contacts/sendPulse_crm_report.pdf
                description: >-
                  First, the file must be uploaded to the file manager, and then
                  the file can be attached.
              entityId:
                type: number
                description: ID of entityType (example - id of task, if entityType=task)
              entityType:
                type: string
                description: 'One of entity types: task, deal, contact'
    AttachmentUpdateBody:
      content:
        application/json:
          schema:
            type: object
            properties:
              link:
                type: string
                example: /contacts/sendPulse_crm_report.pdf
                description: >-
                  First, the file must be uploaded to the file manager, and then
                  the file can be attached.
  responses:
    '404':
      description: Record not found
      content:
        application/json:
          schema:
            properties:
              data:
                properties:
                  code:
                    type: integer
                  message:
                    type: string
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      bearerFormat: API Key
      description: >
        Static API Key authentication.  A long-lived token generated manually in
        the SendPulse account settings.
      x-ai-description: >
        Permanent authentication token. Ideal for simple integrations without
        token refresh logic.
    outh2:
      type: oauth2
      description: OAuth 2.0 Client Credentials flow for temporary access tokens.
      flows:
        clientCredentials:
          tokenUrl: https://api.sendpulse.com/oauth/access_token
          scopes: {}
      x-ai-description: >
        Standard OAuth 2.0 flow using Client ID and Client Secret.  Provides
        temporary tokens (valid for 1 hour) for enhanced security.
openapi: 3.1.2
info:
  description: >-
    Using the API for the CRM service, you can integrate your system with CRM
    from SendPulse and receive detailed information on pipelines, deals,
    contacts and their attributes and users. You can also create deals and
    contacts, assign and remove fields, tags, contact details and instant
    messengers. On the right, there is a button for authorizing requests made on
    this page. Click “Authorize,” then insert the ID and Secret from your
    account. To perform a request directly from the page, click the "Try it out"
    button within each method block. Then fill in input fields if any (for URL
    parameters, the description is right below the URL request; for body
    parameters, the description is under the “Scheme” button to the right of the
    example), and click “Run.” You will find the server response and description
    of received parameters below.
  title: SendPulse CRM Public API
  version: 0.1.0
security:
  - apiKey: []
  - oauth2: []
servers:
  - url: https://api.sendpulse.com/crm/v1
paths:
  /users:
    get:
      tags:
        - Users
      summary: Get a list of team members
      responses:
        '200':
          description: >-
            | Returns a list of active invited users with the following
            information about each user: team member ID, contact details and
            interface settings * active users - team members who have confirmed
            their account through an email invitation. You can assign deals and
            contacts to your team members.
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/User'
      operationId: getUsers
      x-ai-role: team_management_specialist
      x-ai-description: >-
        Retrieves all active team members in the account — users who have
        confirmed their invitation via email. This list is essential for CRM
        workflows where deals and contacts must be assigned to specific team
        members. Use this endpoint to resolve human-readable names to internal
        IDs before performing assignments.
      x-ai-reasoning-instructions:
        - >-
          Use this list to validate that a target assignee exists and is active
          before assigning deals or contacts.
        - Cache results if performing bulk assignments to avoid repeated calls.
        - >-
          Note that only confirmed (active) users are returned — pending
          invitations are excluded.
      x-ai-responding-instructions:
        - >-
          Present team members by name and role for easier selection by the
          user.
        - >-
          If the list is empty, inform the user that no confirmed team members
          exist yet and suggest sending invitations.
        - >-
          When helping assign resources, reference the team member ID, not just
          the name.
      x-ai-suggestions:
        - Use returned IDs with contact or deal assignment endpoints.
        - >-
          Cross-reference with pipeline stages to see workload distribution per
          team member.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /pipelines:
    post:
      tags:
        - Pipelines
      summary: Create new pipeline
      description: Create new pipeline with specified settings
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Pipeline name
                settings:
                  type: array
                  items:
                    $ref: '#/components/schemas/Setting'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Pipeline'
      operationId: createPipeline
      x-ai-role: crm_workflow_architect
      x-ai-description: >-
        Initializes a new CRM pipeline — a structured, stage-based workflow for
        tracking deals or leads through a defined sales or support process. A
        pipeline is the backbone of CRM automation: it defines the stages
        through which contacts or deals progress and governs which automations,
        notifications, and conditions fire at each transition.
      x-ai-reasoning-instructions:
        - >-
          Before creating, check if a pipeline with a similar name already
          exists to avoid duplicates.
        - >-
          Clarify the intended use case (sales, support, onboarding) to help the
          user choose appropriate stage settings.
        - >-
          Validate that `settings` values conform to the expected schema —
          incomplete settings may result in a non-functional pipeline.
        - >-
          If the user hasn't specified stages or conditions, suggest starting
          with a minimal viable pipeline and iterating.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by referencing the new pipeline's ID and
          name.
        - >-
          Suggest the next logical step: adding stages or assigning
          contacts/deals to the pipeline.
        - >-
          If settings were omitted, note that default settings were applied and
          they can be updated later.
        - >-
          On failure, explain whether the issue is a naming conflict, invalid
          settings schema, or permission problem.
      x-ai-suggestions:
        - Sales_Pipeline_B2B
        - Lead_Qualification_Flow
        - Customer_Onboarding_Pipeline
        - Support_Escalation_Track
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    get:
      tags:
        - Pipelines
      summary: Get a list of pipelines
      description: >-
        Returns a list of pipelines with information about each: pipeline ID,
        pipeline creator, created statuses, and pipeline settings
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Pipeline'
      operationId: getPipelines
      x-ai-role: crm_pipeline_analyst
      x-ai-description: >-
        Retrieves the full list of CRM pipelines configured in the account.
        Pipelines define the sales or workflow stages through which contacts
        move. This endpoint is the entry point for understanding the current
        pipeline structure before creating deals, assigning stages, or
        automating transitions.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint to discover available pipeline IDs before creating
          or updating deals.
        - >-
          Check pipeline statuses to determine which pipelines are active and
          suitable for new deals.
        - >-
          If the user asks about a specific pipeline by name, fetch all
          pipelines first and filter by name client-side, as the API does not
          support name-based filtering.
      x-ai-responding-instructions:
        - Present the list with pipeline names and IDs for easy reference.
        - >-
          If no pipelines exist, suggest creating one as a prerequisite for deal
          management.
        - >-
          Highlight any pipelines with unusual configurations (e.g., no statuses
          defined) as potential setup issues.
      x-ai-suggestions:
        - >-
          Use the returned pipeline IDs with `createDeal` to assign deals to the
          correct pipeline.
        - >-
          Inspect `statuses` in each pipeline to understand available deal
          stages before progressing contacts.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /pipelines/{pipelineId}:
    get:
      tags:
        - Pipelines
      summary: Get information about a pipeline by ID
      description: >-
        Returns information about the specified pipeline: pipeline ID, pipeline
        creator, created statuses, and pipeline settings
      parameters:
        - name: pipelineId
          in: path
          required: true
          description: >-
            ID of a pipeline you need to get information about. It can be
            obtained with the "Get a list of pipelines" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Pipeline'
      operationId: getPipelineById
      x-ai-role: crm_pipeline_analyst
      x-ai-description: >-
        Retrieves the full configuration snapshot of a single CRM pipeline —
        including its creator, status definitions, and behavioral settings. Use
        this to inspect pipeline structure before automating stage transitions
        or auditing workflow logic.
      x-ai-reasoning-instructions:
        - >-
          Ensure the pipelineId was obtained from the 'Get a list of pipelines'
          response — do not guess or construct IDs manually.
        - >-
          If the user asks about a pipeline by name, resolve the ID first using
          the list endpoint before calling this one.
        - >-
          Check whether the response includes all expected statuses; absence may
          indicate an incomplete pipeline setup.
      x-ai-responding-instructions:
        - >-
          Summarize the pipeline's key settings (name, creator, status count)
          rather than dumping the raw object.
        - >-
          If the user needs to modify the pipeline, suggest the appropriate
          update endpoint as a follow-up.
        - >-
          If a 404 is returned, confirm the pipelineId source and suggest
          re-fetching the pipeline list.
      x-ai-suggestions:
        - >-
          Use this endpoint to verify pipeline structure before creating or
          moving deals through stages.
        - >-
          Combine with 'Get a list of pipelines' to build a full pipeline
          inventory.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - Pipelines
      summary: Update information about a pipeline by its ID
      description: Updates information in the specified pipeline
      parameters:
        - name: pipelineId
          in: path
          required: true
          description: Pipeline ID to be updated.
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Pipeline name
                order:
                  type: integer
                  description: Field display order
                settings:
                  type: array
                  items:
                    $ref: '#/components/schemas/Setting'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Pipeline'
      operationId: updatePipeline
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Updates the metadata and configuration of an existing CRM pipeline. A
        pipeline defines the sales or processing stages through which deals
        progress — changing its name, order, or settings reconfigures the
        workflow structure for all deals currently inside it.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the pipelineId exists to avoid silent
          failures.
        - >-
          If renaming, warn the user that the new name should remain unique and
          descriptive to avoid confusion with other pipelines.
        - >-
          When changing `order`, consider that shifting one pipeline's position
          may affect the display order of other pipelines — advise a full
          re-check afterward.
        - >-
          Treat `settings` as a full replacement of the pipeline's configuration
          array, not a partial merge — ensure all desired settings are included
          in the request.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were changed by comparing the request payload
          against the returned `data` object.
        - If the pipeline name was updated, highlight the new name explicitly.
        - >-
          Suggest verifying the pipeline's stage list as a logical next step
          after structural changes.
      x-ai-suggestions:
        - >-
          Retrieve current pipeline data with GET /pipelines/{pipelineId} before
          updating to avoid accidental overwrites.
        - 'Use PATCH semantics in mind: only send fields you intend to change.'
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating a pipeline's settings affects all deals currently assigned
            to it. Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
  /pipelines/{pipelineId}/steps:
    post:
      tags:
        - Pipeline Steps
      summary: Create a new pipeline step
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                order:
                  type: integer
                color:
                  type: string
                  enum:
                    - '#000000'
                    - black
                  description: Step color
                addEndHours:
                  type: integer
                  enum:
                    - null
                    - 1
                    - 2
                    - 3
                    - 4
                    - 5
                    - 6
                    - 8
                    - 9
                    - 10
                  description: Add number of hours or null
                notifyIn:
                  type: string
                  enum:
                    - '0'
                    - 15min
                    - 30min
                    - 1h
                    - 2h
                    - 3h
                    - 6h
                    - 12h
                    - 24h
                    - 2d
                    - 3d
                    - 4d
                    - 5d
                    - 6d
                    - 7d
                  description: Time notification
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Step'
      operationId: createPipelineStep
      x-ai-role: crm_pipeline_architect
      x-ai-description: >-
        Adds a new stage to an existing sales pipeline, defining the structural
        progression of deals. Each step represents a distinct phase in the sales
        funnel — from initial contact to closing. The order, visual color, and
        time-based notifications shape how the team tracks and responds to deal
        movement through the pipeline.
      x-ai-reasoning-instructions:
        - Verify the pipeline exists before attempting to add a step.
        - >-
          Check the current steps of the pipeline to determine appropriate
          `order` value and avoid collisions.
        - >-
          If `order` is not specified by the user, suggest appending at the end
          (highest order + 1).
        - >-
          Advise using descriptive step names aligned with the actual sales
          process (e.g., 'Qualification', 'Proposal Sent', 'Negotiation').
        - >-
          If `notifyIn` is set, clarify to the user that this controls how far
          in advance or after a deal enters this step a notification is
          triggered.
      x-ai-responding-instructions:
        - >-
          Confirm the new step was created and mention its position (order)
          within the pipeline.
        - >-
          If color was set, acknowledge it to confirm visual differentiation in
          the UI.
        - >-
          Suggest reviewing the full pipeline structure using the list steps
          endpoint to confirm ordering.
        - >-
          If `notifyIn` was configured, remind the user to ensure team
          notifications are active for this pipeline.
      x-ai-suggestions:
        - Qualification
        - Proposal Sent
        - Negotiation
        - Contract Review
        - Closed Won
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    get:
      tags:
        - Pipeline Steps
      summary: Get pipeline steps
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Step'
      operationId: getPipelineSteps
      x-ai-role: crm_pipeline_analyst
      x-ai-description: >-
        Retrieves the ordered list of steps configured within a specific
        pipeline. Steps define the sequential stages a deal or contact must pass
        through. Understanding the step structure is a prerequisite for creating
        or moving deals, as each step ID governs valid state transitions within
        the pipeline's lifecycle.
      x-ai-reasoning-instructions:
        - >-
          Verify the pipelineId exists before calling — use a pipeline listing
          endpoint if the ID is unknown.
        - >-
          Use this endpoint to map step names to step IDs before performing any
          deal stage transitions.
        - >-
          If the response returns an empty steps array, inform the user that the
          pipeline has no configured stages yet.
      x-ai-responding-instructions:
        - >-
          Present steps in their logical order, highlighting each step's ID and
          name.
        - >-
          Suggest using step IDs from this response as input for endpoints that
          create or move deals.
        - >-
          If the pipeline is not found, clarify that the pipelineId may be
          invalid or the user may lack access.
      x-ai-suggestions:
        - >-
          Use returned step IDs with deal creation or deal update endpoints to
          assign a stage.
        - >-
          Combine with GET /pipelines to first discover available pipelines and
          their IDs.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /pipelines/{pipelineId}/steps/{stepId}:
    put:
      tags:
        - Pipeline Steps
      summary: Update a pipeline step
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
        - name: stepId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                order:
                  type: integer
                color:
                  type: string
                  enum:
                    - '#000000'
                    - black
                  description: Step color
                addEndHours:
                  type: integer
                  enum:
                    - null
                    - 1
                    - 2
                    - 3
                    - 4
                    - 5
                    - 6
                    - 8
                    - 9
                    - 10
                  description: Add number of hours or null
                notifyIn:
                  type: string
                  enum:
                    - '0'
                    - 15min
                    - 30min
                    - 1h
                    - 2h
                    - 3h
                    - 6h
                    - 12h
                    - 24h
                    - 2d
                    - 3d
                    - 4d
                    - 5d
                    - 6d
                    - 7d
                  description: Time notification
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Step'
      operationId: updatePipelineStep
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Modifies the configuration of an existing step within a CRM sales
        pipeline. Pipeline steps define deal progression stages — changes to
        order, color, timing, or notifications affect the pipeline board layout
        and the sales team's awareness of all deals currently residing in this
        step.
      x-ai-reasoning-instructions:
        - >-
          Before updating, verify the step exists in the target pipeline to
          avoid operating on stale IDs.
        - >-
          Changing `order` reshuffles stage sequence — confirm with the user if
          this is intentional, as it alters the logical deal flow for the entire
          pipeline.
        - >-
          `addEndHours` extends the deal's deadline automatically when a deal
          enters this step; setting it to null disables auto-extension — make
          sure the user understands the timing implications.
        - >-
          `notifyIn` triggers a reminder relative to deal end time; choose a
          value proportional to the stage urgency (e.g., shorter intervals for
          closing stages, longer for early qualification).
        - >-
          The `color` field impacts visual differentiation on the board —
          suggest meaningful color conventions (e.g., red for blocked, green for
          won-pending).
      x-ai-responding-instructions:
        - >-
          Confirm the update by referencing both pipelineId and stepId so the
          user can verify the correct step was modified.
        - >-
          If timing fields (addEndHours, notifyIn) were changed, explicitly note
          the impact on deal deadline tracking and sales team notifications.
        - >-
          If order was changed, advise the user to review adjacent steps to
          ensure the full pipeline sequence remains logically consistent.
      x-ai-suggestions:
        - >-
          After updating, fetch the pipeline steps list to verify the new
          configuration reflects correctly.
        - >-
          If multiple steps need reordering, update them sequentially to avoid
          order conflicts.
      x-ai-capabilities:
        confirmation:
          type: Soft
          reason: >-
            Modifying step configuration affects all deals currently in this
            stage, including their deadline calculations and notification
            schedules.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Pipeline Steps
      summary: Delete a pipeline step
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
        - name: stepId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deletePipelineStep
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Permanently removes a single step from a pipeline, collapsing the
        workflow at that position. In CRM pipelines, steps define the sequential
        stages of a deal or contact journey — deleting one restructures the
        entire flow and may affect active records currently assigned to that
        step.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, check if any active deals or contacts are currently
          assigned to this step — deletion may leave them in an inconsistent
          state.
        - >-
          Confirm whether the pipeline has dependent automation rules or
          triggers tied to this step.
        - >-
          Warn the user that this action is irreversible and will permanently
          remove the step configuration.
      x-ai-responding-instructions:
        - Confirm successful deletion by referencing both pipelineId and stepId.
        - >-
          Suggest reviewing the remaining pipeline steps to ensure the workflow
          sequence is still logical.
        - >-
          If records were assigned to the deleted step, recommend reassigning
          them to an appropriate existing step.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            Deleting a pipeline step is irreversible. Confirm that no active
            records depend on this step before proceeding.
        security_info:
          data_handling:
            - IrreversibleDelete
            - ResourceStateUpdate
  /deals/get-list:
    post:
      tags:
        - Deals
      summary: Get deals list
      description: |
        "status" field values:
        0 = inactive
        1 = active
        2 = fail
        3 = success
      requestBody:
        $ref: '#/components/requestBodies/DealFilter'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/Deal'
                  meta:
                    type: object
                    properties:
                      total:
                        type: integer
                      searchRequest:
                        type: string
      operationId: getDealsList
      x-ai-role: crm_pipeline_analyst
      x-ai-description: >-
        Retrieves a filtered, paginated list of deals from the CRM pipeline.
        This is the primary discovery endpoint for deal management — it allows
        agents to assess pipeline health, segment deals by status, and determine
        which records need action. Status semantics: 0=inactive, 1=active,
        2=failed, 3=successful.
      x-ai-reasoning-instructions:
        - >-
          Before filtering, clarify which pipeline stage or status the user is
          targeting — ambiguous requests like 'show my deals' should default to
          active (status=1).
        - >-
          Use `meta.total` to detect large result sets and proactively suggest
          pagination or narrower filters.
        - >-
          Status values are numeric: always map human-readable terms (e.g.,
          'won', 'lost', 'open') to their numeric equivalents before calling.
        - >-
          If the user wants analytics or aggregates, note that this endpoint
          returns raw list data — recommend client-side aggregation or follow-up
          calls.
      x-ai-responding-instructions:
        - >-
          Summarize the result by count and status distribution rather than
          dumping the raw list.
        - >-
          Highlight any deals that appear stalled (e.g., active deals with no
          recent update) if date fields are present.
        - >-
          Mention `meta.total` vs returned count to inform the user if results
          were truncated.
        - >-
          Suggest follow-up actions such as updating a specific deal or
          filtering by a narrower criterion.
      x-ai-suggestions:
        - Filter by status=1 to list all active deals currently in progress.
        - Filter by status=3 to review successfully closed deals for reporting.
        - >-
          Combine with responsible manager or pipeline filters to scope results
          to a specific team member.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /deals:
    post:
      tags:
        - Deals
      summary: Create a new deal
      description: Creates a new deal
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                pipelineId:
                  type: integer
                  description: >-
                    Pipeline ID where you need to create a deal. It can be
                    obtained with the "Get a list of pipelines" method
                stepId:
                  type: integer
                  description: >-
                    Pipeline step ID in which you want to create a deal. It can
                    be obtained with the methods "Get a list of pipelines" and
                    "Get information about a pipeline by ID"
                responsibleId:
                  type: integer
                  description: >-
                    Team member ID to assign to a deal. It can be obtained with
                    the "Get a list of team members" method
                name:
                  type: string
                  description: Deal name. The maximum number of characters is 255
                price:
                  type: number
                  description: Deal amount
                currency:
                  type: string
                  description: Deal currency. Accepts values in the form of UAH, USD, EUR
                sourceId:
                  type: integer
                  description: Custom source ID of the deal from an external source
                contact:
                  description: Deal contact
                  type: array
                  items:
                    type: integer
                    description: >-
                      Contact ID of the deal. It can be obtained with the method
                      "Get contact list"
                attributes:
                  description: ''
                  items:
                    properties:
                      attributeId:
                        type: integer
                        description: Attribute ID
                      value:
                        type: string
                        description: Attribute value
                attachments:
                  type: array
                  items:
                    type: string
                  example:
                    - /personal/deal/sendPulse_crm_deals.csv
                  description: >-
                    First, the file must be uploaded to the file manager, and
                    then the file can be attached.
              required:
                - pipelineId
                - stepId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Deal'
      operationId: createDeal
      x-ai-role: crm_sales_pipeline_manager
      x-ai-description: >-
        Creates a new deal within a specific pipeline and step. A deal is the
        central entity in SendPulse CRM, representing a potential sale or
        business opportunity. Its placement in a pipeline step defines the
        current stage of the sales process. Proper initialization — with the
        right pipeline, step, responsible team member, and contact — is critical
        for accurate pipeline reporting and follow-up automation.
      x-ai-reasoning-instructions:
        - >-
          Before creating, verify that the pipelineId and stepId are valid and
          belong to the same pipeline using 'Get a list of pipelines'.
        - >-
          If the user provides a contact name instead of a contact ID, resolve
          it first with 'Get contact list'.
        - >-
          If responsibleId is not provided, clarify who should own the deal —
          unassigned deals are often overlooked in sales workflows.
        - >-
          Validate that the currency value is one of the accepted formats: UAH,
          USD, EUR — reject other values early.
        - >-
          If attachments are provided, ensure the files have been uploaded to
          the file manager first and the paths are correct.
        - >-
          If attributes are provided, confirm the attributeId values are valid
          custom attributes defined for deals.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by surfacing the new deal ID from the
          response data.
        - >-
          Mention the pipeline and step the deal was placed in so the user can
          verify placement.
        - If responsible team member was assigned, confirm the assignment.
        - >-
          Suggest next steps such as adding a note, scheduling a follow-up
          activity, or moving the deal to the next pipeline step.
        - >-
          If an error occurs due to missing pipelineId or stepId, guide the user
          to fetch pipelines first.
      x-ai-suggestions:
        - New Lead from Website
        - Enterprise Contract Q2
        - Upsell Opportunity — Existing Client
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /deals/{dealId}:
    get:
      tags:
        - Deals
      summary: Get information about the deal by ID
      description: >-
        Returns information about the specified deal: deal ID, ID of a pipeline
        where the deal was created, at what stage the deal is now, team member
        responsible for the deal, deal amount, deal creation source, list of
        notes and fields
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID for which you need to get information. You can get it in the
            "Get a list of deals" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealDetailed'
      operationId: getDeal
      x-ai-role: crm_pipeline_analyst
      x-ai-description: >-
        Retrieves full context of a single deal entity — its current pipeline
        stage, responsible team member, monetary value, creation source, and all
        associated notes and custom fields. This is the primary read operation
        for deal inspection before any update, assignment, or stage transition.
      x-ai-reasoning-instructions:
        - >-
          Obtain the dealId from a prior `getDeals` call if the user hasn't
          provided it explicitly.
        - >-
          Use this endpoint before any update operation to confirm the current
          stage and owner to avoid overwriting stale data.
        - >-
          If the response includes custom fields, map them to their semantic
          meaning using the pipeline schema context.
        - >-
          Check the responsible team member field when routing follow-up actions
          or notifications.
      x-ai-responding-instructions:
        - >-
          Highlight the deal's current pipeline stage and responsible person as
          the most actionable summary.
        - >-
          Present the deal amount prominently if the user is evaluating revenue
          impact.
        - >-
          If notes are present, summarize their content rather than listing raw
          data.
        - >-
          Suggest logical next steps based on the current stage (e.g., advance
          stage, reassign, add a note).
      x-ai-suggestions:
        - >-
          Use the returned `pipeline_id` and stage to call the update deal
          endpoint and advance the deal.
        - >-
          Cross-reference `responsible_id` with the team member list to get
          contact details.
        - Review attached notes to understand deal history before taking action.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - Deals
      summary: Update information about a deal by its ID
      description: >-
        Updates information in the specified deal. Provided property values will
        be overwritten
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID to be updated. You can get it in the "Get a list of deals"
            method
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                pipelineId:
                  type: integer
                  description: >-
                    Pipeline ID in which the deal is located. It can be obtained
                    with the method "Get a list of pipelines"
                status:
                  type: integer
                  description: ''
                stepId:
                  type: integer
                  description: >-
                    ID of a pipeline step where you need to place a deal. It can
                    be obtained from the methods "Get a list of pipelines" and
                    "Get information about a pipeline by its ID"
                responsibleId:
                  type: integer
                  description: >-
                    Team member ID to assign to a deal. It can be obtained with
                    the "Get a list of team members" method
                name:
                  type: string
                  description: Deal name
                price:
                  type: number
                  description: Deal amount
                currency:
                  type: string
                  description: Deal currency. Accepts values in the form of UAH, USD, EUR
                sourceId:
                  type: integer
                  description: Custom source ID of the deal from an external source
                order:
                  type: integer
                  description: >-
                    Field display order. If empty, the deal will be placed at
                    the top of the list.
              required:
                - pipelineId
                - status
                - stepId
                - name
                - price
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Deal'
      operationId: updateDealById
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Updates mutable properties of an existing deal in the CRM pipeline. This
        is the primary mutation endpoint for deal lifecycle management — it
        controls not only metadata (name, price, currency) but also pipeline
        placement (stepId) and ownership (responsibleId). Partial updates are
        NOT supported: omitting required fields will cause validation errors, so
        always fetch the current deal state before modifying.
      x-ai-reasoning-instructions:
        - >-
          Before updating, call the 'Get a list of deals' or 'Get deal by ID'
          method to retrieve the current state and avoid accidentally
          overwriting unintended fields.
        - >-
          Validate that pipelineId and stepId are consistent — the step must
          belong to the specified pipeline. Fetch pipelines first if unsure.
        - >-
          When changing status, be aware that certain status transitions may
          have business implications (e.g., marking as won/lost may trigger
          automations).
        - >-
          If reassigning responsibleId, confirm the team member exists via 'Get
          a list of team members' before submitting.
        - >-
          Currency must be one of the accepted values (UAH, USD, EUR) — do not
          pass ISO codes outside this set.
        - >-
          The 'order' field controls visual position in the pipeline board;
          omitting it places the deal at the top.
      x-ai-responding-instructions:
        - Confirm which fields were changed and their new values.
        - >-
          If the step or pipeline changed, highlight the new position of the
          deal in the pipeline.
        - >-
          Suggest next logical actions such as adding a contact to the deal,
          logging an activity, or updating custom fields.
        - >-
          If a validation error occurs, identify which required field is missing
          and suggest how to obtain its value.
      x-ai-suggestions:
        - >-
          Fetch the current deal with 'Get deal by ID' before updating to
          preserve unchanged fields.
        - >-
          Use 'Get a list of pipelines' to resolve valid pipelineId and stepId
          combinations.
        - Use 'Get a list of team members' to resolve a valid responsibleId.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This operation overwrites existing deal data. Confirm the updated
            values before submitting.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Deals
      summary: Delete a deal by its ID
      description: Deletes the selected deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: Deal ID to delete
          schema:
            type: integer
      responses:
        '204':
          description: ''
      operationId: deleteDeal
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Permanently removes a deal from the CRM pipeline. This is a destructive,
        irreversible action — the deal record, its stage history, and any
        associated metadata will be lost. Typically used for duplicate cleanup,
        test data removal, or archiving closed pipelines.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm that the dealId exists and belongs to the
          current account to avoid 404 errors.
        - >-
          Warn the user that deletion is permanent — there is no soft-delete or
          recycle bin for deals.
        - >-
          If the deal is linked to contacts or tasks, advise the user to review
          those relationships before proceeding.
        - >-
          Ask for explicit confirmation if the agent is acting autonomously,
          since this action cannot be undone.
      x-ai-responding-instructions:
        - >-
          Confirm successful deletion by acknowledging the dealId that was
          removed.
        - >-
          If the response is 204 (No Content), clearly state that the deal was
          deleted and no further data was returned.
        - >-
          If a 404 error occurs, clarify that the deal may have already been
          deleted or the ID is incorrect.
        - >-
          Suggest verifying the pipeline state by listing remaining deals after
          deletion.
      x-ai-suggestions:
        - >-
          Use `getDeals` first to confirm the dealId before calling this
          endpoint.
        - >-
          Consider updating the deal status to 'lost' or 'closed' instead of
          deleting, to preserve historical data.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete deal #{dealId}. This action cannot be
            undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /deals/{dealId}/change-pipeline:
    post:
      tags:
        - Deals
      summary: Change the pipeline of a deal by its ID.
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID to be updated. You can get it in the "Get a list of deals"
            method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                pipelineId:
                  type: integer
                  description: >-
                    Pipeline ID to which the deal will be moved. It can be
                    obtained with the method "Get a list of pipelines"
                stepId:
                  type: integer
                  description: >-
                    ID of a pipeline step where you need to place a deal. It can
                    be obtained from the methods "Get a list of pipelines" and
                    "Get information about a pipeline by its ID"
      responses:
        '200':
          description: OK
      operationId: changeDealPipeline
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Transfers a deal to a different pipeline and optionally places it at a
        specific step. This is a structural operation in CRM — pipelines
        represent sales processes or workflows, and moving a deal between them
        signals a fundamental shift in its lifecycle (e.g., from 'New Business'
        to 'Renewal' or from 'Standard' to 'Enterprise'). The step placement
        determines the deal's starting point within the new pipeline's stages.
      x-ai-reasoning-instructions:
        - >-
          Before moving, retrieve the target pipeline via 'Get a list of
          pipelines' to confirm it exists and understand its stages.
        - >-
          If stepId is not provided, clarify whether the deal should land on the
          first step of the new pipeline or if a specific step is intended.
        - >-
          Verify that the stepId belongs to the specified pipelineId — placing a
          deal on a step from a different pipeline will cause an error.
        - >-
          Consider the business implication: moving a deal between pipelines may
          reset or affect automation rules, notifications, or stage-based
          triggers in the new pipeline.
      x-ai-responding-instructions:
        - >-
          Confirm the move by stating the deal ID, the destination pipeline name
          (if known), and the step name (if known).
        - >-
          If only pipelineId was provided without stepId, note that the deal was
          placed at the default entry point of the pipeline.
        - >-
          Suggest reviewing the deal's new stage and updating relevant fields
          (e.g., expected close date, assigned user) to match the new pipeline's
          context.
      x-ai-suggestions:
        - >-
          Retrieve pipeline list first using 'Get a list of pipelines' to find
          the correct pipelineId and stepId.
        - >-
          Use 'Get information about a pipeline by its ID' to inspect available
          steps before moving the deal.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Moving a deal to a different pipeline may affect automations and
            stage history. Confirm the target pipeline and step before
            proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
  /deals/{dealId}/comments:
    get:
      tags:
        - Deal notes
      summary: Get a list of deal notes
      description: >-
        Returns a list of notes with information about each: ID, author, message
        and status
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID for which you want to get the list of notes. It can be
            obtained with the "Get a list of deals" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealComment'
      operationId: getDealComments
      x-ai-role: crm_sales_analyst
      x-ai-description: >-
        Retrieves the full annotation history for a specific deal — notes left
        by team members during the sales process. In SendPulse CRM, deal
        comments serve as an internal audit trail and collaboration layer: they
        capture objections, agreements, follow-up intentions, and status
        rationale that are not reflected in structured deal fields. Reading this
        thread before taking action on a deal gives the agent the context needed
        to act consistently with the team's prior decisions.
      x-ai-reasoning-instructions:
        - >-
          Resolve dealId first — use 'Get a list of deals' if the user refers to
          a deal by name or company rather than numeric ID.
        - >-
          Before summarizing or acting on a deal, fetch its comments to avoid
          repeating questions the team has already addressed.
        - >-
          If the response contains many comments, identify the most recent ones
          as most likely to reflect current deal status.
        - >-
          Check the 'status' field on each comment to distinguish active notes
          from archived or deleted ones.
      x-ai-responding-instructions:
        - >-
          Present comments in chronological order, attributing each to its
          author.
        - >-
          Highlight any comment that signals a blocking issue or an explicit
          next step.
        - >-
          If no comments exist, inform the user and suggest adding a note to
          start the collaboration thread.
        - >-
          Avoid exposing raw IDs in the user-facing summary — use author names
          and timestamps for readability.
      x-ai-suggestions:
        - >-
          Use the returned comment list to brief a teammate before they take
          ownership of the deal.
        - >-
          After reviewing comments, consider calling the 'Add a deal note'
          endpoint to record the latest update.
        - Combine with deal details to produce a full deal status report.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Deal notes
      summary: Add a note to a deal
      description: Adds a note to the specified deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            ID of the deal for which you want to add a note. It can be obtained
            with the "Get a list of deals" method
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                message:
                  type: string
                  description: Note message. The maximum number of characters is 65,535
              required:
                - message
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealComment'
      operationId: addDealComment
      x-ai-role: crm_sales_specialist
      x-ai-description: >-
        Adds a contextual note to a specific deal in the CRM pipeline. Notes
        serve as an internal communication layer — they capture negotiation
        context, decisions, and follow-up intent that is not reflected in deal
        fields alone. This endpoint is critical for maintaining deal history and
        team coordination across the sales cycle.
      x-ai-reasoning-instructions:
        - >-
          Verify that the dealId exists before attempting to add a note; use
          'Get a list of deals' to retrieve valid IDs.
        - >-
          Encourage the user to be specific and actionable in the note — e.g.,
          'Called client, confirmed budget, follow up on Friday' rather than
          vague entries.
        - >-
          Check that the message does not exceed 65,535 characters; warn the
          user if the input is unusually long.
        - >-
          Consider whether the note should reference a next action or outcome to
          maximize its utility in sales tracking.
      x-ai-responding-instructions:
        - >-
          Confirm that the note was successfully added by referencing the deal
          ID.
        - >-
          Suggest reviewing the full deal timeline or adding a follow-up task as
          the next step.
        - >-
          If the deal ID is invalid or not found, clearly communicate that the
          user should first retrieve valid deal IDs.
      x-ai-suggestions:
        - Called client — confirmed interest, sending proposal by EOD.
        - >-
          Meeting scheduled for next Tuesday. Budget approved at management
          level.
        - Deal stalled — client requested 2-week delay. Re-engage on 2026-04-07.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /deals/{dealId}/comments/{commentId}:
    put:
      tags:
        - Deal notes
      summary: Update a note to a deal
      description: >-
        Updates the selected note in the specified deal. Existing values will be
        overwritten
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            ID of the deal for which you want to update a note. It can be
            obtained with the "Get a list of deals" method
          schema:
            type: integer
        - name: commentId
          in: path
          required: true
          description: >-
            ID of the note to be updated. It can be obtained with the "Get a
            list of deal notes" method
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                message:
                  type: string
                  description: New note message. The maximum number of characters is 65,535
              required:
                - message
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealComment'
      operationId: updateDealComment
      x-ai-role: crm_deal_management_specialist
      x-ai-description: >-
        Updates the text of an existing note attached to a specific deal. Notes
        serve as an internal audit trail and communication layer for deal
        progression — correcting a note preserves the accuracy of the deal's
        history without creating redundant entries.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the commentId belongs to the specified dealId
          to avoid cross-deal mutations.
        - >-
          Verify the new message is not empty and does not exceed 65,535
          characters.
        - >-
          If the user wants to preserve the old text, suggest fetching the note
          first via 'Get a list of deal notes' before overwriting.
      x-ai-responding-instructions:
        - >-
          Confirm the note was successfully updated and reference the commentId
          that was changed.
        - >-
          Remind the user that the previous message content has been permanently
          overwritten.
        - >-
          Suggest reviewing all notes for the deal if the user is auditing deal
          activity.
      x-ai-suggestions:
        - >-
          Fetch existing note content with 'Get a list of deal notes' before
          overwriting.
        - >-
          After updating, use 'Get a list of deal notes' to verify the change
          was applied correctly.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently overwrite the existing note. Confirm before
            proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - DataLoss
    delete:
      tags:
        - Deal notes
      summary: Remove a note from the deal
      description: Removes a note from the specified deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            ID of the deal from which you want to remove a note. It can be
            obtained with the "Get a list of deals" method
          schema:
            type: integer
        - name: commentId
          in: path
          required: true
          description: >-
            ID of the note to be removed. It can be obtained with the "Get a
            list of deal notes" method
          schema:
            type: integer
      responses:
        '204':
          description: ''
      operationId: deleteDealComment
      x-ai-role: crm_deal_manager
      x-ai-description: >-
        Permanently removes a note (comment) from a deal record. Notes in CRM
        deals serve as an audit trail and communication log for the sales team.
        Deletion is irreversible — once removed, the note cannot be recovered.
        Use with caution when cleaning up outdated or erroneous annotations on a
        deal.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm with the user which specific note is to be
          removed — retrieve the list via 'Get a list of deal notes' if the
          commentId is unknown.
        - >-
          Warn the user that this action is irreversible and the note cannot be
          restored after deletion.
        - >-
          Verify that both dealId and commentId belong to the same deal to avoid
          accidental deletion of notes from other deals.
      x-ai-responding-instructions:
        - >-
          Confirm the successful deletion by referencing the removed commentId
          and the associated dealId.
        - >-
          If a 404 error occurs, clarify whether the dealId or commentId is
          invalid and suggest using the respective list endpoints to verify IDs.
        - Suggest reviewing remaining notes on the deal as a follow-up action.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete note #{commentId} from deal #{dealId}.
            This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /deals/{dealId}/contacts:
    get:
      tags:
        - Deal contacts
      summary: Get a list of contacts in a deal
      description: Returns a list of contacts in the specified deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID for which you want to get the list of contacts. It can be
            obtained with the "Get a list of deals" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Contact'
      operationId: getDealContacts
      x-ai-role: crm_sales_specialist
      x-ai-description: >-
        Retrieves all contacts associated with a specific deal in the CRM
        pipeline. A deal in SendPulse CRM can have multiple contacts linked to
        it — this endpoint exposes that relationship, enabling agents to
        understand who the stakeholders are in a given sales opportunity before
        taking further action (e.g., sending follow-ups or updating contact
        data).
      x-ai-reasoning-instructions:
        - >-
          Ensure the dealId is valid before calling — use 'Get a list of deals'
          to obtain it if not already known.
        - >-
          If the response returns an empty array, inform the user that no
          contacts are linked to this deal yet and suggest adding contacts.
        - >-
          Consider whether the user needs full contact details — this endpoint
          returns contact objects, but related endpoints may provide richer
          profile data.
      x-ai-responding-instructions:
        - >-
          List the contacts by name (or identifier) returned in the response for
          clarity.
        - >-
          If multiple contacts are returned, summarize the count and highlight
          key identifiers.
        - >-
          Suggest logical next steps such as updating contact info, sending a
          campaign, or viewing the deal details.
      x-ai-suggestions:
        - >-
          Use the returned contact IDs to fetch full contact profiles via the
          Contacts endpoints.
        - >-
          Cross-reference these contacts with mailing lists to check if they are
          already subscribed.
        - >-
          If no contacts are found, use the 'Add contact to deal' endpoint to
          link relevant contacts.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /deals/{dealId}/contacts/{contactId}:
    post:
      tags:
        - Deal contacts
      summary: Add a contact to a deal
      description: Adds a previously created contact to the specified deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID in which you want to add the contact. It can be obtained
            with the "Get a list of deals" method
          schema:
            type: integer
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID you want to add to the deal. It can be obtained with the
            "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '201':
          description: ''
      operationId: addContactToDeal
      x-ai-role: crm_pipeline_specialist
      x-ai-description: >-
        Links an existing contact to a specific deal, establishing a
        relationship between a person and a sales opportunity. This is a
        structural association endpoint — both the contact and the deal must
        already exist. It is typically used after deal creation to assign
        responsible parties, prospects, or stakeholders to the pipeline item.
      x-ai-reasoning-instructions:
        - >-
          Verify that the deal exists before attempting to link — use 'Get a
          list of deals' to confirm dealId is valid.
        - >-
          Verify that the contact exists before linking — use 'Get a list of
          contacts' to confirm contactId.
        - >-
          Check whether the contact is already associated with this deal to
          avoid duplicate associations.
        - >-
          Consider whether the contact's role in the deal (prospect,
          decision-maker, stakeholder) should be tracked separately via a
          dedicated field or note.
      x-ai-responding-instructions:
        - >-
          On success (201), confirm which contact was linked to which deal by
          referencing both IDs.
        - >-
          Suggest reviewing the deal's full contact list as a follow-up using
          the appropriate GET endpoint.
        - >-
          If a 404 or validation error occurs, clarify which resource (deal or
          contact) was not found and guide the user to retrieve the correct ID.
      x-ai-suggestions:
        - >-
          First retrieve available deals via 'Get a list of deals', then
          contacts via 'Get a list of contacts' before calling this endpoint.
        - >-
          After linking, consider adding a note or task to the deal to document
          the contact's role.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - RelationshipCreate
    delete:
      tags:
        - Deal contacts
      summary: Delete a contact from a deal
      description: Removes the contact from the specified deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID from which you want to remove the contact. It can be
            obtained with the "Get a list of deals" method
          schema:
            type: integer
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID you want to remove from the deal. It can be obtained with
            the "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: ''
      operationId: removeDealContact
      x-ai-role: crm_deal_manager
      x-ai-description: >-
        Disassociates a contact from a deal without deleting either entity. Use
        this when a person is no longer relevant to a specific sales opportunity
        — for example, when a stakeholder changes or a contact was added by
        mistake. The deal and contact continue to exist independently.
      x-ai-reasoning-instructions:
        - >-
          Confirm the dealId is valid by cross-referencing with 'Get a list of
          deals' before attempting removal.
        - >-
          Confirm the contactId is currently associated with the specified deal
          to avoid misleading 404 errors.
        - >-
          Warn the user that this action only unlinks the contact from the deal
          — it does not delete the contact from the CRM.
        - >-
          If the user intends to remove the last contact from a deal, note that
          the deal may become ownerless or harder to track.
      x-ai-responding-instructions:
        - >-
          On success (204), confirm that the contact has been unlinked from the
          deal, not deleted.
        - >-
          If the deal or contact is not found, clarify which ID caused the issue
          and suggest how to retrieve valid IDs.
        - >-
          Suggest using 'Get a list of deal contacts' to verify the updated
          contact list after removal.
      x-ai-suggestions:
        - >-
          Use 'Get a list of deals' to retrieve a valid dealId before calling
          this endpoint.
        - Use 'Get a list of contacts' to retrieve a valid contactId.
        - >-
          After removal, call the deal contacts list endpoint to confirm the
          association no longer exists.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will remove the contact from the deal. The contact record
            itself will not be deleted.
        security_info:
          data_handling:
            - RelationshipDelete
  /pipelines/{pipelineId}/attributes:
    get:
      tags:
        - Deal Attributes
      summary: Get deal attributes list
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttribute'
      operationId: listPipelineAttributes
      x-ai-role: crm_pipeline_specialist
      x-ai-description: >-
        Retrieves the full set of custom deal attributes defined for a specific
        pipeline. In SendPulse CRM, each pipeline can have its own schema of
        deal fields — these attributes define what structured data can be
        captured per deal (e.g., budget, priority, custom labels). Knowing the
        attribute schema is a prerequisite before creating or updating deals.
      x-ai-reasoning-instructions:
        - >-
          Always call this endpoint before attempting to create or update a deal
          in the pipeline — attribute IDs are required for setting custom field
          values.
        - >-
          Verify that the provided pipelineId exists and is accessible to the
          current account before making the request.
        - >-
          Cache the attribute list for a pipeline session if multiple deal
          operations will follow, to avoid redundant calls.
      x-ai-responding-instructions:
        - >-
          Present the returned attributes as a structured list with their IDs
          and names, so the user can identify which fields are available.
        - >-
          If the list is empty, inform the user that no custom attributes are
          configured for this pipeline and suggest adding them via CRM settings.
        - >-
          Highlight required attributes (if indicated) to help the user
          understand mandatory fields when creating deals.
      x-ai-suggestions:
        - >-
          Use returned attribute IDs when calling createDeal or updateDeal to
          populate custom field values.
        - >-
          If attributes are missing, navigate to the CRM pipeline settings to
          define them before proceeding.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Deal Attributes
      summary: Create a deal attribute
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                type:
                  type: integer
                  description: >-
                    0 = Text, 1 = Number, 2 = Date, 3 = Link, 4 = Select, 5 =
                    MultiSelect
                mandatory:
                  type: boolean
                options:
                  type: array
                  items:
                    oneOf:
                      - type: string
                      - type: integer
              required:
                - name
                - pipelineId
                - type
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttribute'
      operationId: createPipelineAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        This endpoint extends the data schema of a specific CRM pipeline by
        defining a custom attribute for deals. Deal attributes act as typed
        metadata fields that shape how deals are captured, validated, and
        reported on. The `type` field determines the UI control and validation
        logic — selecting the wrong type for a field (e.g., Text instead of Date
        for a close date) causes downstream issues in filters, reporting, and
        automations. Mandatory fields enforce data completeness at deal creation
        time.
      x-ai-reasoning-instructions:
        - >-
          Confirm the target pipeline exists by its `pipelineId` before
          attempting to create an attribute.
        - >-
          Map the user's intent to the correct `type` integer: 0=Text, 1=Number,
          2=Date, 3=Link, 4=Select, 5=MultiSelect.
        - >-
          If `type` is 4 (Select) or 5 (MultiSelect), the `options` array is
          required — prompt the user for option values if not provided.
        - >-
          Avoid creating duplicate attribute names within the same pipeline;
          advise checking existing attributes first.
        - >-
          Use `mandatory: true` only for fields that are genuinely required for
          every deal — overuse creates friction in data entry.
      x-ai-responding-instructions:
        - >-
          Confirm the attribute was created by echoing its name and type in
          human-readable form (e.g., 'Date' instead of '2').
        - >-
          If type is Select or MultiSelect, list the registered options back to
          the user.
        - >-
          Suggest populating deals with the new attribute or reviewing pipeline
          attribute order as a next step.
        - >-
          If the pipeline is not found or validation fails, explain which field
          caused the error and how to fix it.
      x-ai-suggestions:
        - 'Expected Close Date (type: 2, mandatory: true)'
        - >-
          Deal Source (type: 4, options: ['Inbound', 'Outbound', 'Referral',
          'Partner'])
        - 'Contract Value (type: 1, mandatory: true)'
        - 'Product Tags (type: 5, options: [''SaaS'', ''Enterprise'', ''Trial''])'
        - 'Demo URL (type: 3)'
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - SchemaModification
            - ResourceStateUpdate
  /pipelines/{pipelineId}/attributes/{attributeId}:
    put:
      tags:
        - Deal Attributes
      summary: Update a deal attribute
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                type:
                  type: integer
                  description: >-
                    0 = Text, 1 = Number, 2 = Date, 3 = Link, 4 = Select, 5 =
                    MultiSelect
                mandatory:
                  type: boolean
                order:
                  type: integer
                status:
                  type: integer
                  description: 0 = Inactive, 1 = Active, 2 = Hidden
                options:
                  type: array
                  items:
                    oneOf:
                      - type: string
                      - type: integer
              required:
                - name
                - order
                - pipelineId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttribute'
      operationId: updatePipelineAttribute
      x-ai-role: sales_operations_specialist
      x-ai-description: >-
        Updates a deal attribute definition within a specific pipeline, allowing
        reconfiguration of the deal data model — its display name, field type,
        visibility, sort order, and whether it is mandatory. Attribute structure
        changes propagate immediately to all deals in the pipeline, so type or
        mandatory-status edits can affect data integrity and form behavior
        across the entire sales workflow.
      x-ai-reasoning-instructions:
        - >-
          Before updating, verify both the pipelineId and attributeId exist; a
          missing pipeline or attribute returns an error.
        - >-
          Warn the user if changing the `type` field on an attribute that
          already has values stored — type changes (e.g., Text → Number) may
          corrupt or discard existing deal data.
        - >-
          If `mandatory` is being set to `true`, check whether existing deals
          already have this attribute populated; unpopulated mandatory fields
          can block deal save operations.
        - >-
          When `type` is 4 (Select) or 5 (MultiSelect), `options` must be
          provided; omitting them leaves the field unusable.
        - >-
          Use `order` to place the attribute logically relative to sibling
          attributes — confirm the desired position with the user if not
          explicitly specified.
        - >-
          Setting `status` to 0 (Inactive) or 2 (Hidden) hides the attribute
          from the deal form but preserves stored data.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were changed and echo back the updated attribute
          name and type for clarity.
        - >-
          If `type` was changed, proactively warn that existing deal data for
          this attribute may be affected.
        - >-
          If `mandatory` was enabled, suggest reviewing open deals for
          compliance.
        - >-
          Suggest using `getPipelineAttributes` to verify the full updated
          attribute list after the change.
      x-ai-suggestions:
        - >-
          Set status to 2 (Hidden) instead of deleting the attribute to preserve
          historical deal data.
        - >-
          Use descriptive names like 'Expected Close Date' or 'Contract Value
          (USD)' for clarity across the team.
        - >-
          For Select/MultiSelect types, provide a complete and final list of
          options — partial lists confuse users filling in deals.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Modifying attribute type or mandatory status affects all existing
            deals in this pipeline. Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PotentialDataLoss
    delete:
      tags:
        - Deal Attributes
      summary: Delete a deal attribute
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deletePipelineAttribute
      x-ai-role: crm_pipeline_administrator
      x-ai-description: >-
        Permanently removes a custom attribute definition from a pipeline. This
        is a schema-level operation — it deletes the attribute field itself, not
        just a value. Any deal data stored under this attribute across all
        pipeline deals will be lost.
      x-ai-reasoning-instructions:
        - >-
          Confirm the attributeId belongs to the specified pipelineId before
          proceeding — cross-pipeline deletions are not valid.
        - >-
          Warn the user that this operation is irreversible and will erase all
          stored values for this attribute across every deal in the pipeline.
        - >-
          Check if the attribute is used in any automation, filter, or report
          before deletion — removing it may silently break dependent logic.
        - >-
          Prefer archiving or disabling an attribute over deletion if the user
          is unsure.
      x-ai-responding-instructions:
        - >-
          Confirm deletion with the attributeId and pipelineId that were
          affected.
        - >-
          Explicitly note that all deal-level data for this attribute has been
          permanently removed.
        - >-
          Suggest reviewing pipeline deal views or automations that may have
          referenced this attribute.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete the attribute and all associated deal
            data. This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - CascadingDataLoss
  /deals/{dealId}/attributes:
    get:
      tags:
        - Deal attribute Value
      summary: Get deal attribute values by ID
      description: >-
        Returns a list of attributes with ID, types, and values in the specified
        deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID for which you want to get the fields. It can be obtained
            with the "Get a list of deals" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttributeValue'
      operationId: getDealAttributeValues
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves the full set of custom and system attribute values attached to
        a specific deal. In SendPulse CRM, deal attributes are the structured
        fields that define a deal's stage-specific data — prices, sources,
        priorities, or any custom fields configured per pipeline. This endpoint
        is the primary way to inspect a deal's enriched profile before updating,
        qualifying, or reporting on it.
      x-ai-reasoning-instructions:
        - >-
          Ensure the dealId is valid by cross-referencing it with the 'Get a
          list of deals' response before calling this endpoint.
        - >-
          Use the returned attribute types to determine correct value casting —
          numeric fields must not be treated as strings in downstream logic.
        - >-
          If the goal is to update attributes, first call this endpoint to
          retrieve current values and avoid accidental overwrites.
        - >-
          Consider that some attributes may be pipeline-specific — their
          presence depends on how the CRM pipeline is configured.
      x-ai-responding-instructions:
        - >-
          Present attribute values in a structured, human-readable format
          grouped by attribute type.
        - >-
          Highlight attributes with null or empty values as potential data gaps
          the user should address.
        - >-
          If the user is inspecting a deal for qualification, suggest which
          attributes are typically most critical (e.g., value, stage, source).
        - >-
          On error (e.g., deal not found), clearly indicate that the dealId may
          be incorrect or the deal may have been deleted.
      x-ai-suggestions:
        - Use this before `updateDealAttributeValues` to get current state.
        - Combine with 'Get a list of deals' to build a full deal audit report.
        - >-
          Useful for validating data completeness before moving a deal to the
          next pipeline stage.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Deal attribute Value
      summary: Add a attribute value to deal by deal ID
      description: Adds a attribute with the specified value and ID to the deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID to which you want to add the field. It can be obtained with
            the "Get a list of deals" method
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                attributeId:
                  type: integer
                  description: >-
                    Attribute ID you want to add to the deal. It can be obtained
                    with the "Get a list of deals" and "Get information about
                    the deal by ID" methods
                value:
                  type: string
                  description: >-
                    Attribute value to be added to the deal. The maximum number
                    of characters is 5500
              required:
                - attributeId
                - value
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttributeValue'
      operationId: addDealAttribute
      x-ai-role: crm_data_specialist
      x-ai-description: >-
        Attaches a custom attribute value to a specific deal, extending its data
        model beyond standard fields. In SendPulse CRM, deal attributes act as
        flexible metadata — they allow teams to capture domain-specific
        information (e.g., contract terms, priority scores, product SKUs)
        directly on the deal record without modifying the core schema.
      x-ai-reasoning-instructions:
        - >-
          Retrieve the target deal first via 'Get a list of deals' or 'Get
          information about the deal by ID' to confirm both the dealId and
          available attributeId values.
        - >-
          Verify the attribute type before setting a value — some attributes may
          expect formatted strings (dates, URLs, enums).
        - >-
          Respect the 5500-character limit on value; truncate or split content
          if the source data exceeds it.
        - >-
          Avoid duplicate attribute assignments — check existing attribute
          values on the deal before adding.
      x-ai-responding-instructions:
        - >-
          Confirm which attribute was added and to which deal by echoing back
          the dealId and attribute name (if known).
        - >-
          If the response contains a DealAttributeValue object, surface its ID
          for future reference or update operations.
        - >-
          If the attributeId is invalid or not found, explain that the ID must
          be retrieved from the deal or attribute list endpoints.
      x-ai-suggestions:
        - >-
          Use 'Get information about the deal by ID' first to see which
          attributes are already attached.
        - >-
          After adding, call the deal details endpoint again to verify the
          attribute appears correctly.
        - >-
          For bulk updates, repeat this call per attribute rather than batching
          — each attribute requires its own request.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /deals/attributes/{pipelineId}:
    get:
      tags:
        - Deal attribute Value
      summary: List of all deal attribute values by pipeline
      parameters:
        - name: pipelineId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttribute'
      operationId: listDealAttributesByPipeline
      x-ai-role: crm_pipeline_analyst
      x-ai-description: >-
        Retrieves all custom attribute values defined for deals within a
        specific pipeline. Deal attributes are pipeline-scoped metadata fields
        (e.g., dropdowns, checkboxes, text fields) that extend the default deal
        schema. This endpoint is essential for dynamically rendering deal forms,
        validating attribute values before deal creation or update, and building
        conditional automation logic based on pipeline-specific field
        configurations.
      x-ai-reasoning-instructions:
        - >-
          Resolve the pipelineId before calling — verify the pipeline exists and
          the agent has access to it.
        - >-
          Use the returned attribute list to validate deal field values before
          creating or updating a deal in this pipeline.
        - >-
          If multiple pipelines are involved, call this endpoint per pipeline —
          attribute sets are not shared across pipelines.
        - >-
          Cache the response short-term if making multiple deal operations
          within the same pipeline context to avoid redundant calls.
      x-ai-responding-instructions:
        - >-
          Present the attributes grouped by type (e.g., text, select, boolean)
          for readability.
        - >-
          If the list is empty, inform the user that no custom attributes are
          configured for this pipeline and suggest creating them.
        - >-
          When used as a prerequisite step, confirm which attribute IDs or keys
          will be needed for the follow-up operation.
      x-ai-suggestions:
        - >-
          Use returned attribute definitions to populate a deal creation form
          dynamically.
        - >-
          Cross-reference attribute IDs with deal records to enrich exported
          reports.
        - Call `listPipelines` first if the pipelineId is unknown.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /deals/{dealId}/attributes/{attributeId}:
    put:
      tags:
        - Deal attribute Value
      summary: Update the deal attribute value
      description: >-
        Updates the deal attribute with the new value. Existing values will be
        overwritten.
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            The deal ID for which you want to update the attribute. It can be
            obtained with the "Get a list of deals" method
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          description: >-
            The attribute ID you want update. It can be obtained with the "Get a
            list of deals" and "Get information about the deal by ID" methods
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                value:
                  type: string
                  description: >-
                    New attribute value. The maximum number of characters is
                    5500
              required:
                - value
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealAttributeValue'
      operationId: updateDealAttributeValue
      x-ai-role: crm_data_specialist
      x-ai-description: >-
        Updates a single custom attribute value on a specific deal. This is a
        targeted write operation — it fully overwrites the existing value,
        making it suitable for corrections, status progressions, or syncing deal
        metadata from external systems. Attribute values are key data points
        used for filtering, reporting, and pipeline automation in CRM workflows.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the dealId and attributeId are valid — both
          can be retrieved via 'Get a list of deals' or 'Get information about
          the deal by ID'.
        - >-
          Warn the user that this operation overwrites the existing value with
          no diff or history preserved — verify the new value is intentional.
        - >-
          If the value represents a date, currency, or enum, validate the format
          matches what the attribute schema expects to avoid silent data
          corruption.
        - >-
          If updating multiple attributes on the same deal, perform requests
          sequentially to avoid race conditions.
      x-ai-responding-instructions:
        - >-
          Confirm which deal and which attribute were updated by echoing back
          dealId and attributeId.
        - >-
          If the response includes the updated DealAttributeValue object,
          highlight the new value that was applied.
        - >-
          If the operation is part of a bulk update flow, suggest proceeding to
          the next attribute in the sequence.
        - >-
          On error, clarify whether the issue is an invalid dealId, invalid
          attributeId, or a value constraint violation (e.g., exceeding 5500
          characters).
      x-ai-suggestions:
        - >-
          Fetch current attribute values first using 'Get information about the
          deal by ID' before overwriting.
        - >-
          Use this endpoint to sync deal stage or score from an external system
          into SendPulse CRM.
        - >-
          After updating, retrieve the deal again to confirm the attribute
          reflects the new value.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will overwrite the existing attribute value. Confirm the new
            value before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - DataOverwrite
    delete:
      tags:
        - Deal attributes
      summary: Remove the deal attribute
      description: Removes the attribute from the specified deal
      parameters:
        - name: dealId
          in: path
          required: true
          description: >-
            Deal ID from which you want to delete the field. It can be obtained
            with the "Get a list of deals" method
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          description: >-
            Attribute ID you want delete. It can be obtained with the "Get a
            list of deals" and "Get information about the deal by ID" methods
          schema:
            type: integer
      responses:
        '204':
          description: ''
      operationId: deleteDealAttribute
      x-ai-role: crm_data_integrity_specialist
      x-ai-description: >-
        Removes a specific custom attribute from a deal without deleting the
        deal itself. Use this when a field is no longer relevant to a particular
        deal — for example, after a stage transition makes certain data
        obsolete. This operation affects only the deal-attribute association,
        not the attribute definition globally.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm the attributeId belongs to the specified
          dealId — mismatched IDs will result in a 404.
        - >-
          Verify whether the attribute holds data the user may want to preserve
          before removal, as this action is irreversible.
        - >-
          If the user wants to remove an attribute from all deals, this endpoint
          must be called per deal individually — there is no bulk variant.
        - >-
          Distinguish between removing an attribute value (this endpoint) and
          deleting the attribute definition globally.
      x-ai-responding-instructions:
        - >-
          Confirm the attribute was successfully removed from the deal (204 No
          Content means success).
        - >-
          Remind the user that this does not delete the attribute definition —
          it only dissociates it from this deal.
        - >-
          If the user seems to want to clean up multiple deals, suggest
          iterating over the deal list and calling this endpoint per deal.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the attribute from the deal. The
            attribute definition will remain intact. Proceed?
        security_info:
          data_handling:
            - ResourceStateUpdate
            - IrreversibleDelete
  /messenger-types:
    get:
      tags:
        - Messengers types
      summary: Get a list of messengers
      description: Returns a list of types of available messengers for contacts
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/MessengerType'
      operationId: getMessengerTypes
      x-ai-role: omnichannel_communication_specialist
      x-ai-description: >-
        Returns the catalog of messenger channels available on the account. This
        is a discovery endpoint — it must be called before any
        messenger-specific operation to confirm which channels (e.g., Telegram,
        WhatsApp, Facebook) are active and can be used for contact segmentation
        or campaign targeting.
      x-ai-reasoning-instructions:
        - >-
          Call this endpoint first when the user asks to send a message or
          create a campaign via a specific messenger — confirm the channel is
          available before proceeding.
        - >-
          Use the returned type identifiers as valid values when filtering
          contacts by messenger or constructing messenger-specific payloads.
        - >-
          If the list is empty or a desired messenger is missing, inform the
          user that the channel may not be connected to their account.
      x-ai-responding-instructions:
        - >-
          List the available messengers by name in a human-readable format, not
          just raw IDs.
        - >-
          If the user was looking for a specific messenger and it is absent,
          suggest connecting it via account settings.
        - >-
          Mention that these types can be used to filter contacts or scope
          campaigns to a specific channel.
      x-ai-suggestions:
        - >-
          Use returned messenger type IDs when calling contact list or campaign
          endpoints that require a `messenger_type` parameter.
        - >-
          Cross-reference with connected integrations in the account if an
          expected messenger is missing.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /payments/all:
    get:
      tags:
        - Payments
      summary: Get a list of payments by user
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/UserPaymentData'
                  total:
                    type: integer
      operationId: getAllPayments
      x-ai-role: financial_analyst
      x-ai-description: >-
        Retrieves the full payment history for the authenticated user account.
        Use this endpoint to audit billing activity, reconcile charges, or
        surface subscription and top-up events. The response includes a pageable
        dataset and a total count, making it suitable for building financial
        dashboards or automated billing reports.
      x-ai-reasoning-instructions:
        - >-
          Consider whether the user needs the full history or a filtered subset
          — if date or status filters are available as query params, prefer them
          to reduce payload size.
        - >-
          Use the `total` field to determine if pagination is required before
          presenting results.
        - >-
          If the result set is large, summarize key metrics (total spend, latest
          payment date) rather than listing every record.
      x-ai-responding-instructions:
        - >-
          Present the total number of payments alongside the first few records
          for context.
        - >-
          Highlight the most recent payment and its status if visible in the
          data.
        - >-
          If the list is empty, suggest that the account may be new or that no
          charges have been made yet.
      x-ai-suggestions:
        - Use this endpoint before generating an invoice or billing summary.
        - >-
          Combine with a date-range filter if available to scope monthly or
          quarterly reports.
        - >-
          Cross-reference with subscription endpoints to map payments to
          specific plan changes.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
            - SensitiveFinancialData
  /payments/deals/{dealId}:
    get:
      tags:
        - Payments
      summary: Get a list of payments by dealId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/Payment'
                  total:
                    type: integer
      operationId: getDealPayments
      x-ai-role: crm_payments_analyst
      x-ai-description: >-
        Retrieves the full payment history associated with a specific CRM deal.
        Useful for financial reconciliation, deal progress tracking, and
        validating whether a deal has been fully paid, partially paid, or is
        outstanding.
      x-ai-reasoning-instructions:
        - >-
          Verify the dealId exists before querying — an invalid ID will return
          an empty result or error.
        - >-
          Use the `total` field to determine if pagination is needed when the
          dataset is large.
        - >-
          Cross-reference payment statuses to assess the financial health of the
          deal.
        - >-
          If no payments are returned, consider whether the deal is at an early
          pipeline stage.
      x-ai-responding-instructions:
        - Summarize the total number of payments found using the `total` field.
        - >-
          Highlight key payment fields such as amount, status, and date if
          available.
        - >-
          If the list is empty, suggest verifying the dealId or checking if
          payments have been recorded for this deal.
        - >-
          Suggest follow-up actions like creating a payment or updating deal
          status if relevant.
      x-ai-suggestions:
        - Use this endpoint to verify payment completion before closing a deal.
        - >-
          Combine with deal details endpoint to get a full financial picture of
          the deal.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /payments/contacts/{contactId}:
    get:
      tags:
        - Payments
      summary: Get a list of payments by contactId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/Payment'
                  total:
                    type: integer
      operationId: getPaymentsByContactId
      x-ai-role: payments_analyst
      x-ai-description: >-
        Retrieves the full payment history for a specific contact by their
        unique ID. Useful for auditing transaction activity, detecting billing
        anomalies, or building financial summaries per customer in CRM or
        analytics workflows.
      x-ai-reasoning-instructions:
        - >-
          Verify that the contactId is valid and the contact exists before
          making the call.
        - >-
          Use the `total` field in the response to determine if pagination is
          needed for contacts with large transaction histories.
        - >-
          Consider filtering or sorting results on the client side if the API
          does not support query-level filters.
      x-ai-responding-instructions:
        - Summarize the total number of payments found using the `total` field.
        - >-
          Highlight the most recent or largest payment if relevant to the user's
          context.
        - >-
          If no payments are returned, clarify whether the contact exists but
          has no transaction history.
      x-ai-suggestions:
        - Use this endpoint to audit payment activity before issuing a refund.
        - >-
          Combine with contact profile data to build a full customer financial
          overview.
        - >-
          Check `total` to decide whether to paginate or display all results at
          once.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
            - SensitiveFinancialData
  /contacts/get-list:
    post:
      tags:
        - Contacts
      summary: Get contacts list
      requestBody:
        content:
          application/json:
            schema:
              properties:
                limit:
                  type: integer
                  minimum: 1
                  maximum: 100
                offset:
                  type: integer
                  minimum: 0
                from:
                  type: string
                  format: date
                  description: >-
                    Contact creation date, filter start date. Accepted format
                    YYYY-MM-DD
                to:
                  type: string
                  format: date
                  description: >-
                    Contact creation date, filter end date. Accepted format
                    YYYY-MM-DD
                updateFrom:
                  type: string
                  format: date
                  description: >-
                    Contact updated date, filter start date. Accepted format
                    YYYY-MM-DD
                updateTo:
                  type: string
                  format: date
                  description: >-
                    Contact updated date, filter end date. Accepted format
                    YYYY-MM-DD
                firstName:
                  type: string
                  description: Contacts first name you want to search for
                lastName:
                  type: string
                  description: Contacts last name you want to search for
                responsibleIds:
                  type: array
                  description: >-
                    A list with the ID of users assigned to the contact you want
                    to to search for. It can be obtained with the "Get a list of
                    team members" method
                  items:
                    type: integer
                sourceType:
                  type: array
                  items:
                    type: integer
                    enum:
                      - 1
                      - 2
                      - 3
                      - 4
                      - 5
                      - 6
                      - 8
                      - 9
                      - 10
                phone:
                  type: string
                  description: Phone number of a contact
                email:
                  type: string
                tagIds:
                  type: array
                  items:
                    type: integer
                messengerTypeIds:
                  type: array
                  items:
                    type: integer
                messengerLogin:
                  type: string
                sortBy:
                  type: object
                  properties:
                    direction:
                      type: string
                      description: >-
                        Sorting direction. Possible values: asc — ascending
                        order; desc — descending order.
                      enum:
                        - asc
                        - desc
                    fieldName:
                      type: string
                      enum:
                        - id
                        - created_at
                        - first_name
                        - attributeId
                        - responsible_id
                      example: id
                attributes:
                  $ref: '#/components/schemas/AttributesProperty'
                location:
                  type: string
                fieldValueConditions:
                  type: array
                  items:
                    type: object
                    properties:
                      field:
                        type: string
                        description: Field name
                        enum:
                          - attributes
                          - lastName
                          - phones
                          - emails
                          - messengers
                          - location
                          - tags
                      expression:
                        type: string
                        description: >-
                          | Possible values:

                          - eq (=) - neq (!=) - gt (>) - gte (>=) - lt (<) - lte
                          (<=) - like - in (check among list of values).
                      value:
                        description: Can have array or string type
                ids:
                  type: array
                  description: Array of contacts IDs
                  items:
                    type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      list:
                        items:
                          $ref: '#/components/schemas/Contact'
                      total:
                        type: integer
                      searchRequest:
                        type: string
      operationId: getContactsList
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Powerful filtered search across the CRM contact base. Unlike a simple
        list fetch, this endpoint supports multi-dimensional filtering — by
        creation/update date ranges, assigned team members, source types, tags,
        messengers, custom attributes, and field-level conditions. Used to build
        segmented views, audit contact data, or feed downstream automation with
        a precise contact subset.
      x-ai-reasoning-instructions:
        - >-
          Combine filters additively — all provided conditions are applied
          simultaneously (AND logic), so overly specific combinations may return
          empty results.
        - >-
          Use `from`/`to` for filtering by creation date and
          `updateFrom`/`updateTo` for recently modified contacts — do not mix up
          the two date ranges.
        - >-
          When filtering by `responsibleIds`, first call 'Get a list of team
          members' to resolve names to IDs.
        - >-
          Paginate using `limit` (max 100) and `offset` — for large datasets,
          iterate until `total` is exhausted.
        - >-
          If `fieldValueConditions` is used, ensure `field` names match the
          schema enum — typos cause silent empty results.
        - >-
          For sorting by a custom attribute, use `attributeId` as `fieldName`
          and provide the actual attribute ID.
        - >-
          When the user describes a search intent in natural language, map it to
          the most specific available filters before falling back to broad ones.
      x-ai-responding-instructions:
        - >-
          Report the total count from `searchRequest` or `total` field alongside
          the list — it helps the user understand whether they got all results
          or need to paginate.
        - >-
          If the result list is empty, suggest reviewing the filter combination
          — one overly restrictive condition is often the cause.
        - >-
          When returning a subset of a large dataset, remind the user to
          paginate with `offset` to retrieve remaining records.
        - >-
          If the user searched by a specific filter (e.g., tag, responsible),
          confirm which filter was applied and how many contacts matched.
      x-ai-suggestions:
        - >-
          Filter contacts created in the last 30 days using `from`/`to` date
          range.
        - >-
          Use `tagIds` + `messengerTypeIds` together to find contacts reachable
          via a specific channel with a given tag.
        - Sort by `created_at` descending to get the newest contacts first.
        - >-
          Use `fieldValueConditions` with `expression: like` for partial
          name/email matching when exact values are unknown.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /contacts/get-list-by-email:
    post:
      tags:
        - Contacts
      summary: Search contacts by email
      description: >-
        Returns contacts and the following information about each: the contact
        ID, the assigned person and the contact information
      requestBody:
        content:
          application/json:
            schema:
              properties:
                email:
                  type: string
                  description: Email address of a contact
                isEmailFullSearch:
                  type: boolean
                  description: >-
                    Search for emails that match completely or partially
                    (true/false)
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      list:
                        description: List with contacts
                        type: array
                        items:
                          $ref: '#/components/schemas/Contact'
                      total:
                        description: Total number of filtered records for pagination
                        type: integer
      operationId: getContactListByEmail
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Performs a lookup of CRM contacts by email address, returning full
        contact records including assigned responsible persons and contact
        details. Useful for deduplication checks, pre-call research, and
        verifying whether a lead already exists before creating a new one. The
        partial-match mode makes it effective for domain-level searches (e.g.,
        finding all contacts from a company).
      x-ai-reasoning-instructions:
        - >-
          If the user provides a full email address, default isEmailFullSearch
          to true to avoid unrelated results.
        - >-
          When the user wants to find all contacts from a domain (e.g.,
          '@company.com'), set isEmailFullSearch to false for partial matching.
        - >-
          Before creating a new contact, suggest running this search first to
          prevent duplicates.
        - >-
          Use the returned total field to determine if pagination is needed — if
          total exceeds the returned list size, advise the user to paginate.
      x-ai-responding-instructions:
        - >-
          Report how many contacts were found (use the total field, not the list
          length).
        - >-
          If a single exact match is found, surface the contact ID and assigned
          person prominently.
        - >-
          If no contacts are found, suggest trying partial search
          (isEmailFullSearch: false) or verifying the email spelling.
        - >-
          If multiple contacts are returned, summarize them as a list with ID,
          name, and assigned person.
      x-ai-suggestions:
        - >-
          Use isEmailFullSearch: false to find all contacts sharing an email
          domain.
        - >-
          Combine results with getContact to retrieve full contact details by
          ID.
        - Run this before createContact to enforce uniqueness within the CRM.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /contacts:
    post:
      deprecated: true
      tags:
        - Contacts
      summary: (Deprecated). Use POST /contacts/create instead to create a new contact
      description: >-
        Creates a contact with the given properties and returns a copy of the
        information, including the ID
      requestBody:
        content:
          application/json:
            schema:
              properties:
                responsibleId:
                  type: integer
                  description: >-
                    Team member ID to assign to a contact. It can be obtained
                    with the "Get a list of team members" method
                firstName:
                  type: string
                  description: Contact first name
                lastName:
                  type: string
                  description: Contact last name
                phones:
                  type: array
                  description: List of phone numbers in the international format
                  items:
                    type: string
                emails:
                  type: array
                  description: List of email addresses
                  items:
                    type: string
                tags:
                  type: array
                  description: >-
                    List of tag IDs to be added to a contact. It can be obtained
                    with the "Get a list of contact tags" method
                  items:
                    type: integer
                attributes:
                  type: array
                  description: >
                    List of fields to add to the contact. Pass in the attributes
                    field array an object with the attributeId and value fields
                    (will create a contact with an already existing attribute)
                    Pass in the attributes field

                    array an object with the name, type , value fields (will
                    create a contact with a new attribute

                    if there is no such attribute yet or create a contact with
                    an existing attribute if the attribute already exists)'
                  items:
                    properties:
                      name:
                        type: string
                        description: Attribute name
                      value:
                        type: string
                        description: Attribute value
                      type:
                        type: integer
                        description: >-
                          0 - text, 1 - number, 2 - date, 3 - link, 4 - select ,
                          5 - multiSelect
                    required:
                      - name
                      - value
                messengers:
                  type: array
                  description: List of messengers to add to a contact
                  items:
                    properties:
                      typeId:
                        $ref: '#/components/schemas/MessengerTypeProperty'
                      login:
                        type: string
                        description: Contacts login in the specified messenger
                    required:
                      - typeId
                      - login
                attachments:
                  type: array
                  items:
                    type: string
                  description: >-
                    First, the file must be uploaded to the file manager, and
                    then the file can be attached.
                  example:
                    - /personal/deal/sendPulse_crm_deals.csv
              required:
                - responsibleId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Contact'
      operationId: createContact
      x-ai-role: crm_data_entry_specialist
      x-ai-description: >-
        Deprecated endpoint for creating a CRM contact with full profile data
        including phones, emails, messengers, custom attributes, and file
        attachments. Replaced by POST /contacts/create — use that instead for
        all new integrations. This endpoint remains for backward compatibility
        only.
      x-ai-reasoning-instructions:
        - >-
          This endpoint is deprecated — always redirect the user to POST
          /contacts/create unless they explicitly need backward compatibility.
        - >-
          Before creating, consider checking for duplicate contacts by phone or
          email to avoid data pollution in the CRM.
        - >-
          The `responsibleId` is required — ensure the team member ID is
          obtained via the 'Get a list of team members' method before calling.
        - >-
          For `attributes`, clarify whether existing attributes (by
          `attributeId`) or new ones (by `name`+`type`) are intended — the
          behavior differs.
        - >-
          File attachments must be pre-uploaded via the file manager; raw file
          data cannot be passed directly.
        - >-
          Messenger `typeId` must reference a valid enum value — confirm the
          correct messenger type before constructing the payload.
      x-ai-responding-instructions:
        - >-
          Warn the user that this endpoint is deprecated and recommend migrating
          to POST /contacts/create.
        - >-
          On success, highlight the new contact ID from the returned
          `data.Contact` object.
        - >-
          If attributes were created as new (by name), note that they are now
          persistent CRM attributes shared across contacts.
        - >-
          Suggest following up with assigning the contact to a deal or pipeline
          stage as a next logical step.
      x-ai-suggestions:
        - Use POST /contacts/create for all new contact creation workflows.
        - >-
          Retrieve valid `responsibleId` values via GET /team before calling
          this endpoint.
        - Retrieve valid tag IDs via GET /contacts/tags before assigning tags.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Creating a contact will persist it in the CRM and may trigger
            automations or assignments.
        security_info:
          data_handling:
            - ResourceStateCreate
            - PersonalDataStorage
  /contacts/create:
    post:
      tags:
        - Contacts
      summary: Create a new contact
      description: Creates a contact
      requestBody:
        content:
          application/json:
            schema:
              properties:
                responsibleId:
                  type: integer
                  description: >-
                    Team member ID to assign to a contact. It can be obtained
                    with the "Get a list of team members" method
                firstName:
                  type: string
                  description: Contact first name
                lastName:
                  type: string
                  description: Contact last name
                externalContactId:
                  type: string
                  description: >-
                    External contact ID field for services data - we do not
                    recommend using it to add an ID from third-party systems
              required:
                - responsibleId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Contact'
      operationId: createContact
      x-ai-role: crm_specialist
      x-ai-description: >-
        Initializes a new contact record in the CRM. A contact is the
        foundational entity in SendPulse CRM — assigning a responsible team
        member at creation time ensures immediate ownership and enables
        automated routing, task assignment, and follow-up pipelines from the
        first interaction.
      x-ai-reasoning-instructions:
        - >-
          Before creating, verify the responsibleId is valid by
          cross-referencing with the 'Get a list of team members' endpoint.
        - >-
          Avoid using externalContactId for third-party system IDs as it is not
          recommended — suggest alternative approaches if the user intends to
          map external records.
        - >-
          If both firstName and lastName are omitted, warn the user that the
          contact will be anonymous, which may hinder identification later.
        - >-
          Check whether a contact with the same name or external ID might
          already exist to prevent duplicates.
      x-ai-responding-instructions:
        - >-
          Confirm creation by surfacing the new contact's ID from the returned
          Contact object.
        - >-
          Suggest populating the contact with additional data (phone, email,
          deals) as an immediate next step.
        - >-
          If the responsibleId is invalid, explain that the value must come from
          the team members list and guide the user to retrieve it.
      x-ai-suggestions:
        - >-
          Use 'Get a list of team members' to obtain a valid responsibleId
          before calling this endpoint.
        - >-
          After creation, use 'Create a deal' to associate a sales opportunity
          with the new contact.
        - >-
          Consider adding tags or custom fields immediately after creation to
          enrich the contact profile.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataStorage
  /contacts/{contactId}:
    get:
      tags:
        - Contacts
      summary: Get information about a contact by ID
      description: >-
        Returns the following information on the specified contact: ID, team
        member responsible for the contact, first and Contacts last name, number
        of deals of the contact, list of phone numbers and email addresses, and
        messengers of the contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to get information. It can be obtained
            with the "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Contact'
      operationId: getContactById
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves a complete profile of a single CRM contact by their unique ID.
        This is the primary lookup endpoint for building contact detail views,
        pre-filling forms before edits, or resolving a contact reference
        obtained from a list or deal. The response aggregates identity,
        ownership, communication channels, and deal history into one call —
        avoiding multiple round-trips.
      x-ai-reasoning-instructions:
        - >-
          Ensure the contactId was obtained from a trusted source such as
          `getContacts` or a deal's contact reference — do not guess or
          construct IDs.
        - >-
          If the previous call returned a list, extract the correct ID before
          calling this endpoint.
        - >-
          Check whether the caller needs only basic identity info or full
          channel data; this endpoint returns both, so no supplemental calls are
          needed.
        - >-
          If the response is needed to pre-fill an edit form, cache it locally
          to avoid redundant requests.
      x-ai-responding-instructions:
        - >-
          Present the contact's full name, responsible team member, and contact
          channels (phone, email, messengers) in a structured, readable format.
        - >-
          Highlight the number of associated deals to give the user a quick
          sense of the contact's activity level.
        - >-
          If the contact has multiple phone numbers or emails, list all of them
          clearly — do not omit secondary entries.
        - >-
          Suggest logical next steps such as updating the contact, viewing
          associated deals, or initiating communication.
      x-ai-suggestions:
        - >-
          Use `getContacts` first to search by name or email and obtain the
          contactId.
        - >-
          After retrieving the contact, you can update their data with the
          corresponding PATCH /contacts/{contactId} endpoint.
        - >-
          To see deals linked to this contact, query the deals endpoint filtered
          by this contactId.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - Contacts
      summary: Update information about the contact
      description: Update information about specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID of the contact whose information you want to update. It
            can be obtained with the "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                responsibleId:
                  type: integer
                  description: >-
                    Team member ID to assign to a contact. It can be obtained
                    with the "Get a list of team members" method
                firstName:
                  type: string
                  description: Contact first name
                lastName:
                  type: string
                  description: Contact last name
              required:
                - responsibleId
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Contact'
      operationId: updateContact
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Updates mutable fields of an existing CRM contact record. This is the
        primary mutation endpoint for keeping contact profiles accurate —
        ownership reassignment (responsibleId) is mandatory, making it suitable
        for both data corrections and responsibility handoffs between team
        members.
      x-ai-reasoning-instructions:
        - >-
          Retrieve the contactId first via 'Get a list of contacts' if not
          already known — never guess or fabricate IDs.
        - >-
          responsibleId is required; confirm the target team member exists via
          'Get a list of team members' before calling.
        - >-
          If only name fields are changing, still supply the current
          responsibleId to avoid unintended ownership transfer.
        - >-
          Warn the user if they are reassigning a contact to a different team
          member, as this affects pipeline visibility and notifications.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated and reflect the new values back to
          the user.
        - >-
          If responsibleId changed, explicitly mention the ownership transfer
          and to whom.
        - >-
          Suggest fetching the updated contact via 'Get contact details' to
          verify the full record state.
        - >-
          On 404, clarify that the contactId may be invalid or the contact may
          have been deleted.
      x-ai-suggestions:
        - >-
          Use 'Get a list of team members' to resolve a name to a valid
          responsibleId before calling.
        - >-
          Combine with 'Get a list of contacts' to batch-update contacts by
          segment.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Confirm before reassigning contact ownership, as it affects team
            workload distribution.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Contacts
      summary: Remove contact by ID
      description: Removes the specified contact by ID
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID to be removed. It can be obtained with the "Get a list of
            contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactById
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Permanently removes a contact record from the system by its unique
        identifier. This is a hard-delete operation — the contact and all
        associated data (tags, custom fields, activity history) are irreversibly
        erased. Use when a contact explicitly opts out under GDPR/CCPA or when
        cleaning up test/duplicate records.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm with the user that this is intentional —
          deletion is irreversible and cannot be undone.
        - >-
          Verify the contactId exists by calling the 'Get a list of contacts'
          method if the ID was not obtained in the current session.
        - >-
          Check whether the contact is currently enrolled in active automations
          or campaigns — deletion mid-flow may cause broken sequences.
        - >-
          If the intent is GDPR/CCPA erasure, ensure this call is part of a
          broader data-removal workflow (e.g., also remove from mailing lists).
      x-ai-responding-instructions:
        - Confirm deletion with the contactId that was removed.
        - >-
          Remind the user that this action is permanent and the contact cannot
          be restored.
        - >-
          If the use case is compliance-driven, suggest verifying removal across
          all related resources (lists, automations, CRM deals).
        - >-
          On 404, clarify that the contact may have already been deleted or the
          ID is incorrect.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete contact #{contactId}. This action
            cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - PiiDataRemoval
  /contacts/{contactId}/deals:
    get:
      tags:
        - Contacts
      summary: Get all deals that related to contact
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: deals list
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/Deal'
      operationId: getContactDeals
      x-ai-role: crm_sales_analyst
      x-ai-description: >-
        Retrieves the full list of deals associated with a specific contact,
        providing a 360-degree view of the sales relationship. Use this to
        assess pipeline health for an individual contact, identify stalled
        deals, or understand a contact's purchase history before outreach.
      x-ai-reasoning-instructions:
        - >-
          Verify the contactId is valid before calling — an incorrect ID returns
          an empty dataset or 404, not an error.
        - >-
          Consider whether the user wants all deals or a filtered subset; this
          endpoint returns all, so post-filter by status if needed.
        - >-
          If the result set is empty, distinguish between 'contact exists but
          has no deals' and 'contact not found' scenarios for the user.
      x-ai-responding-instructions:
        - >-
          Summarize the deals by status (e.g., open, won, lost) rather than
          listing raw data.
        - >-
          Highlight any deals in critical stages (e.g., negotiation, closing)
          that may require immediate action.
        - >-
          If no deals are found, suggest creating a deal with the relevant
          create-deal endpoint.
      x-ai-suggestions:
        - >-
          Use the returned deal IDs to fetch individual deal details or update
          deal stages.
        - >-
          Cross-reference with contact activity to prioritize follow-ups on
          stalled deals.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /contacts/{contactId}/comments:
    post:
      tags:
        - Contacts
      summary: Add a note to a contact
      description: Adds a note to the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID to which you want to add a note. It can be obtained with
            the "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                message:
                  type: string
                  minLength: 1
                  description: Note message. The maximum number of characters is 65,535
              required:
                - message
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactComment'
      operationId: addContactComment
      x-ai-role: crm_relationship_manager
      x-ai-description: >-
        Adds a persistent internal note to a specific CRM contact. Notes serve
        as a chronological communication log visible only to team members — not
        the contact — enabling context sharing between agents, support staff,
        and sales reps across interactions.
      x-ai-reasoning-instructions:
        - >-
          Verify the contactId is valid before submitting — use 'Get a list of
          contacts' if the ID is uncertain.
        - >-
          Notes are internal only; never use this endpoint to send a message to
          the contact.
        - >-
          Ensure the message is meaningful and actionable — generic notes reduce
          CRM signal quality.
        - >-
          Check that the message length does not exceed 65,535 characters before
          sending.
      x-ai-responding-instructions:
        - >-
          Confirm the note was added successfully and reference the contact it
          was attached to.
        - >-
          If the contactId is not found, suggest retrieving the correct ID via
          the contacts list endpoint.
        - >-
          Suggest adding follow-up notes or scheduling a task as a logical next
          step.
      x-ai-suggestions:
        - >-
          Called on 2024-03-15, expressed interest in premium plan — follow up
          next week.
        - 'Support ticket #4821 resolved. Customer confirmed satisfaction.'
        - Do not send promotional emails — opted out verbally during call.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /contacts/{contactId}/comments/{commentId}:
    put:
      tags:
        - Contacts
      summary: Update contact note
      description: >-
        Updates the note of the specified contact. Provided property values will
        be overwritten.
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID contact for which you want to update the note. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: commentId
          in: path
          required: true
          description: >-
            Note ID you want to update. It can be obtained with the "Get a list
            of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                message:
                  type: string
                  minLength: 1
                  description: New note message. The maximum number of characters is 65,535
              required:
                - message
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactComment'
      operationId: updateContactComment
      x-ai-role: crm_data_quality_specialist
      x-ai-description: >-
        Updates the text of an existing note attached to a specific contact.
        Notes (comments) serve as internal team annotations — sales context,
        call outcomes, follow-up reminders. Overwriting is full replacement: any
        prior text is lost, so this action should be used deliberately.
      x-ai-reasoning-instructions:
        - >-
          Confirm the contactId and commentId are valid before sending — both
          can be retrieved from the 'Get a list of contacts' response.
        - >-
          Since the update fully overwrites the existing message, ask the user
          to confirm they have the current note content if they want to append
          rather than replace.
        - >-
          Check that the message does not exceed 65,535 characters before
          sending to avoid a validation error.
        - >-
          If the intent is to delete a note rather than update it, inform the
          user that a dedicated delete endpoint may exist.
      x-ai-responding-instructions:
        - >-
          Confirm success by referencing the contactId and commentId that were
          updated.
        - >-
          If the user appended text to the old note, remind them the old content
          is no longer stored.
        - >-
          Suggest reviewing the contact's full note history if multiple comments
          are being managed.
      x-ai-suggestions:
        - Spoke with client on 2024-03-20, moved to negotiation stage.
        - Follow-up scheduled for next week. Awaiting procurement approval.
        - Corrected entry — previous note contained outdated information.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          reason: >-
            Fully overwrites the existing note — previous content is permanently
            lost.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - IrreversibleOverwrite
    delete:
      tags:
        - Contacts
      summary: Remove contact note
      description: Removes a note of a specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to remove the note. It can be obtained
            with the "Get a list of contacts" method
          schema:
            type: integer
        - name: commentId
          in: path
          required: true
          description: >-
            Note ID you want to remove. It can be obtained with the "Get a list
            of contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactComment
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Permanently removes a specific note from a contact record. Notes store
        contextual history added by agents or users — deletion is irreversible
        and should be used for privacy cleanup, data correction, or removal of
        stale context that could mislead future interactions.
      x-ai-reasoning-instructions:
        - >-
          Confirm both contactId and commentId before proceeding — there is no
          recovery after deletion.
        - >-
          Check whether the note is referenced in any recent activity log or
          workflow before removing.
        - >-
          If the user wants to 'clear all notes', warn that this endpoint
          removes only one note at a time — loop carefully.
      x-ai-responding-instructions:
        - >-
          Confirm deletion by echoing both the contactId and commentId that were
          removed.
        - Mention that the action is irreversible and no backup exists.
        - >-
          Suggest using 'Get a list of contacts' to verify the note no longer
          appears if confirmation is needed.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently delete note {commentId} from contact
            {contactId}. This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /contacts/{contactId}/phones:
    post:
      tags:
        - Contact phone number
      summary: Add a phone number to the contact.
      description: Adds phone numbers to existing contacts
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID to add the phone to. Can be obtained in the "Get contact
            list" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                phone:
                  type: string
                  minLength: 1
                  maxLength: 50
                  description: ''
              required:
                - phone
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactPhone'
      operationId: addContactPhone
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Attaches a phone number to an existing CRM contact, extending their
        reachability profile. Phone numbers enable SMS, voice, and WhatsApp
        channel outreach — adding one transforms a contact from email-only to
        omnichannel.
      x-ai-reasoning-instructions:
        - >-
          Resolve the contactId first — use 'Get contact list' if you only have
          a name or email.
        - >-
          Validate the phone format before submitting: include country code
          (e.g., +380501234567). The API accepts up to 50 characters but does
          not normalize formats.
        - >-
          Check whether the contact already has a phone number to avoid
          duplicates — retrieve the contact record first if uncertain.
        - >-
          If adding phones in bulk, consider batching contact lookups rather
          than making one call per contact.
      x-ai-responding-instructions:
        - >-
          Confirm success by referencing the contactId and the phone number that
          was added.
        - >-
          If the response includes a ContactPhone object, surface the assigned
          phone ID for future reference.
        - >-
          On failure, distinguish between 'contact not found' (wrong contactId)
          and validation errors (malformed phone string).
        - >-
          Suggest enabling an SMS or WhatsApp channel for this contact as a
          logical next step.
      x-ai-suggestions:
        - '+380501234567'
        - '+14155552671'
        - '+447911123456'
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PII
  /contacts/{contactId}/phones/{phoneId}:
    put:
      tags:
        - Contact phone number
      summary: Update the phone number of the contact
      description: >-
        Updates the phone number of the specified contact. Provided property
        values will be overwritten.
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to update the phone number. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: phoneId
          in: path
          required: true
          description: >-
            The phone number ID you want to update. It can be obtained with the
            "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                phone:
                  type: string
                  minLength: 1
                  maxLength: 50
                  description: New phone number in the international format
              required:
                - phone
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactPhone'
      operationId: updateContactPhone
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Updates a specific phone number record tied to a CRM contact. Since
        SendPulse CRM supports multiple phone numbers per contact, this endpoint
        targets one precisely by phoneId — ensuring the right record is modified
        without affecting other contact data.
      x-ai-reasoning-instructions:
        - >-
          Retrieve the contact first via 'Get a list of contacts' to confirm
          both contactId and phoneId exist before attempting an update.
        - >-
          Validate the phone number format: it must be in international format
          (e.g., +380501234567). Reject or normalize local formats before
          calling this endpoint.
        - >-
          If the user provides only a local number, prompt them for the country
          code to construct a valid international format.
        - >-
          Be aware that overwrite semantics apply — the existing phone value
          will be fully replaced, not merged.
      x-ai-responding-instructions:
        - >-
          Confirm which phone number was updated and on which contact (include
          contactId and phoneId for traceability).
        - >-
          Show the new phone value from the response to let the user verify the
          change.
        - >-
          If the update affects a contact used in active campaigns or
          automations, warn the user that outreach may now target the new
          number.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contacts' first to discover the correct phoneId
          before calling this endpoint.
        - After updating, verify the change by re-fetching the contact record.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to overwrite the phone number for contact {contactId}.
            This action cannot be undone automatically.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataModification
    delete:
      tags:
        - Contact phone number
      summary: Delete phone number
      description: Removes the phone number from the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID from which you want to remove the phone number. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: phoneId
          in: path
          required: true
          description: >-
            Phone number ID you want to remove. It can be obtained with the "Get
            a list of contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactPhone
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Permanently removes a specific phone number from a contact's profile.
        Use this when a contact has changed their number, requested removal, or
        when deduplicating contact data. This action is irreversible — the phone
        number association is deleted from the system and cannot be restored
        without re-adding it manually.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm you have the correct phoneId — retrieve the
          contact's phone list first if uncertain.
        - >-
          Check whether this is the contact's only phone number; removing it may
          affect SMS campaign targeting.
        - >-
          Ensure the deletion is intentional and not a result of confusion
          between contactId and phoneId.
        - >-
          If the user wants to update (not delete) the number, suggest using the
          update endpoint instead.
      x-ai-responding-instructions:
        - >-
          Confirm the deletion was successful (HTTP 204 means no content
          returned — this is expected).
        - Remind the user that this action is irreversible.
        - >-
          If the contact had only one phone number, note that they are now
          unreachable via SMS campaigns.
        - >-
          Suggest verifying the contact's remaining phones via 'Get a list of
          contacts' if needed.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contacts' to retrieve both contactId and phoneId
          before calling this endpoint.
        - >-
          Consider updating the phone number instead of deleting if the goal is
          a correction.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently remove the phone number from the contact. This
            action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /contacts/{contactId}/emails:
    post:
      tags:
        - Contact email addresses
      summary: Add an email address to the contact
      description: Adds an email address to the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID to which you want to add the email address. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                emails:
                  type: array
                  items:
                    type: object
                    properties:
                      email:
                        type: string
                        minLength: 1
                        maxLength: 50
                        description: Email address to be added to the contact
                      isMain:
                        type: boolean
                        description: Determines whether the email address is the main one
              required:
                - email
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/ContactEmail'
      operationId: addContactEmails
      x-ai-role: crm_data_specialist
      x-ai-description: >-
        Extends a contact's communication profile by associating one or more
        email addresses. In SendPulse CRM, a contact can have multiple emails,
        with exactly one designated as primary — this drives which address is
        used in automated campaigns and follow-ups. Adding the wrong email as
        main can silently redirect all outbound communication.
      x-ai-reasoning-instructions:
        - >-
          Confirm the contactId exists before attempting the request — use 'Get
          a list of contacts' if uncertain.
        - >-
          Ensure at most one entry in the emails array has isMain: true; setting
          multiple as main is logically inconsistent.
        - >-
          If the user provides no isMain flag, default to false unless they
          explicitly state this should be the primary address.
        - >-
          Validate email format and length (max 50 chars) client-side before
          sending to avoid avoidable 4xx errors.
        - >-
          Ask the user whether the new email should replace the current main
          address or coexist as secondary.
      x-ai-responding-instructions:
        - >-
          Confirm which email(s) were added and whether any was set as the main
          address.
        - >-
          If isMain was set to true, note that outbound messaging for this
          contact will now use the new address.
        - >-
          Suggest verifying the contact's full email list using 'Get contact
          details' as a follow-up.
        - >-
          If the contact is part of active campaigns, warn that changing the
          main email may affect delivery targeting.
      x-ai-suggestions:
        - >-
          Set isMain: true only when replacing the primary communication address
          intentionally.
        - >-
          Batch multiple emails in a single request rather than making separate
          calls per address.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Confirm before setting a new main email — this affects all future
            outbound communication for this contact.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataWrite
  /contacts/{contactId}/emails/{emailId}:
    put:
      tags:
        - Contact email addresses
      summary: Update the email address of the contact
      description: Updates the email address of the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to update the email address. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: emailId
          in: path
          required: true
          description: >-
            Email address ID you want to update. It can be obtained with the
            "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                email:
                  type: string
                  minLength: 1
                  maxLength: 128
                  description: New email address
              required:
                - email
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactEmail'
      operationId: updateContactEmail
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Updates a specific email address record linked to a contact. This is a
        targeted mutation — it changes one of potentially many email entries for
        the contact without affecting other attributes or communication history.
        Critical for maintaining accurate deliverability when a subscriber
        changes their address.
      x-ai-reasoning-instructions:
        - >-
          Before updating, retrieve the contact's current emails via 'Get a list
          of contacts' to confirm the emailId belongs to the correct contactId.
        - >-
          Validate the new email format before sending — the API enforces 1–128
          chars, but also check for obvious typos (e.g., missing TLD).
        - >-
          Treat this as a destructive operation: once the address is replaced,
          the old value is gone — confirm intent with the user if acting
          autonomously.
        - >-
          If the contact has only one email and it is the primary one, warn that
          updating it may affect active campaigns or automations targeting that
          address.
      x-ai-responding-instructions:
        - >-
          Confirm which email was updated by referencing the emailId and the new
          address.
        - >-
          If the updated email is used in active campaigns, proactively mention
          potential impact on deliverability tracking.
        - >-
          On success, suggest verifying the contact record to ensure the change
          propagated correctly.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contacts' first to resolve both contactId and
          emailId before calling this endpoint.
        - >-
          After updating, call the contact detail endpoint to confirm the new
          address is reflected.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to replace an existing email address for this contact.
            This action cannot be undone automatically.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PII
    delete:
      tags:
        - Contact email addresses
      summary: Remove the email address from the contact
      description: Removes the email address from the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID from which you want to remove the email address. It can
            be obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: emailId
          in: path
          required: true
          description: >-
            Email address ID you want to delete. It can be obtained with the
            "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactEmail
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Permanently unlinks a specific email address from a contact record
        without deleting the contact itself. Use this when a contact changes
        their email, when an address becomes invalid, or when GDPR/compliance
        requires removal of a particular communication channel. The contact
        remains intact — only the email binding is severed.
      x-ai-reasoning-instructions:
        - >-
          Confirm that both contactId and emailId are valid and belong to the
          same contact before proceeding.
        - >-
          Warn the user if this is the contact's only email address — removing
          it may make the contact unreachable via email campaigns.
        - >-
          Consider whether the intent is to replace the email (use update flow
          instead) or permanently remove it.
        - >-
          Check if the email is currently used in active automations or campaign
          audience segments before deletion.
      x-ai-responding-instructions:
        - >-
          Confirm the email address was successfully removed and mention the
          affected contactId.
        - >-
          If this was the contact's last email, proactively suggest adding a new
          one via the appropriate endpoint.
        - >-
          For compliance-driven removals, note that the action is irreversible
          and suggest archiving contact data if needed.
      x-ai-suggestions:
        - >-
          After removal, use 'Get a list of contacts' to verify the updated
          email list for this contact.
        - >-
          To add a replacement email address, use the 'Add email to contact'
          endpoint.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently remove the email address from the contact.
            This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - PIIRemoval
  /contacts/{contactId}/messengers:
    post:
      tags:
        - Contacts messengers
      summary: Add messenger to contact
      description: Adds a messenger to the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID you want to add a mesenger to. It can be obtained with
            the "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                typeId:
                  $ref: '#/components/schemas/MessengerTypeProperty'
                login:
                  type: string
                  description: Contacts login in the specified messenger
                isMainChatbot:
                  type: boolean
                  description: Determine if chatbot messenger is the main one
              required:
                - typeId
                - login
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactMessenger'
      operationId: addContactMessenger
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Links a specific messenger account (e.g., Telegram, WhatsApp, Viber) to
        an existing CRM contact. This creates a multi-channel communication
        profile, enabling chatbot automation and targeted messaging through the
        contact's preferred messenger. Designating a main chatbot messenger is
        critical for routing automated sequences correctly.
      x-ai-reasoning-instructions:
        - >-
          Verify the contactId exists before attempting to add a messenger — use
          'Get a list of contacts' if the ID is unknown.
        - >-
          Check if the contact already has a messenger of the given typeId to
          avoid duplicates.
        - >-
          If isMainChatbot is true, be aware this may override the existing main
          chatbot messenger for the contact.
        - >-
          Validate that the login format matches the conventions of the
          specified messenger type (e.g., phone number for WhatsApp, username
          for Telegram).
        - >-
          Confirm the typeId value against the MessengerTypeProperty enum before
          sending the request.
      x-ai-responding-instructions:
        - >-
          Confirm success by referencing the contactId and the messenger type
          that was linked.
        - >-
          If isMainChatbot was set to true, explicitly note that this messenger
          is now the primary chatbot channel for the contact.
        - >-
          Suggest verifying the result by retrieving the contact's messenger
          list as a follow-up.
        - >-
          On error, clarify whether the issue is with the contactId (not found),
          typeId (unsupported), or login (invalid format).
      x-ai-suggestions:
        - >-
          After adding, use the messenger channel to enroll the contact in a
          chatbot flow.
        - >-
          If managing bulk contacts, iterate over a contact list and add
          messengers programmatically.
        - >-
          Set isMainChatbot: true only for the primary automation channel to
          avoid routing conflicts.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataWrite
  /contacts/{contactId}/messengers/{messengerId}:
    put:
      tags:
        - Contacts messengers
      summary: Update information about messenger of the contact
      description: >-
        Updates information about a given messenger for the specified contact.
        Provided property values will be overwritten.
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to update messenger information. It
            can be obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: messengerId
          in: path
          required: true
          description: >-
            Messenger ID you want to update. It can be obtained with the "Get a
            list of contacts" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                typeId:
                  $ref: '#/components/schemas/MessengerTypeProperty'
                login:
                  type: string
                  description: Contacts login in the specified messenger
                isMainChatbot:
                  type: boolean
                  description: Determine if chatbot messenger is the main one
              required:
                - typeId
                - login
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactMessenger'
      operationId: updateContactMessenger
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Updates a specific messenger entry linked to a contact. This is a
        partial-overwrite operation — only the fields you provide will be
        changed. Use this when a contact's messenger handle changes (e.g., new
        Telegram username) or when you need to promote a chatbot channel to
        'main' for routing automation flows through it.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the contactId and messengerId are valid by
          calling 'Get a list of contacts' — both IDs must exist and be related.
        - >-
          The `typeId` and `login` fields are required — always validate both
          are present before sending.
        - >-
          If the goal is to change only `isMainChatbot`, still include `typeId`
          and `login` to satisfy the required constraint.
        - >-
          Only one messenger per contact can be the main chatbot — setting
          `isMainChatbot: true` here may implicitly demote another messenger;
          confirm this behavior with the user if relevant.
        - >-
          Messenger `login` formats differ by type — ensure the login value
          matches the expected format for the given `typeId` (e.g., Telegram
          username vs. phone number for WhatsApp).
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated and on which contact/messenger
          combination.
        - >-
          If `isMainChatbot` was changed to true, notify the user that this
          messenger is now the primary chatbot channel for this contact.
        - >-
          Return the updated ContactMessenger object and highlight any fields
          that changed.
        - >-
          On 404 or invalid ID errors, suggest using 'Get a list of contacts' to
          retrieve valid contactId and messengerId values.
      x-ai-suggestions:
        - >-
          Use this after a contact reports a changed messenger handle to keep
          routing rules accurate.
        - >-
          Combine with 'Get a list of contacts' to build a bulk-update flow for
          stale messenger records.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to overwrite messenger data for contact #{contactId}.
            This action cannot be undone automatically.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Contacts messengers
      summary: Remove messenger from contact
      description: Removes messenger from a specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID from which you want to remove messenger. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: messengerId
          in: path
          required: true
          description: >-
            Messenger ID you want to remove. It can be obtained with the "Get a
            list of contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: removeContactMessenger
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Permanently detaches a messenger channel from a contact record. Use when
        a contact opts out of a specific channel, changes their account, or when
        cleaning up stale/invalid messenger links. This action affects only the
        channel binding — the contact itself and other messengers remain intact.
      x-ai-reasoning-instructions:
        - >-
          Confirm the contactId is valid and the contact exists before
          attempting deletion.
        - >-
          Confirm the messengerId belongs to the specified contact — mixing IDs
          from different contacts will result in a 404 or unintended deletion.
        - >-
          Warn the user if this messenger is the contact's only communication
          channel, as removal will leave the contact unreachable.
        - >-
          This action is irreversible — the messenger link must be re-added
          manually if removed by mistake.
      x-ai-responding-instructions:
        - >-
          On success (204), confirm that the messenger has been unlinked from
          the contact.
        - >-
          Remind the user that the contact still exists and other messengers
          remain unaffected.
        - >-
          If the intent was to remove all messengers, suggest iterating over the
          full messenger list from 'Get a list of contacts'.
        - >-
          On error, clarify whether the issue is with the contactId or the
          messengerId.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contacts' to retrieve both contactId and
          messengerId before calling this endpoint.
        - >-
          After removal, verify the contact's remaining channels to ensure
          reachability.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the messenger link from the contact.
            Proceed?
        security_info:
          data_handling:
            - ResourceDeletion
  /contact-tags/{tagId}/contact/{contactId}:
    post:
      tags:
        - Contact tags
      summary: Add a tag to the contact
      description: Adds a tag to the specified contact
      parameters:
        - name: tagId
          in: path
          required: true
          description: >-
            Tag ID you want to add. It can be obtained with the "Get a list of
            contact tags" method
          schema:
            type: integer
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID to which you want to add the tag. It can be obtained with
            the "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '201':
          description: Created
      operationId: addTagToContact
      x-ai-role: crm_contact_segmentation_specialist
      x-ai-description: >-
        Associates an existing tag with a specific contact, enabling behavioral
        segmentation and targeted automation triggers. Tags in SendPulse CRM act
        as lightweight, non-exclusive labels that can drive conditional flows,
        filtering, and personalized outreach without modifying contact
        variables.
      x-ai-reasoning-instructions:
        - >-
          Verify that tagId exists by calling 'Get a list of contact tags'
          before attempting assignment.
        - >-
          Verify that contactId is valid via 'Get a list of contacts' to avoid a
          silent 404.
        - >-
          Check whether the tag is already assigned to the contact to prevent
          duplicate entries if the API does not handle idempotency.
        - >-
          Consider whether a bulk-tagging endpoint exists if the user intends to
          tag multiple contacts — prefer it over repeated single calls.
      x-ai-responding-instructions:
        - >-
          Confirm the tag was successfully applied and mention both the tag name
          and contact identifier for clarity.
        - >-
          Suggest triggering an automation or filter based on this tag as an
          immediate next step.
        - >-
          If a 404 is returned, clarify whether the tagId or contactId is the
          likely culprit and guide the user to retrieve valid IDs.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contact tags' to look up valid tagId values before
          calling this endpoint.
        - >-
          After tagging, consider using 'Get contacts by tag' to verify the
          assignment.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Contact tags
      summary: Delete a tag from a contact
      description: Removes the tag of the specified contact
      parameters:
        - name: tagId
          in: path
          required: true
          description: >-
            Tag ID you want to remove. It can be obtained with the "Get a list
            of contact tags" method
          schema:
            type: integer
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID from which you want to remove the tag. It can be obtained
            with the "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactTagFromContact
      x-ai-role: crm_contact_management_specialist
      x-ai-description: >-
        Removes a specific tag assignment from a contact without deleting the
        tag itself or the contact record. This is the primary mechanism for
        maintaining accurate audience segmentation when a contact's profile
        changes — e.g., after a purchase, lifecycle stage transition, or
        incorrect tagging. Impacts how the contact appears in tag-based filters
        and automations.
      x-ai-reasoning-instructions:
        - >-
          Before removing, verify the tag is actually assigned to the contact —
          a missing association returns the same 204, which could mask logic
          errors.
        - >-
          Check if any active automations, segments, or campaigns rely on this
          tag for targeting before removing it.
        - >-
          This operation affects segmentation silently — no downstream
          notification is triggered; warn the user if this contact is part of
          active workflows.
        - >-
          Obtain tagId from `getContactTags` and contactId from `getContacts` if
          not already known.
      x-ai-responding-instructions:
        - >-
          Confirm that the tag was successfully removed (HTTP 204 means no
          response body — state this explicitly to avoid user confusion).
        - >-
          Suggest verifying the contact's remaining tags via the 'Get a list of
          contacts' method.
        - >-
          If the tag was used in segmentation or automation, proactively
          recommend reviewing affected workflows.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          reason: >-
            Tag removal affects contact segmentation and may silently break
            automation targeting
        security_info:
          data_handling:
            - ResourceStateUpdate
  /contact-tags:
    get:
      tags:
        - Contact tags
      summary: Get a list of contact tags
      description: >-
        Returns a list of contact tags with the tag ID, tag name, and the number
        of contacts associated with this tag
      parameters:
        - name: name
          in: query
          required: false
          description: Exact match filter by tag name
          schema:
            type: string
            maxLength: 64
        - name: search
          in: query
          required: false
          description: Partial match filter by tag name (LIKE %search%)
          schema:
            type: string
            maxLength: 64
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactTag'
      operationId: listContactTags
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves the taxonomy of contact tags used for audience segmentation in
        the CRM. Tags are lightweight labels that group contacts without
        requiring a dedicated field or variable — they reflect behavioural,
        source, or lifecycle attributes. This endpoint is the entry point for
        any tag-based filtering, reporting, or bulk operations on contact
        segments.
      x-ai-reasoning-instructions:
        - >-
          Use `name` for exact lookups when the full tag name is known; use
          `search` for discovery or autocomplete-style queries.
        - >-
          Check the `contacts_count` in the response before performing tag-based
          bulk operations — a tag with 0 contacts may indicate stale taxonomy.
        - >-
          If the user wants to filter contacts by tag, first retrieve the tag ID
          here, then pass it to the contacts list endpoint.
        - >-
          Avoid calling both `name` and `search` simultaneously — they serve
          different precision levels and combining them may yield unexpected
          results depending on backend logic.
      x-ai-responding-instructions:
        - 'Present results as a structured list: tag name, ID, and contact count.'
        - >-
          If no tags are returned, suggest that no tags have been created yet
          and recommend using the tag creation endpoint.
        - >-
          If the user is searching for a specific tag, confirm whether an exact
          or partial match was used and clarify which parameter was applied.
        - >-
          Highlight tags with high contact counts as likely candidates for
          segmentation or campaign targeting.
      x-ai-suggestions:
        - Use `search=vip` to find all tags containing 'vip' in the name.
        - >-
          Use `name=newsletter` for an exact match when you know the precise tag
          label.
        - >-
          After retrieving tag IDs, use them to filter contacts or assign tags
          in bulk.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Contact tags
      summary: Create a tag
      description: Creates a tag with the specified name
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: >-
                    Tag name to be created. The maximum number of characters is
                    64
                colorText:
                  type: string
                  description: Text color
                colorBackground:
                  type: string
                  description: Background color
              required:
                - name
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactTag'
      operationId: createContactTag
      x-ai-role: crm_data_organization_specialist
      x-ai-description: >-
        Creates a named tag used to categorize and segment contacts in SendPulse
        CRM. Tags are lightweight, visual labels that enable fast filtering and
        targeted bulk actions across the contact base. Color customization
        allows teams to build consistent visual taxonomies (e.g., red for
        high-priority, green for qualified leads).
      x-ai-reasoning-instructions:
        - >-
          Before creating, check if a tag with the same or similar name already
          exists to avoid duplicates.
        - >-
          Suggest meaningful, action-oriented tag names that reflect contact
          state or segment (e.g., 'Hot_Lead', 'Churn_Risk', 'VIP_Customer').
        - >-
          If colorText and colorBackground are omitted, the system will apply
          defaults — inform the user if visual consistency matters.
        - >-
          Remind the user that tag names are limited to 64 characters; truncate
          or abbreviate long names proactively.
      x-ai-responding-instructions:
        - >-
          Confirm the tag was created and surface the returned tag ID for
          reference in future operations.
        - >-
          Suggest immediately assigning the tag to contacts using the relevant
          contact-update endpoint.
        - >-
          If creation fails due to a duplicate name, offer to retrieve the
          existing tag instead.
      x-ai-suggestions:
        - Hot_Lead
        - VIP_Customer
        - Churn_Risk
        - Onboarding_Complete
        - Re_Engagement
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /contact-tags/{tagId}:
    put:
      tags:
        - Contact tags
      summary: Update a tag
      description: >-
        Updates the specified tag with a new name. Provided property values will
        be overwritten.
      parameters:
        - name: tagId
          in: path
          required: true
          description: >-
            Tag ID you want to update. It can be obtained with the "Get a list
            of contact tags" method
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: New tag name. The maximum number of characters is 255
                colorText:
                  type: string
                  description: Text color
                colorBackground:
                  type: string
                  description: Background color
              required:
                - name
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactTag'
      operationId: updateContactTag
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Modifies the metadata of an existing contact tag — its display name and
        visual styling (text and background color). Tags in SendPulse CRM are
        classification labels attached to contacts; renaming or recoloring a tag
        instantly affects all contacts it is applied to, making this a
        high-impact bulk-update operation even though only one record is
        targeted.
      x-ai-reasoning-instructions:
        - >-
          Retrieve the current tag state via 'Get a list of contact tags' before
          updating to confirm the tagId is valid and to present the user with
          the current values.
        - >-
          If only colorText or colorBackground is being changed without a name
          change, you must still supply the current name in the request body
          because 'name' is required.
        - >-
          Warn the user that renaming a widely-used tag changes how it appears
          across all associated contacts and pipelines immediately.
        - >-
          Validate that the new name does not exceed 255 characters before
          sending the request.
        - >-
          Check for duplicate tag names in the existing tag list to avoid
          creating visual confusion in the CRM.
      x-ai-responding-instructions:
        - >-
          Confirm the update by echoing the new tag name and, if changed, the
          new color values.
        - >-
          If colorText or colorBackground was updated, mention that the visual
          change is reflected immediately in the CRM contact view.
        - >-
          If the tagId was not found (404), advise the user to fetch the current
          tag list to verify the correct ID.
        - >-
          Suggest filtering or segmenting contacts by this tag as a logical next
          step after renaming.
      x-ai-suggestions:
        - VIP_Client
        - Hot_Lead
        - Churned_2024
        - Needs_Followup
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Renaming a tag affects all contacts it is currently applied to.
            Confirm the new name before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Contact tags
      summary: Remove tag
      description: Removes the specified tag
      parameters:
        - name: tagId
          in: path
          required: true
          description: >-
            Tag ID you want to remove. It can be obtained with the "Get a list
            of contact tags" method
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactTag
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Permanently removes a contact tag from the account. Tags are used to
        categorize and segment contacts — deleting a tag removes it from all
        contacts it was applied to, which may affect segment-based automations
        or filters that rely on this tag.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, verify the tag exists using 'Get a list of contact
          tags' to obtain the correct tagId.
        - >-
          Warn the user that this action is irreversible — the tag will be
          unlinked from all contacts.
        - >-
          Check if the tag is used in any active automations or audience
          segments before proceeding.
        - >-
          If the user provides a tag name instead of an ID, resolve the ID first
          via the tag list endpoint.
      x-ai-responding-instructions:
        - >-
          Confirm successful deletion by noting the tagId that was removed (204
          returns no body).
        - >-
          Remind the user that contacts previously assigned this tag are no
          longer tagged — segments or automations using it may behave
          differently.
        - >-
          If a 404 is returned, clarify that the tag may have already been
          deleted or the ID is incorrect.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete the tag and remove it from all
            associated contacts. This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - CascadingEffect
  /contacts/attributes:
    get:
      tags:
        - Contact Attributes
      summary: Get contact attributes list
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactAttribute'
      operationId: getContactAttributes
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Retrieves the full list of custom attributes defined for contacts in the
        account. These attributes form the schema of contact data — knowing them
        is a prerequisite for filtering, segmenting, or enriching contacts.
        Without this list, an agent cannot reliably map external data fields to
        CRM contact properties.
      x-ai-reasoning-instructions:
        - >-
          Call this endpoint before attempting to create or update contacts to
          know which attributes are available.
        - >-
          Use the returned attribute list to validate that required fields exist
          before building import payloads.
        - >-
          If the user asks to filter or segment contacts, check available
          attributes first to suggest valid filter keys.
      x-ai-responding-instructions:
        - >-
          Present the attributes as a structured list with names and types for
          clarity.
        - >-
          If the list is empty, suggest creating custom attributes as a next
          step.
        - >-
          Highlight any system-reserved attributes vs. user-defined ones if
          distinguishable.
      x-ai-suggestions:
        - >-
          Use the returned attribute names as keys when importing or updating
          contact data.
        - >-
          Cross-reference with contact export fields to ensure schema
          consistency.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Contact Attributes
      summary: Create a contact attribute
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                type:
                  type: integer
                  description: >-
                    0 = Text, 1 = Number, 2 = Date, 3 = Link, 4 = Select, 5 =
                    MultiSelect
                mandatory:
                  type: boolean
                options:
                  type: array
                  items:
                    oneOf:
                      - type: string
                      - type: integer
              required:
                - name
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactAttribute'
      operationId: createContactAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Defines a custom schema field for all contacts in the CRM. Contact
        attributes act as typed columns — once created, they become available
        across the entire contact base for filtering, segmentation, and
        personalization. The `type` field controls validation and UI rendering,
        so choosing the correct type upfront is critical: it cannot be changed
        after contacts start storing values.
      x-ai-reasoning-instructions:
        - >-
          Check whether an attribute with the same name already exists before
          creating a new one to avoid schema duplication.
        - >-
          Validate that `options` is provided when `type` is 4 (Select) or 5
          (MultiSelect) — these types are meaningless without predefined
          choices.
        - >-
          For `type` 2 (Date), remind the user that stored values must conform
          to a consistent date format to enable reliable filtering.
        - >-
          If `mandatory` is true, warn that all existing contacts will have this
          field as empty until explicitly populated — plan a backfill if needed.
        - >-
          Use lowercase, underscore-separated names (e.g., `subscription_tier`)
          for programmatic consistency.
      x-ai-responding-instructions:
        - >-
          Confirm creation by referencing the returned `ContactAttribute`
          object, highlighting the attribute ID and type label (not just the
          numeric code).
        - >-
          If `type` is Select or MultiSelect, list the registered options back
          to the user for verification.
        - >-
          Suggest the next logical step: assigning a value to this attribute on
          specific contacts via the update contact endpoint.
      x-ai-suggestions:
        - subscription_tier
        - lifecycle_stage
        - preferred_language
        - last_purchase_date
        - lead_score
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - SchemaModification
            - ResourceStateUpdate
  /contacts/attributes/{attributeId}:
    put:
      tags:
        - Contact Attributes
      summary: Update a contact attribute
      parameters:
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                status:
                  type: integer
                  description: 0 = Inactive, 1 = Active, 2 = Hidden
                type:
                  type: integer
                  description: >-
                    0 = Text, 1 = Number, 2 = Date, 3 = Link, 4 = Select, 5 =
                    MultiSelect
                mandatory:
                  type: boolean
                contactCardShow:
                  type: boolean
                order:
                  type: integer
                options:
                  type: array
                  items:
                    oneOf:
                      - type: string
                      - type: integer
              required:
                - name
                - order
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactAttribute'
      operationId: updateContactAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Modifies the schema definition of a contact attribute — its display
        name, type, visibility, ordering, and available options. Changes here
        propagate to all contacts that have this attribute assigned, making it a
        structural operation affecting the entire CRM data model, not just a
        single record.
      x-ai-reasoning-instructions:
        - >-
          Fetch the current attribute state before updating to avoid
          accidentally overwriting fields the user did not intend to change.
        - >-
          Warn the user if they are changing the `type` of an existing attribute
          — this may cause data loss or incompatibility with values already
          stored for that attribute on contacts.
        - >-
          If `options` is being modified on a Select or MultiSelect attribute,
          check whether existing contact values reference options that are being
          removed.
        - >-
          Changing `status` to 0 (Inactive) or 2 (Hidden) will silently remove
          the attribute from new contact forms — confirm intent with the user.
        - >-
          Ensure `order` is unique among attributes in the same group to avoid
          ambiguous sorting.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were changed and summarize the new state of the
          attribute.
        - >-
          If `type` was changed, proactively warn about potential data
          compatibility issues with existing contact records.
        - >-
          If `status` was set to Hidden or Inactive, explain the UX impact
          (attribute no longer appears in contact card or forms).
        - >-
          Suggest verifying the result with a GET on the attribute or reviewing
          the contact card layout.
      x-ai-suggestions:
        - >-
          To reorder attributes in the contact card, update the `order` field
          incrementally across all attributes.
        - >-
          Use `status: 2` (Hidden) instead of deleting an attribute to preserve
          historical data while removing it from the UI.
        - >-
          For Select/MultiSelect attributes, always pass the full `options`
          array — partial updates may remove existing options.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          reason: >-
            Structural change to attribute schema affects all contacts with this
            attribute.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PotentialDataLoss
    delete:
      tags:
        - Contact Attributes
      summary: Delete a contact attribute
      parameters:
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Permanently removes a custom contact attribute definition from the
        account. This is a schema-level destructive operation — deleting an
        attribute cascades to all contacts that had a value for it, irreversibly
        erasing that data dimension across the entire contact base. Use only
        when the attribute is no longer part of the data model, not when
        individual contact values need clearing.
      x-ai-reasoning-instructions:
        - >-
          Before proceeding, warn the user that this operation is irreversible
          and will remove the attribute value from every contact in the system.
        - >-
          Verify the attributeId exists and belongs to the user's account to
          avoid a misleading 204 on a phantom ID.
        - >-
          Check whether the attribute is used in active segments, automations,
          or campaign personalization — deletion may silently break those.
        - >-
          If the user's intent is to clear values rather than remove the
          attribute definition, suggest updating contacts instead.
      x-ai-responding-instructions:
        - Confirm deletion by echoing the attributeId that was removed.
        - >-
          Remind the user that all contact data stored under this attribute has
          been permanently lost.
        - >-
          If relevant, suggest auditing automations or segments that may have
          referenced this attribute.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete the attribute and all associated values
            across all contacts. This cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - CascadingDataLoss
  /contacts/{contactId}/attributes:
    get:
      tags:
        - Contact attributes Value
      summary: Get a list of specified contact attribute values
      description: >-
        Returns a list of attributes for the specified contact with information
        about the contacts ID, title, status, value, and options for each
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to get the list of attributes. It can
            be obtained with the "Get a list of contacts" method
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactAttributeValue'
      operationId: getContactAttributes
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves the full set of attribute values bound to a specific contact —
        the semantic profile of that contact in the CRM. Each attribute carries
        its current value, status, and available options, making this endpoint
        essential for understanding contact segmentation state before any
        personalization or automation logic.
      x-ai-reasoning-instructions:
        - >-
          Ensure the contactId is valid by cross-referencing with the 'Get a
          list of contacts' endpoint if the ID was not just retrieved.
        - >-
          Attribute statuses may indicate whether a value is active, pending, or
          disabled — factor this in before using values for targeting.
        - >-
          If the response includes option-type attributes, the 'options' field
          defines the allowed values — use it to validate before any update
          attempts.
      x-ai-responding-instructions:
        - >-
          Present the attribute list in a readable summary grouped by status if
          there are many entries.
        - >-
          Highlight any attributes with empty or null values as potential data
          gaps worth addressing.
        - >-
          Suggest using the returned attribute IDs when calling update or patch
          endpoints for this contact.
      x-ai-suggestions:
        - Use this before updating contact attributes to know current state.
        - Combine with contact list endpoint to build a full contact profile.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Contact attributes Value
      summary: Add attribute value to contact
      description: Adds a attribute to the specified contact
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID to which you want to add the attribute. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                attributeId:
                  type: integer
                  description: >-
                    Attribute ID you want to add to the contact. It can be
                    obtained with the "Get a list of contacts" and "Get
                    information about a contact by ID" methods
                value:
                  type: string
                  description: >-
                    The attribute value to add to the contact. The maximum
                    number of characters is 5500
              required:
                - attributeId
                - value
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactAttributeValue'
      operationId: addContactAttributeValue
      x-ai-role: crm_data_specialist
      x-ai-description: >-
        Assigns a typed attribute value to a specific contact, enriching their
        profile with structured metadata. In SendPulse CRM, contact attributes
        act as custom fields that power segmentation, personalization, and
        automation triggers. This endpoint is the write counterpart to reading
        attribute data from contact detail endpoints.
      x-ai-reasoning-instructions:
        - >-
          Verify the contactId exists before attempting to assign a value — use
          'Get a list of contacts' or 'Get contact by ID' if unsure.
        - >-
          Confirm the attributeId is valid and belongs to the same CRM account
          by cross-referencing contact detail data.
        - >-
          Check that the value does not exceed 5500 characters; truncate or
          prompt the user to shorten if necessary.
        - >-
          Avoid sending duplicate attribute assignments for the same contactId +
          attributeId pair unless an update is intended.
        - >-
          If the attribute represents sensitive data (e.g., phone, email),
          remind the user of data handling responsibilities.
      x-ai-responding-instructions:
        - >-
          Confirm the attribute was successfully added and reference both the
          contactId and attributeId in the response summary.
        - >-
          If the response includes a ContactAttributeValue object, surface the
          assigned value for user verification.
        - >-
          Suggest reviewing the full contact profile as a next step to confirm
          the attribute appears correctly.
        - >-
          If an error occurs due to an invalid attributeId, guide the user to
          retrieve the correct ID from 'Get contact by ID'.
      x-ai-suggestions:
        - >-
          Use 'Get information about a contact by ID' first to confirm available
          attributes before assigning.
        - >-
          Batch multiple attribute assignments by calling this endpoint
          sequentially for each attributeId.
        - >-
          After assignment, use 'Get a list of contacts' with filters to verify
          segmentation reflects the new value.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataWrite
  /contacts/{contactId}/attributes/{attributeId}:
    put:
      tags:
        - Contact attributes Value
      summary: Update contact attribute value
      description: >-
        Updates the attribute for the specified contact. Provided property
        values will be overwritten.
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID for which you want to update the field. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          description: >-
            Attribute ID you want to update. It can be obtained with the "Get a
            list of contacts" and "Get information about a contact by ID"
            methods
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                value:
                  type: string
                  description: >-
                    New attribute value. The maximum number of characters is
                    5500
              required:
                - value
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ContactAttributeValue'
      operationId: updateContactAttributeValue
      x-ai-role: crm_data_steward
      x-ai-description: >-
        Overwrites a single attribute value for a specific contact. This is a
        targeted field-level update — unlike full contact updates, it modifies
        exactly one attribute without touching the rest of the contact record.
        Use when syncing external CRM data, applying segmentation tags, or
        updating lifecycle stage fields after a triggering event.
      x-ai-reasoning-instructions:
        - >-
          Resolve both contactId and attributeId before calling — neither can be
          inferred; use 'Get a list of contacts' to obtain both.
        - >-
          Confirm the attribute type accepts string values; some attributes may
          have constrained value sets.
        - >-
          Truncate or validate the value length before sending — the API
          enforces a 5500-character maximum.
        - >-
          Prefer this endpoint over full contact updates when only a single
          field needs to change, to avoid unintended overwrites.
      x-ai-responding-instructions:
        - >-
          Confirm which attribute was updated by echoing the attributeId and the
          new value.
        - >-
          If the response includes the updated ContactAttributeValue object,
          surface the key fields to the user.
        - >-
          Suggest verifying the change via 'Get information about a contact by
          ID' if the update is part of a critical workflow.
      x-ai-suggestions:
        - 'Set lifecycle stage: value=''churned'' after cancellation event'
        - 'Update lead score: value=''87'' after scoring model run'
        - Sync external CRM field after webhook trigger
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Contact attributes Value
      summary: Delete contact attribute value
      description: 'Delete attribute for specified contact '
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID from which you want to remove the attribute. It can be
            obtained with the "Get a list of contacts" method
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          description: >-
            Attribute ID you want to remove. It can be obtained with the "Get a
            list of contacts" and "Get information about a contact by ID"
            methods
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteContactAttributeValue
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Removes a specific attribute value from a contact record. Use this when
        a contact's data point is no longer relevant — for example, after a
        trial period expires, a temporary tag becomes invalid, or incorrect data
        was assigned. This is a hard delete: the attribute value is gone and
        cannot be recovered without re-assignment.
      x-ai-reasoning-instructions:
        - >-
          Confirm the contactId exists before attempting deletion — use 'Get a
          list of contacts' or 'Get information about a contact by ID' to
          verify.
        - >-
          Confirm the attributeId belongs to the target contact to avoid
          deleting an attribute from the wrong record.
        - >-
          This operation is irreversible — if the user seems uncertain, suggest
          verifying the attribute value first before deleting.
        - >-
          Consider whether the attribute should be cleared (updated to
          null/empty) instead of deleted, depending on the use case.
      x-ai-responding-instructions:
        - >-
          A 204 response means the deletion was successful — confirm this
          clearly to the user since no body is returned.
        - >-
          Mention the contactId and attributeId that were affected so the user
          can verify the correct record was targeted.
        - >-
          If the user deleted the attribute by mistake, inform them they will
          need to reassign it using the appropriate 'set attribute' endpoint.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the attribute value from the contact.
            Confirm before proceeding.
        security_info:
          data_handling:
            - IrreversibleDelete
  /contacts/{contactId}/attributes/batch:
    post:
      tags:
        - Contact Attributes Values
      summary: Batch store contact attributes values
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                attributesValues:
                  type: array
                  items:
                    type: object
                    properties:
                      attributeId:
                        type: integer
                        description: Attribute ID
                      value:
                        type: string
                        description: Attribute value
              required:
                - attributeId
                - value
      responses:
        '201':
          description: Successfully stored
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      attributeId:
                        type: integer
                        description: Attribute ID
                      value:
                        type: string
                        description: Attribute value
      operationId: batchStoreContactAttributeValues
      x-ai-role: crm_data_specialist
      x-ai-description: >-
        Performs a bulk upsert of attribute values for a single contact in one
        atomic request. In SendPulse CRM, contact attributes drive segmentation,
        personalization, and automation triggers — this endpoint is the
        preferred way to hydrate a contact's profile after creation or
        synchronization from an external system, avoiding N separate API calls.
      x-ai-reasoning-instructions:
        - >-
          Verify that the contact with the given contactId exists before
          calling; a 404 here means the contact was deleted or the ID is wrong.
        - >-
          Collect all attribute values that need updating and send them in one
          batch rather than looping with individual calls — this reduces
          rate-limit exposure and latency.
        - >-
          Confirm that each attributeId belongs to the account's attribute
          schema; submitting an unknown ID will silently fail or error depending
          on API version.
        - >-
          If the same attributeId appears more than once in the array, clarify
          with the user which value should win — duplicates cause unpredictable
          behavior.
        - >-
          For sensitive attribute types (e.g., phone, email, financial data),
          check whether the value format matches the attribute's expected type
          before submitting.
      x-ai-responding-instructions:
        - >-
          Confirm which attributes were successfully stored by echoing back the
          attributeId/value pairs from the 201 response.
        - >-
          If the operation was part of a contact import or sync flow, suggest
          verifying the full contact profile with a GET /contacts/{contactId}
          call.
        - >-
          If an error occurs, distinguish between a missing contact (fix: check
          the ID), unknown attribute IDs (fix: list available attributes first),
          and validation errors (fix: check value format).
      x-ai-suggestions:
        - >-
          After storing attributes, trigger segmentation refresh or re-evaluate
          automation conditions that depend on these attributes.
        - >-
          Use GET /contacts/attributes to retrieve the full list of available
          attributeIds for this account before constructing the batch payload.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataWrite
  /boards:
    get:
      tags:
        - Tasks boards
      summary: Get all boards
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Boards'
      operationId: getBoards
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Retrieves all task boards available in the account. Boards are the
        top-level organizational unit in the task management system — each board
        groups related tasks and columns. Use this to discover available
        workspaces before querying tasks or columns.
      x-ai-reasoning-instructions:
        - >-
          Call this endpoint first when the user wants to work with tasks but
          hasn't specified a board — list boards to let them choose.
        - >-
          If the user refers to a board by name, use this response to resolve
          the correct board ID before proceeding.
        - >-
          Check whether the returned list is empty; if so, inform the user no
          boards exist yet and suggest creating one.
      x-ai-responding-instructions:
        - Present boards as a named list with their IDs for easy reference.
        - >-
          If multiple boards are returned, ask the user which one they want to
          work with.
        - >-
          Suggest fetching tasks or columns for a specific board as the logical
          next step.
      x-ai-suggestions:
        - >-
          Use the returned board IDs with endpoints that require a `boardId`
          parameter.
        - >-
          If you need tasks, follow up with a get-tasks endpoint for the
          selected board.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Tasks boards
      summary: Create new board
      description: Creates a new board with the specified properties
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Board name
                settings:
                  type: array
                  items:
                    properties:
                      name:
                        type: string
                        description: Setting name
                        enum:
                          - responsibleUser
                          - color
                      value:
                        type: string
                        description: Setting value
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Boards'
      operationId: createBoard
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Initializes a new task board — the primary organizational unit for
        managing tasks, pipelines, and team workflows in SendPulse CRM. A board
        defines the structural context (color, responsible user) within which
        task columns and cards will be created. Creating a well-configured board
        upfront reduces friction in later task assignment and team coordination.
      x-ai-reasoning-instructions:
        - >-
          Check if a board with a similar name already exists to avoid
          duplicates.
        - >-
          If a responsibleUser is provided, verify the user exists and has
          appropriate CRM access.
        - >-
          Recommend descriptive board names that reflect team, project, or
          pipeline purpose (e.g., 'Sales_Pipeline_Q2', 'Onboarding_Tasks').
        - >-
          Color setting is optional but improves visual distinction in
          multi-board workspaces — suggest using it when multiple boards exist.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by referencing the new board's ID and
          name.
        - >-
          Suggest creating task columns (stages) inside the board as the
          immediate next step.
        - If responsible user was set, confirm the assignment explicitly.
        - >-
          If creation fails due to permission or limit constraints, explain what
          plan or role is required.
      x-ai-suggestions:
        - Sales_Pipeline_Q2
        - Customer_Onboarding_Flow
        - Support_Escalations_Team
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /boards/{boardId}:
    get:
      tags:
        - Tasks boards
      summary: Get board by ID
      description: Gets a board with all associated settings
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Boards'
      operationId: getBoardById
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Retrieves a complete snapshot of a task board including its
        configuration, columns, assignees, and all associated settings. A board
        is the top-level organizational unit in the task management system —
        understanding its structure is a prerequisite before querying tasks,
        members, or workflows within it.
      x-ai-reasoning-instructions:
        - Confirm the boardId is a valid integer before making the request.
        - >-
          If the user references a board by name, first resolve the ID via a
          listing endpoint before calling this one.
        - >-
          Use the returned board settings to inform downstream operations —
          e.g., available columns or member permissions.
      x-ai-responding-instructions:
        - >-
          Summarize the board's name, status, and key settings rather than
          dumping raw JSON.
        - >-
          Highlight any configuration details that are relevant to the user's
          current task (e.g., column structure if they want to create a task).
        - >-
          If the board is not found (404), suggest verifying the boardId or
          listing available boards.
      x-ai-suggestions:
        - >-
          Use the returned board data to populate a subsequent `createTask` or
          `getBoardTasks` call.
        - >-
          Check board membership settings before attempting to assign tasks to
          users.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - Tasks boards
      summary: Update board by ID
      description: Updates the board with settings by ID
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                settings:
                  type: array
                  items:
                    properties:
                      name:
                        type: string
                      value:
                        type: string
                        example: 1 or hello
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Boards'
      operationId: updateBoard
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Updates the configuration and metadata of a task board. In SendPulse
        CRM, a board defines the visual and structural layout of a pipeline —
        its name and settings control how tasks are displayed, filtered, and
        managed across team workflows. Modifying a board affects all users who
        interact with it.
      x-ai-reasoning-instructions:
        - Before updating, verify that the boardId exists to avoid a silent 404.
        - >-
          If only renaming, omit `settings` to avoid accidentally overwriting
          existing configuration.
        - >-
          Warn the user if they are changing board settings that may affect
          active tasks or shared team workflows.
        - >-
          Validate that `settings` items have both `name` and `value` fields
          populated before sending.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated (name and/or settings) in the
          response summary.
        - >-
          If the board is shared across a team, note that changes are
          immediately visible to all members.
        - >-
          Suggest reviewing related boards or tasks if structural settings were
          changed.
      x-ai-suggestions:
        - >-
          Use `getBoardById` first to retrieve current settings before
          performing a partial update.
        - >-
          After updating, use `getBoards` to confirm the change is reflected in
          the board list.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating board settings affects all users with access to this board.
            Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
  /boards/{boardId}/attributes:
    get:
      tags:
        - Board attributes
      summary: Get attribute for board
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/BoardAttribute'
      operationId: getBoardAttributes
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Retrieves the custom attribute schema defined for a specific CRM board.
        Board attributes act as column definitions — they determine what
        structured data can be stored per card/contact on that board.
        Understanding the attribute schema is a prerequisite before creating or
        updating cards, as it defines valid field names, types, and constraints.
      x-ai-reasoning-instructions:
        - >-
          Always fetch board attributes before attempting to create or update
          cards on a board — attribute IDs and types are required for correct
          field mapping.
        - >-
          If the boardId is unknown, first call the board listing endpoint to
          resolve the correct ID.
        - >-
          Cache the attribute schema locally within a session to avoid redundant
          calls when processing multiple cards on the same board.
      x-ai-responding-instructions:
        - >-
          Present the attributes as a structured field reference — name, type,
          and ID for each attribute.
        - >-
          If the attribute list is empty, inform the user that no custom fields
          have been configured for this board yet and suggest creating them.
        - >-
          Highlight any required attributes the user must populate when creating
          cards.
      x-ai-suggestions:
        - >-
          Use returned attribute IDs when constructing payloads for card
          create/update endpoints.
        - >-
          Follow up with a card listing call to see how current data maps to
          these attributes.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Board attributes
      summary: Create attribute for board
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Attribute name
                type:
                  type: number
                  description: |
                    Attribute type:
                    0 -string
                    1 - number
                    2 - date
                    3 - link
                    4 - list
                    5 - multiList
                mandatory:
                  type: boolean
                  description: Is attribute required
                options:
                  type: array
                  description: Attribute options (only for "list" and "multiList" types)
                  default:
                    - 1
                    - 2
      responses:
        '201':
          description: Successfully
      operationId: createBoardAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Defines a custom attribute schema for a CRM board, extending its data
        model beyond built-in fields. Attributes act as typed column definitions
        — they determine what structured data can be captured per contact or
        deal on this board. Choosing the correct type upfront is critical: it
        cannot be changed after contacts have values assigned.
      x-ai-reasoning-instructions:
        - >-
          Before creating, check existing attributes on the board to avoid name
          collisions.
        - >-
          Validate that `type` matches the expected data semantics: use `date`
          for timestamps, `link` for URLs, `list`/`multiList` for constrained
          vocabularies.
        - >-
          If `type` is 4 (list) or 5 (multiList), `options` is required — warn
          the user if it is missing or empty.
        - >-
          If `mandatory` is true, ensure the user understands all existing
          contacts will lack this value until backfilled.
        - >-
          Suggest snake_case or consistent naming conventions for `name` to
          simplify downstream filtering.
      x-ai-responding-instructions:
        - >-
          Confirm the attribute was created and echo back its name and type for
          clarity.
        - >-
          If type is list or multiList, summarize the options that were
          registered.
        - >-
          Suggest populating the attribute via contact update endpoints as an
          immediate next step.
        - >-
          If a 4xx error occurs due to a duplicate name, propose a disambiguated
          alternative.
      x-ai-suggestions:
        - industry
        - deal_stage
        - onboarding_date
        - contract_url
        - preferred_contact_channel
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - SchemaModification
            - ResourceStateUpdate
  /boards/{boardId}/attributes/{attributeId}:
    put:
      tags:
        - Board attributes
      summary: Update attribute for board
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Attribute name
                type:
                  type: number
                  description: |
                    Attribute type:
                    0 -string
                    1 - number
                    2 - date
                    3 - link
                    4 - list
                    5 - multiList
                mandatory:
                  type: boolean
                  description: Is attribute required
                options:
                  type: array
                  description: Attribute options (only for "list" and "multiList" types
                order:
                  type: integer
                  description: Attribute order
                status:
                  type: integer
      responses:
        '200':
          description: Successfully
      operationId: updateBoardAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Modifies the schema definition of a custom attribute on a CRM board.
        Attributes define the data model for board entities — changing a type
        (e.g., from string to list) affects how all existing contact/deal data
        stored under this attribute is interpreted. Order and mandatory flags
        control UI behavior and data entry validation across the board.
      x-ai-reasoning-instructions:
        - >-
          Before changing `type`, warn the user that existing data stored under
          this attribute may become incompatible or unreadable with the new
          type.
        - >-
          If `type` is set to 4 (list) or 5 (multiList), verify that `options`
          array is also provided — otherwise the attribute will be unusable.
        - >-
          If `mandatory` is set to true, existing board records without this
          attribute will fail validation on next update — inform the user about
          the impact.
        - >-
          Changing `order` repositions the attribute in the UI; use this to
          group related attributes visually.
        - >-
          Confirm that both `boardId` and `attributeId` exist before attempting
          the update to avoid misleading 404 errors.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated and briefly describe the effect
          (e.g., 'Attribute is now required for all records').
        - >-
          If `type` was changed, proactively note potential data compatibility
          risks.
        - >-
          If `options` were updated for a list/multiList attribute, mention that
          removed options may affect existing records using those values.
        - >-
          Suggest verifying board records after structural changes to ensure
          data integrity.
      x-ai-suggestions:
        - >-
          Use `getBoardAttributes` to fetch current attribute config before
          patching.
        - >-
          After updating a mandatory attribute, review existing records for
          compliance.
        - >-
          Reorder attributes (`order` field) to improve data entry UX on the
          board UI.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Changing attribute type or mandatory status affects all existing
            board records. Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - SchemaModification
  /boards/{boardId}/steps:
    post:
      tags:
        - Tasks steps
      summary: Create steps for board
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Step name
                color:
                  type: string
                  description: Step color
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/BoardSteps'
      operationId: createBoardSteps
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Initializes a workflow stage within a CRM board. Steps define the
        pipeline structure — each step represents a distinct phase in a deal or
        task lifecycle. The order and naming of steps directly shapes how agents
        and users move tasks through the board.
      x-ai-reasoning-instructions:
        - Before creating a step, verify the boardId exists and is accessible.
        - >-
          Check whether a step with the same name already exists on this board
          to avoid duplication.
        - >-
          If color is omitted, note that a default will be assigned — suggest
          using distinct colors for visual clarity in pipelines with many
          stages.
        - >-
          Consider the logical position of the new step in the workflow — advise
          the user to think about ordering when multiple steps are being
          created.
      x-ai-responding-instructions:
        - Confirm successful creation by referencing the new step's ID and name.
        - >-
          Suggest reviewing the full board structure via the corresponding GET
          endpoint to verify step placement.
        - >-
          If the board is not found or access is denied, explain that boardId
          must correspond to a board the user owns or has access to.
      x-ai-suggestions:
        - New
        - In Progress
        - Review
        - Completed
        - On Hold
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /boards/{boardId}/steps/{stepId}:
    put:
      tags:
        - Tasks steps
      summary: Update steps for board
      description: Updates board step (with order)
      parameters:
        - name: boardId
          in: path
          required: true
          schema:
            type: integer
        - name: stepId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Step name
                color:
                  type: string
                  description: Step color
                order:
                  type: integer
                  description: Step order
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/BoardSteps'
      operationId: updateBoardStep
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Updates a specific step (stage/column) within a board, including its
        name, visual color, and position order. Steps define the workflow stages
        through which tasks progress — modifying them restructures the entire
        board's pipeline logic.
      x-ai-reasoning-instructions:
        - >-
          Verify that both boardId and stepId exist before attempting the
          update.
        - >-
          When changing 'order', check existing step positions to avoid
          conflicts or gaps in sequence.
        - >-
          If only 'color' is being updated, no order recalculation is needed —
          apply a minimal patch.
        - >-
          Warn the user if renaming a step that may be referenced in automations
          or filters.
      x-ai-responding-instructions:
        - Confirm which fields were updated and their new values.
        - >-
          If order was changed, describe the step's new position relative to
          others.
        - >-
          Suggest retrieving the full board structure via a GET
          /boards/{boardId}/steps call to verify the updated pipeline.
      x-ai-suggestions:
        - >-
          Use sequential integers (1, 2, 3…) for 'order' to maintain a clean
          pipeline.
        - >-
          Common step colors: '#FF5733' for urgent, '#28A745' for done,
          '#007BFF' for in-progress.
        - 'Typical step names: ''Backlog'', ''In Progress'', ''Review'', ''Done'''
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /tasks/list:
    post:
      tags:
        - Tasks
      summary: Get tasks
      description: Retrieves a list of tasks based on selected filters
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                boardId:
                  type: integer
                  example: 1
                stepId:
                  type: array
                  description: Array of step IDs
                priority:
                  type: integer
                  example: '[ 1,2,3 ]'
                type:
                  type: integer
                  enum:
                    - 1
                    - 2
                    - 3
                responsibleId:
                  type: array
                  description: Array of responsible users IDs
                parentId:
                  type: array
                  description: Array of parent task IDs
                dealName:
                  type: string
                  example: name
                observers:
                  type: array
                  description: Array of users IDs acting as observers
                tags:
                  type: array
                  description: IDs of tags
                tagMatch:
                  type: string
                  enum:
                    - any
                    - all
                  description: 'Filter by tags (all - all tags, any - any tag). Default: any'
                attributes:
                  type: array
                  items:
                    properties:
                      id:
                        type: integer
                      type:
                        type: integer
                      value:
                        type: string
                        example: hello | ['hello', 'hello']
                contacts:
                  type: string
                  example: name
                startAtFrom:
                  type: string
                  example: 2021-11-25 13:38
                startAtTo:
                  type: string
                  example: 2021-11-25 13:38
                finishAtFrom:
                  type: string
                  example: 2021-11-25 13:38
                finishAtTo:
                  type: string
                  example: 2021-11-25 13:38
                createdAtFrom:
                  type: string
                  example: 2021-11-25 13:38
                createdAtTo:
                  type: string
                  example: 2021-11-25 13:38
                updatedAtFrom:
                  type: string
                  example: 2025-05-03 13:00
                updatedAtTo:
                  type: string
                  example: 2025-05-07 13:00
                sort:
                  type: object
                  properties:
                    field:
                      type: string
                      default: name
                    direction:
                      type: string
                      default: asc
                status:
                  type: integer
                  enum:
                    - 1
                    - 2
                endedAtFrom:
                  type: string
                  example: 2021-11-25 13:38
                endedAtTo:
                  type: string
                  example: 2021-11-25 13:38
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Tasks'
                  searchRequest:
                    type: string
      operationId: listTasks
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Retrieves a filtered, sorted list of CRM tasks. Despite using POST, this
        is a query endpoint — the request body acts as a flexible filter payload
        supporting multi-dimensional filtering by board, step, priority,
        assignee, tags, custom attributes, date ranges, and task type. Use this
        to build task dashboards, run scheduled audits, or find
        overdue/unassigned tasks.
      x-ai-reasoning-instructions:
        - >-
          Before querying, clarify the user's intent: are they looking for tasks
          on a specific board, assigned to someone, within a date range, or by
          status?
        - >-
          If boardId is not provided, the query may return tasks across all
          boards — warn the user if they expect board-scoped results.
        - >-
          When filtering by tags, confirm whether 'any' or 'all' tag matching is
          desired; default is 'any', which may return broader results than
          expected.
        - >-
          Date range fields (startAtFrom/To, finishAtFrom/To, createdAtFrom/To,
          updatedAtFrom/To, endedAtFrom/To) are independent — avoid combining
          conflicting ranges.
        - >-
          If stepId is provided, verify it belongs to the specified boardId to
          avoid empty results.
        - >-
          For responsible/observer filtering, ensure the provided user IDs are
          valid members of the workspace.
        - >-
          Use the sort object to control result ordering; default is by name
          ascending — suggest sorting by updatedAtFrom desc for recent activity
          views.
      x-ai-responding-instructions:
        - >-
          Present results summarized by count and key groupings (e.g., by status
          or priority) before listing individual tasks.
        - >-
          If the result set is large, suggest narrowing filters (e.g., add
          boardId, status, or a date range).
        - >-
          If no tasks are returned, explain which filters were applied and
          suggest relaxing one constraint at a time.
        - >-
          Highlight overdue tasks (finishAt in the past, status not completed)
          as actionable items.
        - >-
          Reference the searchRequest field from the response when helping the
          user refine or repeat the query.
      x-ai-suggestions:
        - >-
          Filter by status=1 (active) and responsibleId to get a personal task
          queue
        - >-
          Use updatedAtFrom/To with a recent range to detect recently changed
          tasks
        - Combine boardId + stepId to get tasks at a specific pipeline stage
        - Use tagMatch=all with multiple tags for precise segment targeting
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /tasks:
    post:
      tags:
        - Tasks
      summary: Create tasks
      description: >
        repeatSetting - has 4 types: 1-daily, 2-weekly, 3-monthly, 4-yearly.

        'endSetting' - has 2 types: byDate(2021-11-25), byCount(1)


        1) 'repeatSetting': {'type': 1, 'startDate': '2021-11-25 13:38',

        'endSetting': {'type':'byDate','value': '2021-11-25'},'setting':
        {'everyDay': 2 }};

        <br> 'everyDay' - 2 (repeat every Tuesday)


        2) 'repeatSetting': {'type': 2, 'startDate': '2021-11-25 13:38',

        'endSetting': {'type':'byCount','value': 1},'setting': {'days': [1,4,5],
        'everyWeekOfMonth': 3 }};

        'days': [1,4,5], 'everyWeekOfMonth': 3

        <br> (repeat every Monday, Thursday, Friday of every 3rd week of the
        month)


        3) 'repeatSetting': {'type': 3, 'startDate': '2021-11-25 13:38',

        'endSetting': {'type':'byDate','value': '2021-11-25'},

        'setting': {'numberOfMonth': {'everyDay': 31, 'everyMonth':5} }};

        <br> 'numberOfMonth': {'everyDay': 31, 'everyMonth':5 (repeat every 31st
        day of every 5th month)


        4) 'repeatSetting': {'type': 3, 'startDate': '2021-11-25
        13:38','endSetting': {'type':'byCount','value': 11},

        'setting': {'dayOfMonth': {'everyWeek': 3, 'dayOfWeek':5,
        'everyMonth':12} }};

        <br> 'dayOfMonth': {'everyWeek': 3, 'dayOfWeek':5, 'everyMonth':12} -
        (repeat every 3rd week every 5th day of the week every 12th month)
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Task name
                boardId:
                  type: integer
                stepId:
                  type: integer
                observers:
                  type: array
                  description: Array of users IDs acting as observers
                priority:
                  $ref: '#/components/schemas/TaskPriorityProperty'
                sourceType:
                  $ref: '#/components/schemas/IntegerSourceTypeProperty'
                responsibleId:
                  type: integer
                  description: Responsible user ID
                parentId:
                  type: integer
                  description: Parent task ID
                description:
                  type: string
                  description: Task description
                alert:
                  type: string
                  description: >-
                    Notify before task expires (when notification is enabled).
                    Allowed values - 0(not selected), 15min, 30min, 1h, 2h, 3h,
                    6h, 12h, 24h, 2d, 3d, 4d, 5d, 6d, 7d
                repeat:
                  type: integer
                  description: Do you need to repeat the task
                startAt:
                  type: string
                  format: Y-m-d H:i
                finishAt:
                  type: string
                  format: Y-m-d H:i
                repeatSetting:
                  $ref: '#/components/schemas/TaskRepeats'
                attributes:
                  $ref: '#/components/schemas/TasksAttribute'
                tags:
                  type: array
                  example: '[ 1,2,3 ]'
                  description: IDs of tags
                checklists:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        description: Checklist name
                      items:
                        type: array
                        items:
                          properties:
                            name:
                              type: string
                              description: Checklist item name
                            isDone:
                              type: integer
                              description: Is item is done (checked)
                connections:
                  type: object
                  properties:
                    dealIds:
                      type: array
                      example: '[ 1,2 ]'
                    contactIds:
                      type: array
                      example: '[ 1,2 ]'
                    taskIds:
                      type: array
                      example: '[ 1,2 ]'
                attachments:
                  type: array
                  items:
                    type: string
                  description: >-
                    First, the file must be uploaded to the file manager, and
                    then the file can be attached.
                  example:
                    - /personal/task/sendPulse_crm_report.csv
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Tasks'
      operationId: createTask
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Creates a new task within a CRM board pipeline. Tasks are the primary
        unit of work tracking in SendPulse CRM — they can be linked to deals,
        contacts, and other tasks, assigned to responsible users, and configured
        with flexible recurrence schedules (daily, weekly, monthly, yearly). The
        recurrence engine supports complex patterns such as "every 3rd Friday of
        every 2nd month", making this endpoint suitable for both one-time and
        long-term recurring workflows.
      x-ai-reasoning-instructions:
        - >-
          Verify that `boardId` and `stepId` exist before creating the task to
          avoid orphan records.
        - >-
          If `repeat` is set to a truthy value, `repeatSetting` must be provided
          and validated against its type: type 1 (daily) requires `everyDay`;
          type 2 (weekly) requires `days` and `everyWeekOfMonth`; type 3/4
          (monthly/yearly) require either `numberOfMonth` or `dayOfMonth`
          sub-objects.
        - >-
          Ensure `startAt` and `finishAt` follow the `Y-m-d H:i` format;
          misformatted dates will silently fail on some backends.
        - >-
          If `attachments` are provided, confirm the files were already uploaded
          via the File Manager — attachment paths must be pre-existing.
        - >-
          When `parentId` is supplied, this is a sub-task — inform the user it
          will appear nested under the parent.
        - >-
          Cross-check that `responsibleId` and all `observers` IDs are valid
          account users to prevent assignment failures.
        - >-
          If `connections` contains `dealIds` or `contactIds`, remind the user
          this links the task bi-directionally — it will appear in those
          deals/contacts' activity feeds.
      x-ai-responding-instructions:
        - >-
          Confirm creation by surfacing the new task ID from the `data` response
          object.
        - >-
          If a repeat schedule was configured, summarize the recurrence pattern
          in plain language (e.g., 'Task will repeat every Monday and Thursday
          for 3 occurrences').
        - >-
          If `parentId` was used, confirm the task was created as a sub-task of
          the specified parent.
        - >-
          Suggest logical next steps: adding checklist items, attaching files,
          or linking the task to a deal or contact.
        - >-
          On validation errors (missing required fields, invalid IDs), clearly
          state which field failed and why.
      x-ai-suggestions:
        - Follow up on proposal
        - Prepare onboarding call
        - Send contract for review
        - Schedule demo with client
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - CrossEntityLinking
  /tasks-repeat/templates:
    get:
      tags:
        - Tasks
      summary: Get task templates
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Tasks'
      operationId: getTaskRepeatTemplates
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Retrieves the list of predefined templates for recurring tasks.
        Templates define the structure and recurrence rules for tasks that need
        to repeat on a schedule. Use this endpoint to discover available
        templates before creating or configuring automated task repetition
        workflows.
      x-ai-reasoning-instructions:
        - >-
          Fetch templates first to understand available recurrence
          configurations before assigning them to tasks.
        - >-
          If the user wants to automate a recurring task, suggest selecting an
          appropriate template from this list.
        - >-
          If the response is empty, inform the user that no templates exist yet
          and guide them to create one.
      x-ai-responding-instructions:
        - >-
          Present the templates in a structured, human-readable way highlighting
          name and recurrence pattern.
        - Suggest which template best fits the user's described scheduling need.
        - >-
          If multiple templates are returned, help the user narrow down by use
          case.
      x-ai-suggestions:
        - >-
          Use the returned template IDs when creating or updating a recurring
          task.
        - >-
          Review recurrence intervals to select the most appropriate template
          for the workflow.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /tasks/{taskId}:
    get:
      tags:
        - Tasks
      summary: Get tasks by ID
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Tasks'
      operationId: getTaskById
      x-ai-role: project_management_assistant
      x-ai-description: >-
        Retrieves the full state of a specific asynchronous task by its unique
        ID. In SendPulse, long-running operations (bulk sends, imports, exports)
        are represented as tasks — this endpoint is the primary polling
        mechanism to track their progress and outcome.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint to poll the status of a previously initiated
          asynchronous operation.
        - >-
          Before calling, ensure the taskId was obtained from a prior operation
          response (e.g., bulk send, import).
        - >-
          Implement exponential backoff when polling — avoid hammering this
          endpoint on every tick.
        - >-
          Check the task status field in the response to determine if the
          operation is still pending, completed, or failed.
      x-ai-responding-instructions:
        - >-
          Clearly report the current task status and what it means in plain
          language.
        - >-
          If the task is still in progress, inform the user and suggest polling
          again after a delay.
        - >-
          If the task has failed, extract and surface the error details from the
          response.
        - >-
          If completed successfully, suggest the logical next step based on the
          task type (e.g., viewing send statistics).
      x-ai-suggestions:
        - >-
          Poll this endpoint every 5–10 seconds until the task reaches a
          terminal state (completed or failed).
        - >-
          Store the taskId from the triggering operation's response for later
          lookup.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - Tasks
      summary: Update a task by ID
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Task name
                boardId:
                  type: integer
                stepId:
                  type: integer
                priority:
                  $ref: '#/components/schemas/TaskPriorityProperty'
                sourceType:
                  $ref: '#/components/schemas/IntegerSourceTypeProperty'
                responsibleId:
                  type: integer
                  description: Responsible user ID
                parentId:
                  type: integer
                  description: Parent task ID
                description:
                  type: string
                  description: Task description
                repeat:
                  type: integer
                  description: Do you need to repeat the task
                startAt:
                  type: string
                  format: Y-m-d H:i
                finishAt:
                  type: string
                  format: Y-m-d H:i
                tags:
                  type: array
                  example: '[ 1,2,3 ]'
                  description: IDs of tags
                observers:
                  type: array
                  example: '[ 1,2,3 ]'
                  description: Array of users IDs acting as observers
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Tasks'
      operationId: updateTaskById
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Updates mutable fields of an existing task in a CRM board. This endpoint
        is the primary mechanism for advancing task lifecycle — changing its
        board step (pipeline stage), reassigning responsibility, adjusting
        priority, or extending deadlines. Partial updates are supported: only
        provided fields are modified, existing values are preserved.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the taskId is valid and the task exists; a
          missing task returns an error rather than a no-op.
        - >-
          If moving the task to a different board (boardId) or step (stepId),
          verify the target board/step exists and the user has permission to
          place tasks there.
        - >-
          When changing responsibleId, consider whether the new assignee should
          be notified — this API call does not send notifications automatically.
        - >-
          If both startAt and finishAt are provided, ensure startAt is
          chronologically before finishAt.
        - >-
          Updating tags or observers replaces the entire array, not appends —
          warn the user if they intend to add a single tag without losing
          existing ones.
        - >-
          parentId establishes a subtask relationship; verify the parent task is
          not itself a subtask to avoid deep nesting issues.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were changed by echoing the updated task data
          from the response.
        - >-
          If the step was changed, describe the new pipeline stage in plain
          language (e.g., 'Task moved to In Review').
        - >-
          If priority was updated, mention the new priority level by name, not
          just its integer value.
        - >-
          Suggest follow-up actions such as notifying the assignee or setting a
          reminder if a deadline was changed.
      x-ai-suggestions:
        - >-
          Change task priority to high: set priority to the corresponding
          TaskPriorityProperty value.
        - 'Move task to next pipeline stage: update stepId to the target step.'
        - 'Reassign task: update responsibleId to the new user''s ID.'
        - >-
          Extend deadline: update finishAt with the new date in Y-m-d H:i
          format.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to overwrite task fields. Confirm the changes before
            proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Tasks
      summary: Delete task by ID
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteTask
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Permanently removes a task from the system by its unique identifier.
        This is a destructive, irreversible operation — the task and all
        associated metadata are deleted. Use when a task is cancelled, created
        by mistake, or no longer relevant to the workflow.
      x-ai-reasoning-instructions:
        - >-
          Verify the taskId exists before attempting deletion to avoid
          misleading 404 errors.
        - >-
          Check if the task has dependent subtasks or linked entities that may
          be orphaned after deletion.
        - >-
          Confirm with the user that deletion is intentional — this action
          cannot be undone.
        - >-
          Prefer archiving or status-change over deletion if the task history
          needs to be preserved.
      x-ai-responding-instructions:
        - >-
          Confirm the deletion was successful (HTTP 204 means no content —
          explicitly tell the user the task is gone).
        - >-
          If the task was not found (404), clarify that it may have already been
          deleted.
        - >-
          Suggest listing remaining tasks or verifying the parent entity after
          deletion.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: This will permanently delete the task. This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDeletion
  /tasks/{taskId}/parent:
    post:
      tags:
        - Tasks
      summary: Set/unset the parent task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                parentId:
                  type:
                    - number
                    - 'null'
                  description: Parent task ID or null
      responses:
        '200':
          description: Successfully
      operationId: setTaskParent
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Establishes or removes the hierarchical relationship between tasks.
        Setting a parent converts a standalone task into a subtask within a tree
        structure, enabling nested task management and dependency tracking.
        Passing null explicitly detaches the task, making it a top-level item
        again.
      x-ai-reasoning-instructions:
        - >-
          Verify the target task (taskId) exists before attempting to set or
          unset its parent.
        - >-
          Confirm the parentId task exists and is not the same as taskId to
          avoid self-referencing.
        - >-
          Check for circular dependency: the proposed parent must not itself be
          a descendant of taskId.
        - >-
          If parentId is null, treat this as an explicit unset — the task will
          become a root-level task.
        - >-
          Consider whether the parent task is closed or archived before nesting
          under it.
      x-ai-responding-instructions:
        - >-
          Confirm whether the parent was set or removed based on the value of
          parentId.
        - >-
          If parentId was set, mention the new hierarchy (e.g., 'Task #X is now
          a subtask of Task #Y').
        - If parentId was null, confirm the task is now a top-level task.
        - >-
          Suggest reviewing the task tree or listing subtasks of the new parent
          as a follow-up.
      x-ai-suggestions:
        - 'Pass parentId: null to detach the task from its current parent.'
        - Use this endpoint after creating a subtask to establish hierarchy.
        - Combine with task listing to verify the updated tree structure.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to change the parent of task #{taskId}. This affects
            its position in the task hierarchy.
        security_info:
          data_handling:
            - ResourceStateUpdate
  /tasks/{taskId}/steps/{stepId}/order:
    post:
      tags:
        - Tasks
      summary: Change task order
      description: >-
        Changes order of a task in the current step or in another. newStepId
        field is optional
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: stepId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                order:
                  type: number
                  minimum: 1
                  description: Task order in step
                newStepId:
                  type: number
                  description: New step ID
              required:
                - order
      responses:
        '200':
          description: Successfully changed
      operationId: changeTaskStepOrder
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Repositions a task within the current step or moves it to a different
        step by specifying a new order index. This is the primary mechanism for
        drag-and-drop-style reordering in kanban or pipeline boards — a
        sequence-sensitive operation that affects the visual priority of all
        sibling tasks.
      x-ai-reasoning-instructions:
        - >-
          Verify the target task and step IDs exist before calling — invalid IDs
          return errors without partial changes.
        - >-
          If `newStepId` is provided, confirm the destination step belongs to
          the same board/pipeline as the source step.
        - >-
          Order values are 1-based; if the user wants to move a task to the top,
          use order=1.
        - >-
          When moving between steps, the semantic meaning changes — inform the
          user that the task's status/stage may change as a result.
      x-ai-responding-instructions:
        - >-
          Confirm that the task was successfully repositioned, mentioning both
          taskId and the effective stepId (new or original).
        - >-
          If `newStepId` was used, explicitly note that the task was moved to a
          different step, not just reordered.
        - >-
          On error, clarify whether the problem was with the task ID, step ID,
          or the order value being out of range.
      x-ai-suggestions:
        - To move a task to the top of a step, set order=1.
        - >-
          To move a task to another step without changing relative position, use
          `newStepId` with the current order value.
        - >-
          Fetch the current task list first to determine valid order range
          before repositioning.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /tasks/{taskId}/comments:
    post:
      tags:
        - Task Comments
      summary: Add comment to task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                message:
                  type: string
                  description: Comment message
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskComment'
      operationId: addTaskComment
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Adds a contextual comment to a specific task, enabling team
        collaboration and communication within the task lifecycle. Comments
        serve as an audit trail of decisions, blockers, and progress updates —
        critical for async workflows where stakeholders need to stay aligned
        without direct communication.
      x-ai-reasoning-instructions:
        - >-
          Verify the taskId exists and is accessible before attempting to post a
          comment.
        - >-
          Ensure the message is non-empty and meaningful — discourage
          placeholder or test comments in production contexts.
        - >-
          If the user is reporting a blocker or status update, suggest also
          updating the task status or assignee accordingly.
        - >-
          Consider whether the comment should mention specific team members (if
          @mentions are supported) to trigger notifications.
      x-ai-responding-instructions:
        - >-
          Confirm successful comment creation by referencing the new comment ID
          and the task it was added to.
        - >-
          If the comment relates to a blocker or decision, suggest updating the
          task status or priority as a follow-up.
        - >-
          On error, clarify whether the issue is with the taskId (not found / no
          access) or the message content.
      x-ai-suggestions:
        - 'Blocked: waiting for design approval before proceeding.'
        - 'Status update: implementation complete, moving to QA.'
        - 'Question for assignee: should this handle edge case X?'
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /tasks/{taskId}/comments/{commentId}:
    put:
      tags:
        - Task Comments
      summary: Update comment in task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: commentId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                message:
                  type: string
                  description: Comment message
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskComment'
      operationId: updateTaskComment
      x-ai-role: project_collaboration_specialist
      x-ai-description: >-
        Updates the text of an existing comment on a task. Use this to correct
        mistakes, add clarifications, or refine previously submitted feedback
        within a task thread. Modifying a comment does not change its position
        in the thread or its author.
      x-ai-reasoning-instructions:
        - >-
          Confirm that both taskId and commentId are valid and belong to the
          same task before attempting the update.
        - >-
          Verify that the authenticated user is the author of the comment or has
          sufficient permissions to edit it.
        - >-
          Ensure the new message is non-empty and meaningfully different from
          the existing content to avoid a no-op update.
        - >-
          If the user wants to delete content rather than update it, redirect
          them to the delete comment endpoint instead.
      x-ai-responding-instructions:
        - >-
          Confirm the update was successful and show the updated comment content
          from the response.
        - >-
          Mention the commentId and taskId so the user can reference the change
          unambiguously.
        - >-
          If a 403 or 404 error occurs, clarify whether the issue is missing
          permissions or a non-existent resource.
      x-ai-suggestions:
        - Fixed typo in the original comment.
        - Added clarification based on team feedback.
        - Updated status note after task progress.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /task-tags/{tagId}/task/{taskId}:
    delete:
      tags:
        - Task Tags
      summary: Detach tag from a task
      parameters:
        - name: tagId
          in: path
          required: true
          schema:
            type: integer
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: detachTagFromTask
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Removes a label association from a specific task without deleting either
        the tag or the task. This is a pure relational operation — it only
        severs the link between the two entities. Useful for re-categorizing
        tasks, cleaning up stale labels, or reorganizing project taxonomy
        without data loss.
      x-ai-reasoning-instructions:
        - >-
          Confirm both tagId and taskId exist before attempting the operation to
          avoid ambiguous 404 errors.
        - >-
          Warn the user that this action is irreversible — the tag must be
          re-attached manually if removed by mistake.
        - >-
          If the tag is not currently attached to the task, the API may still
          return 204 — clarify this behavior to avoid false confidence.
        - >-
          Consider whether the user intends to detach this tag from all tasks or
          just this one before proceeding.
      x-ai-responding-instructions:
        - >-
          Confirm the detachment by referencing both the tag ID and the task ID
          in the response.
        - >-
          Since the response body is empty (204), explicitly state that the
          operation was successful.
        - >-
          Suggest verifying the task's current tags via a GET endpoint if the
          user needs confirmation.
        - >-
          Offer to detach additional tags or re-attach a different tag as a
          logical next step.
      x-ai-suggestions:
        - >-
          Use GET /tasks/{taskId}/tags to verify remaining tags after
          detachment.
        - >-
          Use POST /task-tags/{tagId}/task/{taskId} to re-attach the tag if
          removed by mistake.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently detach tag #{tagId} from task #{taskId}.
            Proceed?
        security_info:
          data_handling:
            - RelationalDelete
  /task-tags:
    get:
      tags:
        - Task Tags
      summary: Get task tags list
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/TaskTag'
      operationId: getTaskTags
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Retrieves the full list of tags available for tasks. Tags serve as a
        lightweight classification layer in task management, enabling filtering,
        grouping, and workflow automation across projects.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint to populate tag selection UI or validate tag
          existence before assigning to a task.
        - >-
          Cache the result if making multiple tag-related operations in a single
          session to reduce redundant calls.
        - >-
          If the returned list is empty, inform the user that no tags exist yet
          and suggest creating one.
      x-ai-responding-instructions:
        - >-
          Present the tags as a named list, highlighting IDs that will be needed
          for subsequent task assignment calls.
        - >-
          If the list is long, suggest filtering or searching by name on the
          client side.
        - >-
          Suggest using the tag IDs from this response when creating or updating
          tasks.
      x-ai-suggestions:
        - >-
          Use returned tag IDs with task create/update endpoints to categorize
          work.
        - >-
          Cross-reference with task list endpoints to filter tasks by specific
          tags.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Task Tags
      summary: Create a task tag
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  minLength: 1
                  maxLength: 64
                  description: Tag name
                color:
                  type: string
                  description: Tag color
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskTag'
      operationId: createTaskTag
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Creates a named, color-coded label used to categorize and filter tasks
        across projects. Tags are a lightweight taxonomy layer — they enable
        cross-project grouping without changing task hierarchy. Color selection
        directly affects visual scannability in task boards and lists.
      x-ai-reasoning-instructions:
        - >-
          Before creating, check if a tag with the same name already exists to
          avoid duplicates.
        - >-
          Suggest using consistent naming conventions (e.g., snake_case or Title
          Case) aligned with the team's existing tags.
        - >-
          If no color is provided, inform the user that a default color may be
          assigned and suggest picking one for better visual distinction.
        - >-
          Validate that the name is between 1 and 64 characters before
          submitting.
      x-ai-responding-instructions:
        - Confirm the new tag was created by referencing its name and color.
        - Suggest applying the tag to existing tasks as an immediate next step.
        - >-
          If creation fails due to a duplicate name, list similar existing tags
          and ask the user to confirm intent.
      x-ai-suggestions:
        - bug
        - high-priority
        - needs-review
        - blocked
        - release-1.0
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /task-tags/{tagId}:
    put:
      tags:
        - Task Tags
      summary: Update a task tag
      parameters:
        - name: tagId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Tag name
                color:
                  type: string
                  description: Tag color
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskTag'
      operationId: updateTaskTag
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Updates metadata of an existing task tag — its display name and color
        coding. Tags in task management systems serve as lightweight
        categorization primitives; renaming or recoloring a tag propagates the
        change across all tasks it is attached to, making this a high-impact
        operation for workspace organization.
      x-ai-reasoning-instructions:
        - >-
          Verify the tagId exists before attempting the update to provide a
          clear error message.
        - >-
          If only one field is provided (name or color), confirm the other field
          will remain unchanged.
        - >-
          Check whether the new name conflicts with an existing tag name in the
          same workspace to avoid ambiguity.
        - >-
          For color values, ensure the format is consistent with what the system
          expects (e.g., hex code like '#FF5733').
      x-ai-responding-instructions:
        - Confirm which fields were updated and display the resulting tag state.
        - >-
          If the tag name was changed, remind the user that all tasks
          referencing this tag will reflect the new name.
        - >-
          Suggest reviewing tasks associated with this tag if the update was
          part of a broader reorganization.
      x-ai-suggestions:
        - >-
          Use descriptive tag names like 'Urgent', 'Blocked', or 'In Review' for
          workflow clarity.
        - >-
          Standardize color coding by priority: red for blockers, yellow for
          warnings, green for done.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Task Tags
      summary: Delete a task tag
      parameters:
        - name: tagId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteTaskTag
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Permanently removes a task tag from the system. Tags are used to
        categorize and filter tasks across projects — deleting a tag will unlink
        it from all associated tasks, potentially affecting existing filters,
        automations, and reporting that rely on this tag.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, verify the tag exists and the provided tagId is
          correct.
        - >-
          Warn the user that this action will remove the tag from all tasks it
          is currently assigned to.
        - >-
          Check if the tag is used in any active filters, views, or automations
          before proceeding.
        - >-
          This action is irreversible — confirm the user's intent if the tag
          appears to be widely used.
      x-ai-responding-instructions:
        - >-
          Confirm successful deletion with a clear message referencing the
          tagId.
        - >-
          Remind the user that the tag has been unlinked from all associated
          tasks.
        - >-
          If the tag is not found (404), clarify that it may have already been
          deleted or the ID is incorrect.
        - >-
          Suggest reviewing remaining tags or recreating the tag if deleted by
          mistake.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently delete the tag and remove it from all
            associated tasks.
        security_info:
          data_handling:
            - ResourceDestruction
  /task-contacts/{taskId}/contact/{contactId}:
    delete:
      tags:
        - Task Entity
      summary: Detach a contact from a task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: detachContactFromTask
      x-ai-role: crm_task_manager
      x-ai-description: >-
        Removes the association between a specific contact and a task without
        deleting either entity. Use this when a contact is no longer relevant to
        a task — for example, a deal fell through or the contact was assigned to
        the wrong task. The operation is non-destructive to the contact or task
        record itself.
      x-ai-reasoning-instructions:
        - >-
          Confirm that both taskId and contactId exist before attempting
          detachment to provide a clear error if either is missing.
        - >-
          Warn the user if this is the last contact on the task — the task may
          become orphaned without any associated contacts.
        - >-
          Distinguish clearly from contact deletion: this only removes the
          task-contact relationship.
      x-ai-responding-instructions:
        - >-
          Confirm the contact was successfully detached from the task (204 means
          no body — explicitly acknowledge success).
        - >-
          Suggest verifying remaining contacts on the task via the appropriate
          list endpoint.
        - >-
          If the user seems to be doing bulk cleanup, suggest iterating over all
          task contacts rather than calling one by one.
      x-ai-suggestions:
        - >-
          Use GET /task-contacts/{taskId} to retrieve all contacts still linked
          to the task after detachment.
        - >-
          If the intent is to reassign rather than remove, first attach the new
          contact before detaching the old one.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will remove contact {contactId} from task {taskId}. The contact
            record itself will not be deleted.
        security_info:
          data_handling:
            - RelationshipDelete
  /task-deals/{taskId}/deal/{dealId}:
    delete:
      tags:
        - Task Entity
      summary: Detach a deal from a task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: dealId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: detachDealFromTask
      x-ai-role: crm_pipeline_specialist
      x-ai-description: >-
        Removes the association between a specific deal and a task without
        deleting either entity. This is a relationship management operation —
        the deal and task continue to exist independently after detachment. Use
        when a deal is no longer relevant to the task's scope or was linked by
        mistake.
      x-ai-reasoning-instructions:
        - >-
          Verify that the deal is currently linked to the task before attempting
          detachment to avoid misleading 404 errors.
        - >-
          Warn the user that this action is non-reversible via API — the link
          must be manually re-created if needed.
        - >-
          If the task has only one deal attached, consider whether detaching
          leaves the task without necessary context.
      x-ai-responding-instructions:
        - >-
          Confirm successful detachment by referencing both the taskId and
          dealId.
        - >-
          Clarify that neither the task nor the deal was deleted — only their
          association was removed.
        - >-
          Suggest verifying the task's remaining deals or updating the task
          status if the detached deal was the primary one.
      x-ai-suggestions:
        - Use `getTaskDeals` to list remaining deals after detachment.
        - >-
          If the deal was linked incorrectly, use `attachDealToTask` to
          re-establish the correct association.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the link between task {{taskId}} and
            deal {{dealId}}. Proceed?
        security_info:
          data_handling:
            - RelationshipDelete
  /task-to-task/{taskHeadId}/task/{taskId}:
    delete:
      tags:
        - Task Entity
      summary: Detach task from another task
      parameters:
        - name: taskHeadId
          in: path
          required: true
          description: Parent task ID
          schema:
            type: integer
        - name: taskId
          in: path
          required: true
          description: Child task ID
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: detachTaskFromTask
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Removes a dependency or hierarchical link between two tasks without
        deleting the tasks themselves. This is a structural operation that
        reshapes the task graph — useful when a subtask needs to be promoted to
        standalone or reassigned under a different parent.
      x-ai-reasoning-instructions:
        - >-
          Confirm that both taskHeadId (parent) and taskId (child) exist before
          attempting the detachment.
        - >-
          Warn the user that detaching may affect dependent workflows or task
          ordering if the child task had sequencing constraints inherited from
          the parent.
        - >-
          Check whether the child task has other parent links — if not, it will
          become a root-level task after detachment.
      x-ai-responding-instructions:
        - >-
          Confirm the detachment by restating which child task was unlinked from
          which parent.
        - >-
          Suggest verifying the task structure afterward using a task retrieval
          endpoint to confirm the new hierarchy.
        - >-
          If the intent was to delete the child task entirely, clarify that this
          operation only unlinks — not deletes.
      x-ai-suggestions:
        - Use after reassigning a subtask to a different parent task.
        - Use when flattening a task hierarchy during project restructuring.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Confirm detachment of task {taskId} from parent task {taskHeadId}.
            This will not delete either task.
        security_info:
          data_handling:
            - RelationshipRemoval
  /tasks/{taskId}/entity-attach:
    post:
      tags:
        - Task Entity
      summary: Attach entity to task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                connections:
                  type: object
                  properties:
                    dealIds:
                      type: array
                      example: '[ 1,2 ]'
                    contactIds:
                      type: array
                      example: '[ 1,2 ]'
                    taskIds:
                      type: array
                      example: '[ 1,2 ]'
                    subTasksIds:
                      type: array
                      example: '[ 1,2 ]'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TasksConnection'
      operationId: attachEntitiesToTask
      x-ai-role: crm_workflow_coordinator
      x-ai-description: >-
        Links related CRM entities — deals, contacts, other tasks, or subtasks —
        to a specific task, forming explicit relationships within the CRM graph.
        This is a structural operation: it does not create entities, but wires
        existing ones together to give the task its relationship context,
        enabling cross-entity visibility and workflow traceability.
      x-ai-reasoning-instructions:
        - >-
          Verify that the target task (taskId) exists before attempting to
          attach entities.
        - >-
          Validate that all IDs in each array (dealIds, contactIds, taskIds,
          subTasksIds) refer to existing entities — attaching non-existent IDs
          may silently fail or return partial results.
        - >-
          Avoid attaching a task to itself via taskIds to prevent circular
          references.
        - >-
          Consider the business intent: is the user linking a deal because this
          task is part of a sales pipeline? If so, confirm the correct dealId.
        - >-
          Multiple entity types can be attached in a single call — batch them to
          minimize API calls.
      x-ai-responding-instructions:
        - >-
          Confirm which entity types were successfully attached and reference
          the taskId.
        - >-
          If the response includes a TasksConnection object, summarize which
          entities are now linked.
        - >-
          Suggest a follow-up action such as viewing the task detail or
          triggering a status update on the linked deal.
      x-ai-suggestions:
        - >-
          Attach a contact and deal simultaneously if the task is part of a
          sales workflow.
        - >-
          Use subTasksIds to build hierarchical task breakdowns under a parent
          task.
        - >-
          After attaching, retrieve the task to confirm the full connection
          graph.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Confirm attaching the specified entities to task #{taskId}. This
            will create persistent relationships in the CRM.
        security_info:
          data_handling:
            - RelationshipStateUpdate
  /tasks/{taskId}/checklists/single:
    post:
      tags:
        - Task Checklist
      summary: Create checklist without items in task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Checklist name
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      taskId:
                        type: integer
                      order:
                        type: number
      operationId: createTaskChecklist
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Creates an empty checklist container within a specific task. A checklist
        in this context is a named grouping structure — a shell without items —
        intended to be populated separately. This is useful when you need to
        define the checklist structure upfront before the items are known, or
        when building task templates programmatically.
      x-ai-reasoning-instructions:
        - >-
          Verify the taskId exists and is accessible before attempting to create
          the checklist.
        - >-
          Check if a checklist with the same name already exists in the task to
          avoid duplication.
        - >-
          Note that this endpoint creates an empty checklist — items must be
          added via a separate endpoint after creation.
        - >-
          The 'order' field in the response indicates display position; plan
          accordingly if multiple checklists exist on the task.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by referencing the new checklist ID and
          its name.
        - >-
          Remind the user that the checklist is currently empty and items need
          to be added separately.
        - >-
          Suggest the next logical step: adding checklist items using the
          appropriate endpoint.
      x-ai-suggestions:
        - Definition of Done
        - Pre-launch Checklist
        - QA Steps
        - Review Criteria
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /tasks/{taskId}/checklists/{checklistId}/single:
    put:
      tags:
        - Task Checklist
      summary: Update checklist without items in task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: checklistId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Checklist name
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      taskId:
                        type: integer
                      order:
                        type: number
      operationId: updateTaskChecklistSingle
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Updates the metadata of a checklist (name only) without affecting its
        items. Use this endpoint when you need to rename a checklist while
        preserving all existing items and their completion states. Operates on
        the checklist container itself — not on its child items.
      x-ai-reasoning-instructions:
        - >-
          Verify that both taskId and checklistId exist before attempting the
          update.
        - >-
          Distinguish this endpoint from item-level update endpoints — this only
          modifies the checklist name, not its items.
        - >-
          If the user wants to rename a checklist, confirm the new name is
          meaningful and unique within the task context.
        - >-
          If no name is provided in the request body, warn the user that the
          update may have no effect.
      x-ai-responding-instructions:
        - >-
          Confirm the update by echoing the new checklist name and its ID from
          the response.
        - Mention that items inside the checklist remain unchanged.
        - >-
          If the task or checklist is not found, explain that the IDs may be
          incorrect or the resources may have been deleted.
      x-ai-suggestions:
        - Definition of Done
        - Pre-launch Checklist
        - QA Verification Steps
        - Deployment Checklist
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /tasks/{taskId}/checklists:
    get:
      tags:
        - Task Checklist
      summary: Get checklist list by task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskChecklist'
      operationId: getTaskChecklists
      x-ai-role: project_management_assistant
      x-ai-description: >-
        Retrieves all checklists associated with a specific task. Checklists are
        sub-structures within a task that break down work into verifiable steps.
        Use this to audit task completion progress or to present a structured
        view of task requirements to the user.
      x-ai-reasoning-instructions:
        - >-
          Verify that the taskId exists before requesting its checklists to
          provide a meaningful error message if the task is not found.
        - >-
          If the response returns an empty list, clarify whether the task has no
          checklists yet versus the task itself being invalid.
        - >-
          Consider whether the user needs the checklist items (sub-entries) as
          well — this endpoint returns checklist containers, not individual
          checklist items.
      x-ai-responding-instructions:
        - Present the checklists with their names and IDs in a readable format.
        - >-
          If no checklists are returned, suggest creating one using the
          appropriate POST endpoint.
        - >-
          Highlight the total count of checklists to give the user a quick
          overview of task complexity.
      x-ai-suggestions:
        - Use the returned checklist IDs to fetch individual checklist items.
        - >-
          Combine with task details endpoint to provide full task context
          alongside its checklists.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Task Checklist
      summary: Create multiple checklists with items in task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                checklists:
                  type: array
                  items:
                    type: object
                    properties:
                      name:
                        type: string
                        description: Checklist name
                      items:
                        type: array
                        items:
                          properties:
                            name:
                              type: string
                              description: Checklist item name
                            isDone:
                              type: number
                              description: >-
                                Is checklist item done (checked). 0 - no, 1 -
                                yes
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskChecklist'
      operationId: createTaskChecklists
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Initializes one or more structured checklists within a specific task,
        each containing an ordered list of actionable items. In SendPulse CRM
        tasks, checklists serve as micro-workflows — they break down a task into
        verifiable steps and allow tracking granular completion state. This is a
        bulk creation endpoint, meaning multiple checklists can be bootstrapped
        in a single call, which is ideal for templated task structures.
      x-ai-reasoning-instructions:
        - >-
          Verify that the taskId exists and is accessible before attempting
          creation.
        - >-
          If the user describes a multi-step process, suggest splitting it into
          separate named checklists rather than one long list.
        - >-
          Warn if any checklist has an empty `name` or no `items` array, as this
          creates an empty checklist with no tracking value.
        - >-
          If `isDone: 1` is passed for items on creation, clarify that this
          pre-marks items as completed — usually only appropriate when migrating
          existing data.
      x-ai-responding-instructions:
        - >-
          Confirm how many checklists were created and reference the parent task
          ID.
        - >-
          Highlight the returned checklist IDs so the user can use them for
          future updates or deletions.
        - >-
          If any checklist items were pre-marked as done, acknowledge this
          explicitly to avoid confusion.
        - >-
          Suggest using the checklist update endpoint to modify individual item
          states as work progresses.
      x-ai-suggestions:
        - >-
          Use separate checklists per responsibility area (e.g., 'Design',
          'Development', 'QA') for clearer ownership.
        - 'Pre-populate `isDone: 1` only when importing existing completed work.'
        - >-
          Keep checklist item names action-oriented: 'Write unit tests' rather
          than 'Unit tests'.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    put:
      tags:
        - Task Checklist
      summary: Update multiple checklists with items in task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                checklists:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: number
                      name:
                        type: string
                        description: Checklist name
                      items:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            name:
                              type: string
                              description: Checklist item name
                            isDone:
                              type: number
                              description: >-
                                Is checklist item done (checked). 0 - no, 1 -
                                yes
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TaskChecklist'
      operationId: updateTaskChecklists
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Performs a bulk replacement of all checklist structures within a task.
        This is not a partial update — the entire checklists array is replaced.
        Use this endpoint to synchronize checklist state (names, items,
        completion flags) after local edits, or to programmatically advance task
        progress by marking items as done.
      x-ai-reasoning-instructions:
        - >-
          This is a full-replace operation: omitting a checklist from the array
          may remove it — confirm the full desired state before sending.
        - >-
          Retrieve the current checklists first (GET /tasks/{taskId}/checklists)
          to avoid accidental data loss.
        - >-
          When marking items as done, use isDone: 1; to uncheck use isDone: 0 —
          do not omit the field.
        - >-
          If only one checklist needs updating, still include all other
          checklists in the payload to preserve them.
        - >-
          Validate that all checklist and item IDs exist on the task before
          submitting — unknown IDs may cause silent errors or rejection.
      x-ai-responding-instructions:
        - >-
          Confirm which checklists were updated and how many items were
          affected.
        - >-
          If any items were marked as done, summarize progress (e.g., '3 of 5
          items completed').
        - >-
          Suggest verifying task completion status if all checklist items are
          now marked done.
        - >-
          On error, clarify whether the issue is a missing taskId, invalid
          checklist ID, or payload structure problem.
      x-ai-suggestions:
        - >-
          Fetch current state with GET /tasks/{taskId}/checklists before
          updating to build a safe payload.
        - After updating, check overall task progress with GET /tasks/{taskId}.
        - >-
          Use isDone: 1 to bulk-complete items when a sprint or phase is
          finished.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This operation replaces all checklists on the task. Confirm the full
            payload includes all checklists you want to retain.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PotentialDataLoss
  /tasks/{taskId}/checklists/{checklistId}:
    delete:
      tags:
        - Task Checklist
      summary: Delete a checklist from a task
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: checklistId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteTaskChecklist
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Permanently removes a specific checklist from a task. A checklist is a
        structured sub-list of completion criteria within a task — deleting it
        removes all its items and their completion state. This is a destructive,
        irreversible operation that affects task progress tracking.
      x-ai-reasoning-instructions:
        - >-
          Before deletion, confirm the user understands that all checklist items
          and their completion states will be permanently lost.
        - >-
          Verify that taskId and checklistId are valid integers and belong to
          the same task context.
        - >-
          Consider whether the checklist contains incomplete items — if so, warn
          the user before proceeding.
        - >-
          Check if the checklist is the last one on the task, as removing it may
          impact task completion percentage.
      x-ai-responding-instructions:
        - Confirm the deletion with the specific checklistId that was removed.
        - >-
          Remind the user that this action is irreversible and the data cannot
          be recovered.
        - >-
          If relevant, suggest recreating the checklist via the create checklist
          endpoint if deletion was accidental.
        - >-
          On 204 response, explicitly state that no content is returned — this
          is the expected success behavior.
      x-ai-suggestions:
        - To recreate, use the POST /tasks/{taskId}/checklists endpoint.
        - >-
          Use GET /tasks/{taskId}/checklists to verify remaining checklists
          after deletion.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete the checklist and all its items. This
            action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - ResourceStateUpdate
  /checklists/{checklistId}/items:
    post:
      tags:
        - Checklist Items
      summary: Create items for checklist
      parameters:
        - name: checklistId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Checklist item name
                isDone:
                  type: number
                  description: Is checklist item done (checked). 0 - no, 1 - yes
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      isDone:
                        type: integer
                      order:
                        type: number
      operationId: createChecklistItems
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Adds one or more actionable items to an existing checklist, extending
        its task structure. In SendPulse CRM, checklist items are the atomic
        units of work tracking within a checklist — each represents a discrete
        task with a completion state. This endpoint is used to populate a newly
        created checklist or extend an existing one with additional steps.
      x-ai-reasoning-instructions:
        - >-
          Verify the target checklist exists before attempting to add items; use
          the checklist retrieval endpoint if the ID is uncertain.
        - >-
          If the user provides a list of tasks to add, batch them into a single
          request where the API supports arrays, or iterate sequentially.
        - >-
          When `isDone` is not specified, default to 0 (not completed) — do not
          assume a task is pre-completed unless explicitly stated.
        - >-
          Check whether the checklist already contains an item with the same
          name to avoid duplicate entries.
      x-ai-responding-instructions:
        - Confirm successful creation by reporting the new item's ID and name.
        - >-
          If `isDone: 1` was passed, note that the item was created already
          marked as completed.
        - >-
          Suggest marking items done via the update endpoint once the
          corresponding task is finished.
        - >-
          On error, clarify whether the issue is a missing checklist (invalid
          `checklistId`) or a validation problem with the item payload.
      x-ai-suggestions:
        - Send follow-up email to client
        - Prepare contract draft
        - Schedule kick-off call
        - Review proposal
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /checklists/{checklistId}/items/{itemId}:
    post:
      tags:
        - Checklist Items
      summary: Change order of item in checklist
      parameters:
        - name: checklistId
          in: path
          required: true
          schema:
            type: integer
        - name: itemId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                order:
                  type: number
      responses:
        '200':
          description: Successfully
      operationId: reorderChecklistItem
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Reorders a specific item within a checklist by updating its position
        index. Ordering affects how items are displayed and prioritized in task
        views — use this when automating task sequencing or responding to
        user-driven drag-and-drop reordering.
      x-ai-reasoning-instructions:
        - >-
          Verify that both checklistId and itemId exist before attempting
          reorder to avoid silent failures.
        - >-
          Check the current item order before submitting to avoid redundant
          requests if the item is already in the desired position.
        - >-
          Consider whether other items' positions will shift automatically or
          require explicit updates — clarify with the user if sequencing is
          critical.
      x-ai-responding-instructions:
        - Confirm the item was moved to the requested position.
        - >-
          If the order value conflicts with existing items, explain how the
          system resolves the conflict (shift vs. override).
        - >-
          Suggest retrieving the updated checklist to verify the new item
          sequence.
      x-ai-suggestions:
        - 'Use order: 1 to promote the item to the top of the checklist.'
        - >-
          After reordering, call getChecklist to confirm the updated item
          sequence.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    put:
      tags:
        - Checklist Items
      summary: Update checklist item
      parameters:
        - name: checklistId
          in: path
          required: true
          schema:
            type: integer
        - name: itemId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Checklist item name
                isDone:
                  type: number
                  description: Is checklist item done (checked). 0 - no, 1 - yes
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      isDone:
                        type: integer
                      order:
                        type: number
      operationId: updateChecklistItem
      x-ai-role: task_management_specialist
      x-ai-description: >-
        Updates the state or label of a specific item within a checklist. This
        endpoint is the primary mechanism for tracking task completion —
        toggling `isDone` marks progress without deleting history. Used by
        agents to reflect real-time workflow status changes driven by user
        actions or automation triggers.
      x-ai-reasoning-instructions:
        - >-
          Verify that both `checklistId` and `itemId` exist before sending the
          request to avoid cryptic 404 errors.
        - >-
          When toggling `isDone`, treat 1 as 'completed' and 0 as 'reopened' —
          communicate the semantic difference to the user clearly.
        - >-
          If only renaming the item, omit `isDone` from the payload to avoid
          unintentional state changes.
        - >-
          If the user wants to mark multiple items done, issue sequential calls
          — there is no bulk-update endpoint.
      x-ai-responding-instructions:
        - >-
          Confirm which field was changed (name, status, or both) and reflect
          the new value in the response summary.
        - >-
          If `isDone` was set to 1, acknowledge the task as completed and
          suggest reviewing remaining items in the checklist.
        - >-
          If `isDone` was set to 0, frame it as the task being reopened or reset
          for further work.
        - Highlight the returned `id` to confirm the correct item was updated.
      x-ai-suggestions:
        - 'Mark item as done: set `isDone: 1`'
        - 'Reopen item: set `isDone: 0`'
        - 'Rename item without changing status: send only `name`'
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Checklist Items
      summary: Delete checklist items
      parameters:
        - name: checklistId
          in: path
          required: true
          schema:
            type: integer
        - name: itemId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteChecklistItem
      x-ai-role: task_management_specialist
      x-ai-description: >-
        Permanently removes a single item from a checklist by its ID. This is an
        irreversible destructive operation — the item and any associated state
        (completion status, notes) are deleted immediately. Use when the task is
        no longer relevant or was added by mistake.
      x-ai-reasoning-instructions:
        - Confirm the correct itemId before deletion — there is no undo.
        - >-
          If the user refers to an item by name or description rather than ID,
          resolve the ID first via the list items endpoint.
        - >-
          Check whether the item is the last one in the checklist; deleting it
          may leave an empty checklist.
      x-ai-responding-instructions:
        - Confirm the deletion succeeded (204 No Content means success).
        - Do not attempt to display the deleted item — it no longer exists.
        - >-
          If the user may have deleted the wrong item, suggest recreating it or
          reviewing remaining items.
      x-ai-suggestions:
        - >-
          Use GET /checklists/{checklistId}/items to verify remaining items
          after deletion.
        - >-
          If bulk cleanup is needed, consider deleting the entire checklist
          instead.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete checklist item #{itemId}. This action
            cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /tasks/{taskId}/attributes:
    post:
      tags:
        - Task Attributes
      summary: Create attribute value
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                attributeId:
                  type: number
                  description: ID of attribute
                value:
                  description: Attribute value (string or array)
      responses:
        '201':
          description: Successfully
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        attributeable_type:
                          type: string
                        attributeable_id:
                          type: integer
                        value:
                          type: string
                        attribute_id:
                          type: integer
                        user_id:
                          type: integer
                        id:
                          type: integer
      operationId: createTaskAttributeValue
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Assigns a value to a predefined custom attribute for a specific task.
        Attribute values extend the task data model beyond standard fields —
        they enable flexible metadata (priority tiers, custom statuses, linked
        entities) without schema changes. The attributeId must reference an
        existing attribute definition; the value type (scalar or array) depends
        on the attribute's configuration.
      x-ai-reasoning-instructions:
        - >-
          Verify that the taskId exists before attempting to assign an attribute
          value.
        - >-
          Confirm the attributeId refers to a valid, active attribute definition
          — do not guess IDs.
        - >-
          Check whether the attribute accepts a scalar string or an array value;
          passing the wrong type will fail.
        - >-
          If the goal is to update an existing value rather than create a new
          one, use the appropriate PATCH/PUT endpoint instead to avoid
          duplicates.
        - >-
          When value is an array, ensure all items are valid according to the
          attribute's allowed values if the attribute is enum-typed.
      x-ai-responding-instructions:
        - >-
          Confirm success by referencing the returned id and attribute_id from
          the response.
        - >-
          If multiple items are returned in data, summarize how many attribute
          values were created.
        - >-
          On failure, distinguish between 'task not found', 'attribute not
          found', and 'invalid value type' errors and explain each clearly.
        - >-
          Suggest retrieving the full task or listing its attributes as a
          natural next step after creation.
      x-ai-suggestions:
        - >-
          Use getTaskAttributes or listAttributes to obtain a valid attributeId
          before calling this endpoint.
        - For array-type attributes, pass value as a JSON array of strings.
        - >-
          After creation, verify the assignment with a GET
          /tasks/{taskId}/attributes request.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /{boardId}/attributes/{attributeId}/values/{valueId}:
    put:
      tags:
        - Task Attributes
      summary: Update task attribute value
      parameters:
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
        - name: valueId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                value:
                  description: Attribute value (string or array)
      responses:
        '200':
          description: Successfully
      operationId: updateTaskAttributeValue
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Updates a specific predefined value within a task attribute's value set
        on a given board. Use this when the attribute is enumerable (e.g., a
        dropdown list) and an existing option needs to be renamed or corrected —
        without removing and recreating it, which would break existing task
        assignments.
      x-ai-reasoning-instructions:
        - >-
          Confirm the boardId, attributeId, and valueId all exist before sending
          the request — a wrong valueId will produce an error or silently target
          an unintended record.
        - >-
          If the attribute is of array type, the value field should be a JSON
          array; for string-type attributes, pass a plain string.
        - >-
          Check whether other tasks already use this value before updating —
          renaming a shared value affects all tasks that reference it.
      x-ai-responding-instructions:
        - >-
          Confirm that the value was updated and reflect the new value text in
          the response summary.
        - >-
          Remind the user that any tasks already assigned this attribute value
          will now display the updated label.
        - >-
          If the update fails, clarify whether the error is due to an invalid
          ID, a type mismatch, or a permission issue.
      x-ai-suggestions:
        - >-
          Use GET /{boardId}/attributes/{attributeId}/values to retrieve
          existing values before updating.
        - >-
          After updating, call GET /{boardId}/tasks to verify tasks reflect the
          new value correctly.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating this value will affect all tasks on the board that
            reference it. Proceed?
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Task Attributes
      summary: Delete attribute value from task
      parameters:
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
        - name: valueId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully
      operationId: deleteAttributeValue
      x-ai-role: project_management_specialist
      x-ai-description: >-
        Permanently removes a specific predefined value from a task attribute's
        value list on a given board. Use this when cleaning up obsolete or
        incorrect options from dropdown/select-type attributes to keep task data
        consistent and avoid user confusion.
      x-ai-reasoning-instructions:
        - >-
          Verify the attributeId belongs to the specified boardId before
          attempting deletion.
        - >-
          Check if any existing tasks currently use this valueId — deletion may
          affect task data integrity.
        - >-
          Warn the user if the attribute has only one remaining value, as
          removing it may leave the attribute unusable.
        - >-
          Confirm that the valueId is indeed a child of the given attributeId to
          prevent accidental mismatches.
      x-ai-responding-instructions:
        - >-
          On success (204), confirm the value was deleted and mention the
          attributeId it belonged to.
        - Suggest reviewing remaining values of the attribute as a follow-up.
        - >-
          If tasks were referencing this value, advise reassigning them to
          another value via the update task endpoint.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This action permanently deletes the attribute value and cannot be
            undone.
        security_info:
          data_handling:
            - DestructiveOperation
            - ResourceStateUpdate
  /telephony/calls/get-list:
    post:
      tags:
        - Telephony
      summary: Get calls
      requestBody:
        $ref: '#/components/requestBodies/FilterTelephonyCalls'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      total:
                        type: integer
                        description: Total number of calls
                      list:
                        type: array
                        items:
                          $ref: '#/components/schemas/TelephonyCall'
      operationId: getTelephonyCalls
      x-ai-role: telephony_operations_analyst
      x-ai-description: >-
        Retrieves a paginated and filtered list of telephony call records from
        the account. Use this endpoint to audit call activity, analyze
        communication patterns, track campaign performance, or feed call data
        into reporting pipelines. The endpoint uses POST with a filter body
        rather than GET query params — pass all filtering criteria in the
        request body.
      x-ai-reasoning-instructions:
        - >-
          Check available filter fields in FilterTelephonyCalls before
          constructing the request — date range, status, direction, and phone
          number are typical filter axes.
        - >-
          If the user asks for 'all calls', apply a broad date range rather than
          omitting filters, to avoid unexpected default limits.
        - >-
          Use the `total` field in the response to determine if pagination is
          needed and advise accordingly.
        - >-
          If the result set is large, suggest narrowing the date range or
          filtering by status/direction to reduce payload size.
      x-ai-responding-instructions:
        - Report the total number of matching calls alongside the list.
        - >-
          If the list is empty, suggest reviewing the applied filters rather
          than assuming no calls exist.
        - >-
          Summarize key patterns if multiple records are returned (e.g.,
          dominant call status, busiest period).
        - >-
          Suggest follow-up actions such as exporting data or drilling into a
          specific call record.
      x-ai-suggestions:
        - Filter by date range to scope results to a specific campaign period.
        - >-
          Use status filter to isolate failed or missed calls for support
          review.
        - Combine with reporting tools to track call conversion rates.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /contacts/{contactId}/get-calls:
    post:
      tags:
        - Telephony
      summary: Get calls by contact"
      requestBody:
        $ref: '#/components/requestBodies/FilterTelephonyCalls'
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date
                          example: 2022-06-28T00:00:00.000Z
                        calls:
                          type: array
                          items:
                            $ref: '#/components/schemas/TelephonyCall'
      operationId: getContactCalls
      x-ai-role: telephony_analytics_specialist
      x-ai-description: >-
        Retrieves the full call history for a specific CRM contact, grouped by
        date. Use this to analyze communication patterns, measure engagement
        frequency, or audit interaction timelines before escalating a contact or
        preparing a follow-up strategy.
      x-ai-reasoning-instructions:
        - >-
          Verify that the contactId exists before calling — an invalid ID will
          return an empty or error response.
        - >-
          Apply date range filters to narrow results; fetching unbounded call
          history for active contacts may return a large payload.
        - >-
          Consider call direction and status fields in TelephonyCall schema to
          distinguish inbound vs. outbound or missed calls when summarizing
          activity.
      x-ai-responding-instructions:
        - >-
          Summarize the total number of calls and the date range covered by the
          response.
        - >-
          Highlight the most recent call date and any notable patterns (e.g.,
          high call frequency on a specific date).
        - >-
          If the result is empty, inform the user that no calls are recorded for
          this contact and suggest verifying the contactId or broadening the
          filter range.
      x-ai-suggestions:
        - >-
          Filter by a specific date range to review activity before a scheduled
          follow-up.
        - >-
          Use alongside contact details endpoint to build a full communication
          profile.
        - >-
          Cross-reference with CRM deal or task endpoints to correlate calls
          with pipeline stages.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /deals/{dealId}/get-calls:
    post:
      tags:
        - Telephony
      summary: Get calls by deal
      requestBody:
        $ref: '#/components/requestBodies/FilterTelephonyCalls'
      parameters:
        - name: dealId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        date:
                          type: string
                          format: date
                          example: 2022-06-28T00:00:00.000Z
                        calls:
                          type: array
                          items:
                            $ref: '#/components/schemas/TelephonyCall'
      operationId: getDealCalls
      x-ai-role: crm_telephony_analyst
      x-ai-description: >-
        Retrieves the full call history associated with a specific CRM deal.
        This endpoint bridges telephony activity and sales pipeline context —
        enabling agents to correlate communication patterns with deal
        progression, identify follow-up gaps, or audit contact frequency without
        leaving the deal context.
      x-ai-reasoning-instructions:
        - >-
          Verify the dealId exists before querying — a missing deal will return
          no data or an error.
        - >-
          Check if filter parameters (date range, direction, status) are
          provided; if not, the response may include a large unfiltered call
          set.
        - >-
          If the user asks about recent activity, default the filter to the last
          30 days to keep results actionable.
        - >-
          Consider whether the user needs raw call data or a summary — this
          endpoint returns raw records; aggregation must be done client-side.
      x-ai-responding-instructions:
        - Summarize the number of calls returned and the date range covered.
        - Highlight any missed or unanswered calls that may require follow-up.
        - >-
          If the result is empty, suggest verifying the dealId or broadening the
          date filter.
        - >-
          If multiple call dates exist, group results by date for clarity when
          presenting to the user.
      x-ai-suggestions:
        - Filter by date range to narrow results for active deals.
        - Use alongside `getDealContacts` to cross-reference who was called.
        - >-
          If no calls found, suggest logging a new call or checking deal
          assignment.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /deals/{dealId}/attach-call:
    post:
      tags:
        - Telephony
      summary: Attach call to deal
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                callId:
                  type: integer
      parameters:
        - name: dealId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/TelephonyCall'
      operationId: attachCallToDeal
      x-ai-role: crm_telephony_integration_specialist
      x-ai-description: >-
        Links a recorded or logged telephony call to a specific CRM deal,
        creating a traceable communication history. This association is critical
        for sales pipeline visibility — it allows managers and agents to audit
        deal progression through actual conversations, not just manual notes.
      x-ai-reasoning-instructions:
        - Verify that the dealId exists before attempting to attach a call.
        - >-
          Confirm that the callId belongs to the same account context as the
          deal.
        - >-
          If attaching multiple calls to the same deal, consider whether the
          previous call attachment will be overwritten or appended.
        - >-
          Ensure the call has already been recorded/logged before attempting to
          attach it — attaching a non-existent call will fail.
      x-ai-responding-instructions:
        - >-
          Confirm which call was attached to which deal by echoing back dealId
          and callId.
        - Suggest reviewing the deal's full call history as a follow-up action.
        - >-
          If the operation fails, distinguish between a missing deal error and a
          missing call error to guide the user precisely.
      x-ai-suggestions:
        - >-
          Use `getDeals` to retrieve a valid dealId before calling this
          endpoint.
        - Use the telephony call log endpoint to obtain a valid callId.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /deals/{dealId}/expiration:
    put:
      tags:
        - Deal Expiration
      summary: Update or create deal expiration
      parameters:
        - name: dealId
          in: path
          required: true
          description: Deal ID
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                date:
                  type: string
                  format: date
                  description: Expiration date
                time:
                  type: string
                  format: time
                  description: Expiration time
                notifyIn:
                  type:
                    - string
                    - 'null'
                  description: >-
                    Notify before deal expires (when notification is enabled).
                    Allowed values - 0(not selected), 15min, 30min, 1h, 2h, 3h,
                    6h, 12h, 24h, 2d, 3d, 4d, 5d, 6d, 7d
                dealAction:
                  type:
                    - integer
                    - 'null'
                  description: Allowed values 1 - created, 2 - updated
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealExpiration'
      operationId: upsertDealExpiration
      x-ai-role: crm_pipeline_manager
      x-ai-description: >-
        Sets or replaces the expiration deadline for a specific deal in the CRM
        pipeline. This endpoint acts as an upsert — if no expiration exists, it
        creates one; if it does, it overwrites it entirely. Expiration dates
        drive urgency-based automation, sales rep notifications, and deal
        auto-closure workflows. Proper use of this endpoint ensures deals don't
        silently stall in the pipeline past their negotiated deadlines.
      x-ai-reasoning-instructions:
        - >-
          Confirm the dealId exists before calling — a 404 on a missing deal is
          a hard failure.
        - >-
          If the user provides only a date without a time, clarify whether a
          default time (e.g., end-of-business) is acceptable or if precision
          matters.
        - >-
          When notifyIn is set, verify the deal has an assigned owner with a
          valid notification channel; otherwise the reminder will be silently
          dropped.
        - >-
          The dealAction field (1=created, 2=updated) is metadata — infer '2'
          when the deal is known to already have an expiration, '1' when setting
          it for the first time.
        - >-
          Avoid setting expiration dates in the past; validate the date is in
          the future before submitting.
        - >-
          If the user wants to remove an expiration, this endpoint is not the
          right tool — check for a DELETE /deals/{dealId}/expiration instead.
      x-ai-responding-instructions:
        - >-
          Confirm the expiration was set by echoing back the date and time in a
          human-readable format.
        - >-
          If notifyIn was provided, remind the user when the notification will
          fire relative to the expiration.
        - >-
          Suggest reviewing related deals in the same pipeline stage that may
          also need expiration dates.
        - >-
          If the response includes a DealExpiration object, highlight the
          effective deadline and any active notification settings.
      x-ai-suggestions:
        - >-
          Set expiration to end of current quarter with a 24h advance
          notification.
        - >-
          Use notifyIn: '2d' for deals in the negotiation stage to give reps
          buffer time.
        - >-
          Combine with a pipeline stage update to automatically move stalled
          deals to 'Closing' before expiry.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will overwrite any existing expiration for deal {dealId}.
            Proceed?
        security_info:
          data_handling:
            - ResourceStateUpdate
            - ScheduledNotificationTrigger
    delete:
      tags:
        - Deal Expiration
      summary: Remove deal expiration
      parameters:
        - name: dealId
          in: path
          required: true
          description: Deal ID
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: removeDealExpiration
      x-ai-role: crm_deal_manager
      x-ai-description: >-
        Removes the expiration deadline from a deal, effectively making it
        open-ended. Use this when a deal's timeline has been extended
        indefinitely or when a premature expiration was set by mistake. In CRM
        workflows, expiration dates drive automated reminders and stage
        transitions — removing one halts that pressure on the deal.
      x-ai-reasoning-instructions:
        - >-
          Confirm the deal exists and has an active expiration before attempting
          removal — a 204 on a non-expiring deal may still succeed but is a
          no-op.
        - >-
          Check whether any automations or reminders are tied to this deal's
          expiration; removing it may silently disable them.
        - >-
          If the user's intent is to extend the deadline rather than remove it
          entirely, suggest using the update-expiration endpoint instead.
      x-ai-responding-instructions:
        - >-
          On success (204 No Content), confirm that the expiration has been
          cleared and the deal is now open-ended.
        - >-
          Mention that any expiration-triggered automations for this deal are
          now inactive.
        - >-
          If the deal ID is not found or the operation fails, clarify whether
          the deal exists and whether it had an expiration set.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the expiration date from the deal. Any
            automated reminders tied to this deadline will stop.
        security_info:
          data_handling:
            - ResourceStateUpdate
  /contacts/{contactId}/edu-payments:
    get:
      tags:
        - Contacts
      summary: Get EDU payments by contact
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      list:
                        type: array
                        items:
                          type: object
                          properties:
                            courseId:
                              type: integer
                            name:
                              type: string
                            price:
                              type: object
                              properties:
                                amount:
                                  type: integer
                                currency:
                                  type: string
                            status:
                              type: integer
                            paymentMethod:
                              type: string
                              enum:
                                - YooMoney
                                - PayPal
                                - Fondy
                                - ROBOKASSA
                                - Stripe
                                - MERCADOPAGO
                                - LiqPay
                            createdAt:
                              type: string
                              format: date-time
      operationId: getContactEduPayments
      x-ai-role: edu_payments_analyst
      x-ai-description: >-
        Retrieves the full payment history for a specific contact within the EDU
        module. Each record reflects a course purchase attempt or completion,
        including payment method, amount, currency, and current status. Use this
        to audit monetization activity per learner, detect failed or pending
        transactions, and inform support decisions.
      x-ai-reasoning-instructions:
        - >-
          Verify the contactId belongs to a valid CRM contact before calling —
          invalid IDs return empty or error.
        - >-
          The `status` field is an integer enum; map it to human-readable labels
          (e.g., 0=pending, 1=completed, 2=failed) using domain knowledge or
          supplementary documentation.
        - >-
          If the list is empty, it may mean the contact has not made any EDU
          purchases — not that the endpoint failed.
        - >-
          When analyzing payments, group by courseId to detect duplicate
          purchases or retry patterns.
      x-ai-responding-instructions:
        - >-
          Summarize the total number of payments found and highlight any
          non-completed statuses.
        - >-
          Present price as a formatted value with currency (e.g., '500 UAH',
          '9.99 USD').
        - >-
          If multiple payment methods are present, note the variety — it may
          indicate cross-region usage.
        - >-
          Suggest follow-up actions such as checking course enrollment status or
          issuing a refund if failed payments are detected.
      x-ai-suggestions:
        - >-
          Use alongside `getContact` to build a complete learner profile with
          purchase history.
        - >-
          Filter results by `status` to identify contacts with failed payments
          for re-engagement campaigns.
        - >-
          Cross-reference `courseId` with the course catalog to enrich payment
          data with course names and categories.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
            - >-
              PII — contact financial data, handle according to data privacy
              policy
  /contacts/{contactId}/edu-statistic:
    get:
      tags:
        - Contacts
      summary: Get EDU statistics for a contact
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      courses:
                        type: array
                        items:
                          type: object
                          properties:
                            id:
                              type: integer
                            status:
                              type: string
                            statusStudentOnCourse:
                              type: string
                            sections:
                              type: array
                              items:
                                type: object
                                properties:
                                  id:
                                    type: integer
                                  name:
                                    type: string
                                  lessons:
                                    type: array
                                    items:
                                      type: object
                                      properties:
                                        id:
                                          type: integer
                                        name:
                                          type: string
                                        statusStudentOnLesson:
                                          type: object
                                          properties:
                                            status:
                                              type: string
                                            updatedAt:
                                              type: string
                            tests:
                              type: array
                              items:
                                type: object
                                properties:
                                  name:
                                    type: string
                                  score:
                                    type: string
      operationId: getContactEduStatistic
      x-ai-role: edu_progress_analyst
      x-ai-description: >-
        Retrieves a full snapshot of a contact's educational journey within the
        EDU platform — including course enrollment statuses, section/lesson
        completion, and test scores. This is the primary endpoint for auditing
        individual learning progress, identifying blockers, and triggering
        re-engagement flows based on actual study behavior.
      x-ai-reasoning-instructions:
        - >-
          Verify that the contactId belongs to a contact enrolled in at least
          one EDU course before interpreting empty results as an error.
        - >-
          Distinguish between course-level status (e.g., 'active', 'completed')
          and student-on-course status — they may reflect different lifecycle
          states.
        - >-
          When analyzing lesson progress, check statusStudentOnLesson.updatedAt
          to assess recency of activity and identify stalled learners.
        - >-
          Test scores are returned as strings — handle potential null or
          non-numeric values before performing comparisons or aggregations.
      x-ai-responding-instructions:
        - >-
          Summarize overall progress per course before diving into
          section/lesson details.
        - >-
          Highlight any lessons or sections where progress has stalled (no
          recent updatedAt activity).
        - >-
          If test scores are available, present them alongside pass/fail context
          if thresholds are known.
        - >-
          If the response contains no courses, clarify that the contact may not
          be enrolled in any EDU courses rather than implying an error.
      x-ai-suggestions:
        - >-
          Use this endpoint before sending a re-engagement email to check if the
          contact is genuinely inactive.
        - >-
          Combine with contact profile data to build personalized course
          completion reports.
        - >-
          Cross-reference statusStudentOnCourse with lesson-level statuses to
          detect partial completions.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /files/upload:
    post:
      tags:
        - File Manager
      summary: Upload files
      requestBody:
        content:
          multipart/form-data:
            schema:
              type: object
              properties:
                files[]:
                  type: array
                  description: Array of file binaries
                  items:
                    type: string
                    format: binary
      responses:
        '201':
          description: Created successfully
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        link:
                          type: string
      operationId: uploadFiles
      x-ai-role: file_storage_manager
      x-ai-description: >-
        Uploads one or more binary files to SendPulse file storage and returns
        their public URLs. Use these links in email campaigns, landing pages, or
        chatbot messages — anywhere a publicly accessible URL to a hosted asset
        is needed.
      x-ai-reasoning-instructions:
        - >-
          Confirm the user intends to upload binary files, not reference
          already-hosted URLs.
        - >-
          Check whether the files are intended for email content, chatbot flows,
          or landing pages — this context may affect how the returned links are
          used downstream.
        - >-
          Remind the user that multiple files can be uploaded in a single
          request via the `files[]` array.
        - >-
          Advise on common size or format restrictions if the user uploads large
          or unsupported file types.
      x-ai-responding-instructions:
        - Return the list of uploaded file links clearly, one per file.
        - >-
          Suggest the immediate next step based on context — e.g., embedding the
          link into an email template or a chatbot message.
        - >-
          If the upload fails for any file, indicate which file caused the error
          and why.
      x-ai-suggestions:
        - Upload a logo or banner image for use in email campaigns.
        - Upload a PDF attachment to share via email or chatbot.
        - Upload multiple assets in one request for batch hosting.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceCreation
            - PubliclyAccessibleAfterUpload
  /attachments:
    post:
      tags:
        - Attachments
      summary: Attach file
      description: >-
        First, the file must be uploaded to the file manager, and then the file
        can be attached.
      requestBody:
        $ref: '#/components/requestBodies/AttachmentBody'
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/EntityAttachment'
      operationId: createAttachment
      x-ai-role: file_management_specialist
      x-ai-description: >-
        Attaches a previously uploaded file to an entity (e.g., email campaign
        or message). This is a two-step process: the file must first exist in
        the File Manager before it can be referenced here. This endpoint acts as
        the binding layer between a stored asset and its intended usage context.
      x-ai-reasoning-instructions:
        - >-
          Confirm the file has already been uploaded to the File Manager before
          calling this endpoint — attachment will fail if the file does not
          exist.
        - >-
          Retrieve the file URL or identifier from the File Manager response
          prior to invoking this operation.
        - >-
          Validate that the file type is compatible with the target entity
          (e.g., supported MIME types for email attachments).
        - >-
          Be aware of size limits that may apply to attachments depending on the
          delivery channel.
      x-ai-responding-instructions:
        - >-
          Confirm the attachment was created by referencing the returned
          attachment ID or entity details.
        - >-
          If the file was not found or upload was incomplete, instruct the user
          to complete the file upload step first.
        - >-
          Suggest the next logical action, such as linking the attachment to a
          specific campaign or message.
      x-ai-suggestions:
        - >-
          Use `uploadFile` (File Manager) first to obtain the file reference
          before calling this endpoint.
        - >-
          After attaching, associate the attachment with the target resource
          using its returned ID.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /attachments/batch:
    post:
      tags:
        - Attachments
      summary: Create attachment
      description: >-
        First, the file must be uploaded to the file manager, and then the file
        can be attached.
      requestBody:
        content:
          application/json:
            schema:
              properties:
                attachments:
                  type: array
                  items:
                    type: object
                    properties:
                      link:
                        type: string
                      entityId:
                        type: integer
                      entityType:
                        type: string
                        enum:
                          - deal
                          - task
                          - contact
                          - dealComment
                          - taskComment
                          - contactComment
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/EntityAttachment'
      operationId: createAttachmentsBatch
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Batch-links previously uploaded files (from the File Manager) to CRM
        entities such as deals, tasks, or contacts. This is a two-step flow:
        upload file → attach to entity. The endpoint supports heterogeneous
        batches — a single request can attach files to different entity types
        simultaneously, reducing round-trips in automation scenarios.
      x-ai-reasoning-instructions:
        - >-
          Remind the user that files must be uploaded to the File Manager first
          — attachment without a valid file link will fail.
        - >-
          Validate that each item in the batch has a `link`, `entityId`, and
          `entityType` before submitting.
        - >-
          If attaching to multiple entity types in one batch, confirm the user
          intends mixed-entity attachment — it is valid but uncommon.
        - >-
          Check that `entityId` values correspond to existing CRM records;
          attaching to a non-existent entity may silently fail or return a
          partial success.
      x-ai-responding-instructions:
        - >-
          Confirm how many attachments were successfully created from the
          response `data` array.
        - >-
          If the batch is partially successful, clearly indicate which items
          succeeded and which did not.
        - >-
          Suggest verifying attachments by fetching the entity (deal, contact,
          etc.) and checking its attachment list.
      x-ai-suggestions:
        - >-
          Upload files via the File Manager endpoint first, then use the
          returned links here.
        - >-
          Group attachments by entity type for clarity, even though mixed
          batches are supported.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /attachments/{attachmentId}:
    put:
      tags:
        - Attachments
      summary: Update file attachment
      description: >-
        First, the file must be uploaded to the file manager, and then the file
        can be attached.
      parameters:
        - name: attachmentId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        $ref: '#/components/requestBodies/AttachmentUpdateBody'
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/EntityAttachment'
      operationId: updateAttachment
      x-ai-role: content_asset_manager
      x-ai-description: >-
        Updates an existing file attachment by linking it to a new or different
        file from the file manager. This is a two-phase operation: the file must
        first exist in the file manager before it can be referenced here. Use
        this to replace the underlying file of an attachment without changing
        the attachment reference downstream.
      x-ai-reasoning-instructions:
        - >-
          Before calling this endpoint, ensure the target file has already been
          uploaded via the file manager — this endpoint does not accept raw file
          data.
        - >-
          Verify the attachmentId exists and belongs to the current account to
          avoid 404 errors.
        - >-
          If the goal is to swap a file used in active campaigns, warn the user
          that the change may affect in-flight or scheduled sends depending on
          timing.
      x-ai-responding-instructions:
        - >-
          Confirm the update was applied by referencing the attachmentId and the
          new file details from the response.
        - >-
          If the file manager upload step was skipped, guide the user to upload
          the file first before retrying.
        - >-
          Suggest verifying the updated attachment is still correctly referenced
          in any campaigns or templates that use it.
      x-ai-suggestions:
        - >-
          Use `uploadFile` (file manager) to obtain a file reference before
          calling this endpoint.
        - >-
          After updating, call the relevant campaign endpoint to confirm the
          attachment is still correctly linked.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating an attachment will replace the file for all entities
            referencing this attachmentId.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Attachments
      summary: Delete file attachment
      parameters:
        - name: attachmentId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully detached
      operationId: deleteAttachment
      x-ai-role: file_management_specialist
      x-ai-description: >-
        Permanently detaches and removes a file attachment by its ID. Use this
        to clean up uploaded files that are no longer needed, free storage, or
        revoke file access linked to a specific attachment record.
      x-ai-reasoning-instructions:
        - >-
          Confirm the attachmentId exists before attempting deletion to avoid
          misleading 404 errors.
        - >-
          Warn the user that deletion is irreversible — the file cannot be
          recovered after this call.
        - >-
          Check if the attachment is referenced by active campaigns or messages
          before deleting to prevent broken links.
      x-ai-responding-instructions:
        - >-
          Confirm successful deletion with a clear message since the response
          body is empty (204 No Content).
        - >-
          If a 404 is returned, clarify that the attachment may have already
          been deleted or the ID is incorrect.
        - Suggest uploading a replacement file if the deletion was accidental.
      x-ai-suggestions:
        - Use `listAttachments` first to retrieve valid attachmentId values.
        - >-
          After deletion, verify removal by attempting to fetch the attachment —
          expect a 404.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: This action permanently deletes the attachment and cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /companies/short-data:
    post:
      tags:
        - Company
      summary: Get companies short data
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                companyName:
                  type: string
                companyIds:
                  type: array
                email:
                  type: string
                phone:
                  type: string
                responsibleId:
                  type: array
                messengerLogin:
                  type: string
                dateFrom:
                  type: string
                dateTo:
                  type: string
                limit:
                  type: integer
                offset:
                  type: integer
                withoutContacts:
                  type: boolean
                searchString:
                  type: string
                  description: >-
                    If you pass a search string, all other filters will be
                    ignored.
                attributes:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: integer
                      expression:
                        type: string
                sortBy:
                  type: object
                  properties:
                    attributeId:
                      type: integer
                    fieldName:
                      type: string
                      enum:
                        - name
                        - address
                        - annualBusinessVolume
                        - createdAt
                    direction:
                      type: string
                      enum:
                        - asc
                        - desc
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/CompanySortData'
                  metadata:
                    type: object
                    properties:
                      total:
                        type: integer
      operationId: getCompaniesShortData
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves a lightweight, paginated list of companies from the CRM with
        flexible multi-criteria filtering. 'Short data' means only key fields
        are returned — optimized for list views, dropdowns, and bulk lookups.
        Use this endpoint when you need to discover, search, or enumerate
        companies without loading full contact trees or attribute sets. The
        searchString param acts as a global override — when provided, all other
        filters are silently ignored.
      x-ai-reasoning-instructions:
        - >-
          Prefer searchString for freeform user queries (name fragments, email,
          phone) — it's faster and overrides all other filters.
        - >-
          When filtering by attributes, use the attributes array with attribute
          IDs from the CRM schema; do not guess IDs.
        - >-
          Always apply limit+offset for pagination; avoid unbounded queries on
          large datasets.
        - >-
          If responsibleId or companyIds filters are used, confirm the IDs exist
          before calling to avoid empty result sets.
        - >-
          Note that dateFrom/dateTo filter by company creation date — clarify
          with the user if they mean something else (e.g., last activity).
        - >-
          If withoutContacts is true, the response excludes companies that have
          no linked contacts — use this to find active company records only.
      x-ai-responding-instructions:
        - >-
          Report the total count from metadata.total alongside the returned page
          size so the user understands how many records exist overall.
        - >-
          If the result is empty, suggest relaxing filters or switching to
          searchString.
        - >-
          When returning a list, highlight company names and IDs as the primary
          identifiers for follow-up operations.
        - >-
          If searchString was used, note that other filters were ignored in this
          request.
      x-ai-suggestions:
        - Use limit=20 and offset=0 as default pagination values.
        - >-
          To find a specific company quickly, pass searchString instead of
          combining multiple filters.
        - >-
          Sort by createdAt desc to surface the most recently added companies
          first.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /companies/list:
    post:
      tags:
        - Company
      summary: Get companies
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                companyName:
                  type: string
                companyIds:
                  type: array
                email:
                  type: string
                phone:
                  type: string
                responsibleId:
                  type: array
                messengerLogin:
                  type: string
                dateFrom:
                  type: string
                dateTo:
                  type: string
                limit:
                  type: integer
                offset:
                  type: integer
                withoutContacts:
                  type: boolean
                searchString:
                  type: string
                  description: >-
                    If you pass a search string, all other filters will be
                    ignored.
                attributes:
                  type: array
                  items:
                    type: object
                    properties:
                      id:
                        type: integer
                      expression:
                        type: string
                sortBy:
                  type: object
                  properties:
                    attributeId:
                      type: integer
                    fieldName:
                      type: string
                      enum:
                        - name
                        - address
                        - annualBusinessVolume
                        - createdAt
                    direction:
                      type: string
                      enum:
                        - asc
                        - desc
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/CompanySortData'
                  metadata:
                    type: object
                    properties:
                      total:
                        type: integer
      operationId: getCompaniesList
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves a filtered, paginated list of companies from the CRM. Unlike a
        simple GET, this endpoint accepts a rich filter payload — enabling
        complex queries by name, contacts, responsible manager, custom
        attributes, and date range. The `searchString` parameter acts as a
        global override that bypasses all other filters, useful for quick
        lookups. This is the primary discovery endpoint for company records and
        the entry point for bulk CRM workflows.
      x-ai-reasoning-instructions:
        - >-
          If the user provides a search string, remind them that all other
          filters will be ignored — confirm this is the intended behavior.
        - >-
          Use `limit` and `offset` for pagination; default to a reasonable page
          size (e.g., 20–50) if not specified.
        - >-
          When filtering by `responsibleId`, ensure the IDs correspond to
          existing team members; invalid IDs may silently return empty results.
        - >-
          Combining `attributes` filter with `sortBy.attributeId` allows for
          advanced CRM segmentation — suggest this pattern for power users.
        - >-
          If `dateFrom`/`dateTo` are used, clarify which date field they apply
          to (likely `createdAt`) to avoid unexpected results.
        - >-
          Prefer specific filters over `searchString` in automated pipelines to
          ensure predictable, reproducible queries.
      x-ai-responding-instructions:
        - >-
          Report the total number of matching companies from `metadata.total`
          alongside the current page results.
        - >-
          If the result set is empty, suggest relaxing filters or checking the
          `searchString` override behavior.
        - >-
          If `metadata.total` exceeds the requested `limit`, proactively suggest
          paginating with `offset` to retrieve remaining records.
        - >-
          When presenting results to a user, highlight key identifiers and the
          responsible manager for each company to aid quick recognition.
      x-ai-suggestions:
        - >-
          Filter by `responsibleId` to get all companies assigned to a specific
          sales rep.
        - >-
          Use `searchString` for quick name lookups; switch to structured
          filters for automated or repeatable queries.
        - >-
          Sort by `createdAt` descending to review the most recently added
          companies.
        - >-
          Set `withoutContacts: true` to identify orphaned company records that
          need contact association.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /companies:
    post:
      tags:
        - Company
      summary: Create company
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                companyName:
                  type: string
                  minimum: 1
                  maximum: 100
                responsibleId:
                  type: integer
                  description: >-
                    If you do not send the responsible ID, the system will
                    automatically identify the responsible person.
                address:
                  type: string
                annualBusinessVolume:
                  type: integer
                currency:
                  type: string
                  description: >-
                    The parameter is required if you send a annualBusinessVolume
                    parameter
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Company'
      operationId: createCompany
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Creates a new company record in the CRM. A company acts as a top-level
        organizational entity that groups contacts, deals, and activities.
        Proper setup — including responsible user and financial metadata —
        directly affects pipeline visibility and reporting accuracy across the
        account.
      x-ai-reasoning-instructions:
        - >-
          Before creating, check whether a company with the same name already
          exists to prevent duplicates.
        - >-
          If `annualBusinessVolume` is provided, ensure `currency` is also
          included — the API requires it.
        - >-
          If `responsibleId` is omitted, the system auto-assigns responsibility;
          clarify this with the user if ownership matters.
        - >-
          Validate that `companyName` is between 1 and 100 characters before
          submitting.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by surfacing the new company ID from the
          `data` object in the response.
        - >-
          If `responsibleId` was not sent, inform the user that responsibility
          was assigned automatically.
        - >-
          Suggest adding contacts or deals linked to this company as the next
          logical step.
        - >-
          If a conflict or validation error occurs, explain which field caused
          it and how to fix it.
      x-ai-suggestions:
        - Acme Corp
        - TechStart Solutions
        - GlobalRetail Group
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /companies/{companyId}:
    get:
      tags:
        - Company
      summary: Get company by id
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Company'
      operationId: getCompanyById
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves the full profile of a specific company entity by its unique
        identifier. In CRM context, a company is an organizational anchor — it
        groups contacts, deals, and activities under a shared business entity,
        enabling account-based relationship management.
      x-ai-reasoning-instructions:
        - Confirm the companyId is a valid integer before making the request.
        - >-
          If the call is part of a lookup flow, prefer caching the result rather
          than re-fetching the same company repeatedly.
        - >-
          If the company is not found (404), suggest the user verify the ID or
          list available companies first.
      x-ai-responding-instructions:
        - Present the company name and key identifiers prominently.
        - >-
          If downstream actions are likely (e.g., updating the company or
          fetching its contacts), suggest the relevant endpoints.
        - >-
          On a 404 response, clearly indicate the company does not exist and
          recommend listing companies to find the correct ID.
      x-ai-suggestions:
        - >-
          Use this endpoint to verify company details before updating or
          deleting.
        - Combine with contact-listing endpoints to get a full account overview.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - Company
      summary: Update company
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                companyName:
                  type: string
                  minimum: 1
                  maximum: 100
                responsibleId:
                  type: integer
                annualBusinessVolume:
                  type: integer
                currency:
                  type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Company'
      operationId: updateCompany
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Updates the core profile of a company entity in the CRM. This is the
        primary way to keep account-level business data accurate — including
        ownership (responsibleId), revenue tier (annualBusinessVolume), and
        billing currency. Changes here propagate to all deals, contacts, and
        pipelines associated with this company.
      x-ai-reasoning-instructions:
        - >-
          Fetch the current company record before updating to avoid accidentally
          overwriting fields the user didn't intend to change.
        - >-
          Validate that responsibleId corresponds to an existing user in the
          account.
        - >-
          If annualBusinessVolume is being set, confirm the currency field is
          also provided to ensure consistent financial data.
        - >-
          companyName must be between 1 and 100 characters — validate before the
          call.
        - >-
          Only include fields that are explicitly being changed; omit unchanged
          fields to prevent data loss.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated by comparing the request payload
          with the returned Company object.
        - >-
          If responsibleId changed, mention the name of the newly assigned
          owner.
        - >-
          If annualBusinessVolume or currency changed, briefly note the updated
          revenue profile.
        - >-
          On error, explain whether the issue is a validation constraint (e.g.,
          name too long) or a reference error (e.g., unknown responsibleId).
      x-ai-suggestions:
        - >-
          Use `getCompany` first to retrieve current values before a partial
          update.
        - >-
          After updating responsibleId, notify the new responsible user via a
          task or note.
        - >-
          Updating annualBusinessVolume is useful for dynamic lead-scoring
          pipelines.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: Confirm update of company {companyId} with the provided changes.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Company
      summary: Delete company
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteCompany
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Permanently removes a company record and all its associated data from
        the CRM. This is a destructive, irreversible operation that may cascade
        to linked contacts, deals, or activities tied to this company.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm the companyId exists to avoid a misleading
          404 error.
        - Warn the user that deletion is permanent and cannot be undone.
        - >-
          Check if any contacts, deals, or tasks are linked to this company —
          deletion may affect related records.
        - >-
          Prefer archiving or soft-delete patterns if the business goal is data
          retention rather than removal.
      x-ai-responding-instructions:
        - >-
          Confirm the company was successfully deleted (HTTP 204 means no
          content returned).
        - >-
          Remind the user that linked records (contacts, deals) may have been
          affected or orphaned.
        - >-
          If a 404 is returned, clarify that the company may have already been
          deleted or the ID is incorrect.
      x-ai-suggestions:
        - Verify the companyId before calling this endpoint using getCompany.
        - >-
          Export or back up company data before deletion if audit trails are
          required.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete the company and cannot be undone.
            Confirm before proceeding.
        security_info:
          data_handling:
            - IrreversibleDelete
            - CascadeRisk
  /companies/{companyId}/history:
    get:
      tags:
        - Company history
      summary: get Company history
      parameters:
        - name: dateFrom
          in: query
          required: false
          schema:
            type: string
            format: date-time
            example: 2024-11-01T12:12:12.000Z
        - name: dateTo
          in: query
          required: false
          schema:
            type: string
            format: date-time
            example: 2024-11-01T12:12:12.000Z
        - name: limit
          in: query
          required: false
          schema:
            type: integer
        - name: offset
          in: query
          required: false
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/History'
                  metadata:
                    type: object
                    properties:
                      total:
                        type: integer
      operationId: getCompanyHistory
      x-ai-role: crm_analyst
      x-ai-description: >-
        Retrieves a paginated, time-filtered audit trail of events for a
        specific company. This endpoint surfaces the full interaction and
        state-change history, enabling agents to reconstruct a company's
        lifecycle, audit recent activity, or prepare context before taking
        actions on behalf of this company.
      x-ai-reasoning-instructions:
        - >-
          If no dateFrom/dateTo is provided, you will receive the most recent
          records — clarify the intended time range with the user if context is
          ambiguous.
        - >-
          Use limit + offset for pagination; always check metadata.total to
          determine if more pages exist.
        - >-
          When investigating a specific event, narrow the window with
          dateFrom/dateTo before paginating to avoid processing unnecessary
          records.
        - >-
          companyId must be a valid, existing company — resolve it first if only
          a company name is known.
      x-ai-responding-instructions:
        - >-
          Summarize the number of returned records versus metadata.total to
          indicate whether the result is complete or paginated.
        - >-
          Highlight the most recent events if the user is investigating recent
          activity.
        - >-
          If the result is empty, suggest widening the date range or verifying
          the companyId.
      x-ai-suggestions:
        - 'Fetch the last 20 events: limit=20, offset=0'
        - >-
          Filter by a specific day: dateFrom='2024-11-01 00:00:00',
          dateTo='2024-11-01 23:59:59'
        - >-
          Paginate through all history using metadata.total to control loop
          termination
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /companies/attributes:
    get:
      tags:
        - Company Attributes
      summary: Get company attributes list
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Attribute'
      operationId: getCompanyAttributes
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Retrieves the full list of custom attributes defined for companies in
        the CRM. These attributes form the schema of company-level metadata —
        they must be known before creating or updating companies, as they define
        what fields are available for enrichment and segmentation.
      x-ai-reasoning-instructions:
        - >-
          Call this endpoint before creating or updating a company to know which
          attributes are available.
        - >-
          Use the returned attribute list to validate that any attribute you
          intend to set actually exists.
        - >-
          If the user wants to filter or segment companies by a custom field,
          first verify the field name matches an attribute returned here.
      x-ai-responding-instructions:
        - >-
          Present the attributes as a structured list with their names and
          types.
        - >-
          If the list is empty, inform the user that no custom attributes have
          been defined yet and suggest creating them.
        - >-
          Suggest using the attribute names as keys when calling company
          create/update endpoints.
      x-ai-suggestions:
        - Use returned attribute names as keys in company creation payloads.
        - >-
          Cross-reference with contact attributes to understand the full CRM
          schema.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Company Attributes
      summary: Create a company attribute
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                type:
                  type: integer
                  description: >-
                    0 = Text, 1 = Number, 2 = Date, 3 = Link, 4 = Select, 5 =
                    MultiSelect
                mandatory:
                  type: boolean
                options:
                  type: array
                  items:
                    oneOf:
                      - type: string
                      - type: integer
              required:
                - name
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Attribute'
      operationId: createCompanyAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Defines a custom metadata field for the company entity in the CRM.
        Attributes extend the default company schema and allow teams to capture
        domain-specific data (e.g., 'Industry', 'Contract Value', 'Renewal
        Date'). The type determines both the UI widget and data validation
        rules; Select/MultiSelect types require populating the `options` array
        to be usable.
      x-ai-reasoning-instructions:
        - >-
          Check whether an attribute with the same name already exists before
          creating to avoid schema duplication.
        - >-
          If type is 4 (Select) or 5 (MultiSelect), verify that the `options`
          array is non-empty — otherwise the field will be rendered but
          unusable.
        - >-
          Advise using consistent naming conventions (e.g., PascalCase or
          snake_case) across all custom attributes to simplify downstream
          filtering.
        - >-
          Consider whether `mandatory: true` is appropriate — mandatory
          attributes block company record creation until filled.
        - >-
          Date-type attributes (type 2) follow ISO 8601 — flag this if the user
          intends to store locale-specific formats.
      x-ai-responding-instructions:
        - >-
          Confirm creation by referencing the returned attribute ID and its
          resolved type name (e.g., 'Text', 'Select').
        - >-
          If type is Select or MultiSelect, list the registered options back to
          the user for confirmation.
        - >-
          Suggest the next step: assigning a value to this attribute on a
          specific company via the update company endpoint.
        - >-
          If a validation error occurs, clarify which field caused it and
          provide a corrected example.
      x-ai-suggestions:
        - 'Industry (type: 0 — Text)'
        - 'Employee Count (type: 1 — Number)'
        - 'Contract Renewal Date (type: 2 — Date)'
        - 'Company Website (type: 3 — Link)'
        - >-
          Account Tier (type: 4 — Select, options: ['Free', 'Pro',
          'Enterprise'])
        - 'Interested Products (type: 5 — MultiSelect)'
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - SchemaModification
  /companies/attributes/{attribute}:
    put:
      tags:
        - Company Attributes
      summary: Update a company attribute
      parameters:
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                status:
                  type: integer
                  description: 0 = Inactive, 1 = Active, 2 = Hidden
                type:
                  type: integer
                  description: >-
                    0 = Text, 1 = Number, 2 = Date, 3 = Link, 4 = Select, 5 =
                    MultiSelect
                mandatory:
                  type: boolean
                order:
                  type: integer
                options:
                  type: array
                  items:
                    oneOf:
                      - type: string
                      - type: integer
              required:
                - name
                - order
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Attribute'
      operationId: updateCompanyAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Modifies the schema definition of a custom company attribute — its
        display name, data type, visibility, and validation rules. This is a
        structural operation: changing `type` or `status` affects how all
        existing company records store and expose that field. Use with caution
        in production environments where CRM data integrity is critical.
      x-ai-reasoning-instructions:
        - >-
          Before updating, retrieve the current attribute definition to
          understand what is changing and what downstream impact it may have.
        - >-
          Changing `type` (e.g., from Text to Select) is a breaking schema
          change — warn the user that existing values may become invalid.
        - >-
          If `status` is set to 0 (Inactive) or 2 (Hidden), clarify that the
          attribute will no longer be visible or editable on company profiles.
        - >-
          When `options` is provided, verify it is only relevant for types 4
          (Select) or 5 (MultiSelect) — for other types it is ignored.
        - >-
          The `order` field controls rendering position in the UI — coordinate
          with other attributes to avoid ordering conflicts.
        - >-
          If `mandatory` is being set to true, verify that all existing
          companies already have a value for this attribute to avoid form
          validation issues.
      x-ai-responding-instructions:
        - Confirm which fields were updated and their new values.
        - >-
          If `type` was changed, explicitly warn about potential data integrity
          issues with existing company records.
        - >-
          If `status` was changed to Inactive or Hidden, note that the attribute
          will no longer appear in the CRM interface.
        - >-
          Suggest verifying the change by retrieving the attribute or reviewing
          a sample company profile.
      x-ai-suggestions:
        - >-
          Set status to 2 (Hidden) instead of 0 (Inactive) to preserve data
          while removing the field from UI.
        - >-
          For Select/MultiSelect types, always provide the full updated
          `options` array — partial updates may drop existing choices.
        - >-
          Use `order` values with gaps (e.g., 10, 20, 30) to allow future
          reordering without renumbering all attributes.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating attribute schema may affect all existing company records.
            Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - SchemaModification
    delete:
      tags:
        - Company Attributes
      summary: Delete a company attribute
      parameters:
        - name: attributeId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteCompanyAttribute
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Permanently removes a custom company attribute definition from the CRM
        schema. This is a destructive schema operation — deleting an attribute
        eliminates not just the field definition but all associated data stored
        under that attribute across every company record. Use only when the
        attribute is no longer relevant to the business model.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, verify the attribute is not used in active pipeline
          stages, filters, or automation triggers.
        - >-
          Warn the user that all stored values for this attribute across all
          company records will be permanently lost.
        - >-
          Check if any reports, segments, or integrations depend on this
          attribute before proceeding.
        - >-
          Prefer archiving or renaming over deletion if the attribute data may
          be needed for historical analysis.
      x-ai-responding-instructions:
        - Confirm deletion with the attribute ID that was removed.
        - >-
          Remind the user that this action is irreversible and all associated
          data is gone.
        - >-
          Suggest auditing remaining company attributes to ensure schema
          consistency.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            Deleting a company attribute is irreversible and will remove all
            associated data from every company record.
        security_info:
          data_handling:
            - PermanentDataDeletion
            - SchemaModification
  /companies/{companyId}/emails:
    get:
      tags:
        - Emails
      summary: Get emails
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Email'
                  metadata:
                    type: object
                    properties:
                      total:
                        type: integer
      operationId: getCompanyEmails
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves all email addresses associated with a specific company entity
        in the CRM. Use this to audit contact coverage for a company before
        launching targeted campaigns or to validate data completeness prior to
        syncing with external marketing tools.
      x-ai-reasoning-instructions:
        - >-
          Confirm the companyId exists before calling — a 404 indicates the
          company is not in the system.
        - >-
          Note that entityType is fixed to 'company' for this endpoint; do not
          attempt other entity types here.
        - >-
          Check the metadata.total field in the response to detect pagination
          needs if the dataset is large.
        - >-
          If the result is empty, suggest verifying whether emails were imported
          or added to this company record.
      x-ai-responding-instructions:
        - Report the total number of emails found using metadata.total.
        - >-
          List the returned email addresses clearly, grouping by type if the
          Email schema includes a type field.
        - >-
          If the list is empty, inform the user and suggest adding emails via
          the appropriate create/update endpoint.
        - >-
          If the result is partial (total > returned count), mention that
          pagination may be required.
      x-ai-suggestions:
        - >-
          Use the returned emails to pre-populate a mailing list for a targeted
          company-level campaign.
        - >-
          Cross-reference with contact records to ensure all stakeholders at
          this company are covered.
        - >-
          Follow up with a contact details endpoint to enrich email entries with
          names and roles.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Emails
      summary: Create email
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    isMain:
                      type: boolean
                    email:
                      type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Email'
      operationId: createCompanyEmail
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Adds an email address to a company's contact profile in the CRM. This is
        a foundational data operation — the email stored here is used for all
        outbound communication, campaign targeting, and contact identification.
        Setting isMain=true replaces the primary email, which affects
        deliverability tracking and deduplication logic across the account.
      x-ai-reasoning-instructions:
        - >-
          Check if an email for this company already exists before adding a new
          one to avoid duplicate entries.
        - >-
          If isMain is true, warn the user that this will override the current
          primary email, which may affect active campaigns.
        - >-
          Validate the email format before submission to prevent storing
          malformed addresses.
        - >-
          Confirm the companyId exists and is accessible before making the
          request.
      x-ai-responding-instructions:
        - >-
          Confirm the email was added successfully and mention whether it was
          set as the primary email.
        - >-
          If isMain was set to true, note that outbound communications will now
          use this address.
        - >-
          Suggest verifying the email or linking it to a campaign as a logical
          next step.
      x-ai-suggestions:
        - 'Set isMain: true when replacing an outdated primary contact email.'
        - >-
          Use isMain: false to add secondary or billing emails without
          disrupting the main contact.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Setting isMain: true will replace the current primary email for this
            company.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PII
  /companies/{companyId}/emails/batch:
    post:
      tags:
        - Emails
      summary: Batch create email
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                emails:
                  type: array
                  items:
                    type: object
                    properties:
                      email:
                        type: string
                        minLength: 1
                        maxLength: 50
                      isMain:
                        type: boolean
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Email'
      operationId: batchCreateCompanyEmails
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Bulk-provisions multiple email addresses for a CRM company record in a
        single atomic request. One of them can be flagged as the primary contact
        email (`isMain: true`), which affects routing of automated
        communications and display priority in the UI. This is the preferred
        method when onboarding a company with several known contact points —
        avoids multiple sequential calls and reduces the risk of partial state.
      x-ai-reasoning-instructions:
        - >-
          Ensure the target company (`companyId`) exists before attempting the
          batch — a 404 here means all emails in the batch are silently dropped.
        - >-
          Validate that no more than one item in the `emails` array has `isMain:
          true`; multiple main emails will cause ambiguity in downstream
          automation.
        - >-
          Check for duplicate email values within the array itself before
          sending — the API may reject the entire batch on collision.
        - >-
          If the user provides a single email, consider whether a regular
          single-create endpoint is more appropriate to keep the audit trail
          clean.
      x-ai-responding-instructions:
        - >-
          Confirm how many emails were created and list their assigned IDs from
          the response `data` array.
        - >-
          Highlight which email was set as the primary contact if `isMain: true`
          was used.
        - >-
          If the batch partially fails, clearly distinguish which emails
          succeeded and which did not.
        - >-
          Suggest verifying the company's full email list via the corresponding
          GET endpoint as a follow-up.
      x-ai-suggestions:
        - >-
          Set exactly one email with `isMain: true` to establish a clear primary
          contact.
        - >-
          Batch all known emails for a company during initial import rather than
          adding them incrementally.
        - >-
          Use this endpoint when migrating contact data from an external CRM to
          avoid N individual API calls.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PersonalDataWrite
  /companies/{companyId}/emails/{emailId}:
    put:
      tags:
        - Emails
      summary: Update email
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
        - name: emailId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    isMain:
                      type: boolean
                    email:
                      type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Messenger'
      operationId: updateCompanyEmail
      x-ai-role: crm_contact_data_manager
      x-ai-description: >-
        Updates the email address or main status of a specific email record
        linked to a company. Use this to change which email is marked as the
        primary contact point (isMain: true) or to correct an outdated address.
        Only one email can be the main one — setting isMain on another will
        implicitly demote the current primary.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the emailId belongs to the given companyId to
          avoid cross-resource mutations.
        - >-
          If isMain is being set to true, warn the user that the current main
          email will lose its primary status.
        - >-
          If updating the email string, validate the format before sending to
          avoid 4xx errors.
        - >-
          Do not send empty or null values for fields you are not intending to
          change.
      x-ai-responding-instructions:
        - >-
          Confirm which field(s) were updated (email address, isMain flag, or
          both).
        - >-
          If isMain was set to true, explicitly note that this email is now the
          primary contact for the company.
        - >-
          If the response includes a Messenger object, highlight any fields that
          reflect the change.
      x-ai-suggestions:
        - 'Set isMain: true to promote this email to the primary company contact.'
        - >-
          Use alongside GET /companies/{companyId}/emails to retrieve current
          email records before updating.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to update an email record for a company. If isMain is
            being changed, this affects which address is used as the primary
            contact.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Emails
      summary: Delete email
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
        - name: emailId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteCompanyEmail
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Permanently removes a specific email address from a company record in
        the CRM. This is a destructive, irreversible operation that affects
        contact reachability — once deleted, the email cannot be recovered via
        the API and any associated campaign history tied to that address may
        become orphaned.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, confirm the emailId belongs to the specified
          companyId to avoid cross-tenant data mutation.
        - >-
          Warn the user if the email being deleted is the only contact email for
          the company — this may leave the company record unreachable.
        - >-
          Check whether any active campaigns or automations reference this email
          before proceeding.
        - >-
          This operation is irreversible — require explicit user confirmation if
          acting autonomously.
      x-ai-responding-instructions:
        - >-
          On success (204), confirm the email was permanently deleted and
          mention the affected companyId and emailId.
        - >-
          Suggest verifying the company's remaining contact emails using the
          list emails endpoint.
        - >-
          If a 404 is returned, clarify whether the companyId or emailId was not
          found to help the user diagnose the issue.
      x-ai-suggestions:
        - >-
          After deletion, use the list company emails endpoint to confirm
          remaining contacts.
        - >-
          If deletion was accidental, a new email must be added manually via the
          create email endpoint.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete email {emailId} from company
            {companyId}. This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - ResourceStateUpdate
  /companies/{companyId}/phones:
    get:
      tags:
        - Phones
      summary: Get phones
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Phone'
                  metadata:
                    type: object
                    properties:
                      total:
                        type: integer
      operationId: getCompanyPhones
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves all phone numbers associated with a specific company in the
        CRM. Phone records serve as primary communication channels for outbound
        calls, SMS campaigns, and contact routing. This list is essential for
        multi-channel outreach orchestration.
      x-ai-reasoning-instructions:
        - >-
          Verify that the companyId exists before requesting phones to avoid
          misleading empty responses.
        - >-
          Check the total in metadata to determine if pagination is needed for
          large datasets.
        - >-
          Consider that a company may have multiple phones with different roles
          (main, support, sales) — account for this when selecting a contact
          number.
      x-ai-responding-instructions:
        - Present the list of phones with their types or labels if available.
        - >-
          Mention the total count from metadata to give context on the full
          dataset.
        - >-
          If the list is empty, suggest adding phones via the create phone
          endpoint.
      x-ai-suggestions:
        - >-
          Use the returned phone numbers to initiate an SMS campaign or outbound
          call sequence.
        - >-
          Cross-reference with contacts list to map phones to specific
          individuals within the company.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Phones
      summary: Create phone
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    typeId:
                      type: integer
                    login:
                      type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Phone'
      operationId: createCompanyPhone
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Registers a new phone number for a specific company in the CRM. A phone
        entry links a communication channel (defined by typeId) to a company
        profile, enabling multi-channel outreach and contact routing. This is
        foundational for building complete company contact cards.
      x-ai-reasoning-instructions:
        - >-
          Verify that the companyId exists before attempting to create the phone
          record.
        - >-
          Check if a phone with the same login already exists for this company
          to avoid duplicates.
        - >-
          Clarify the typeId with the user — it defines the phone type (e.g.,
          work, mobile, fax) and must be a valid value from the phone types
          dictionary.
        - >-
          Ensure the login value is a valid phone number format appropriate for
          the intended channel.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by referencing the new phone record
          details from the response.
        - >-
          Mention the company context (companyId) so the user understands which
          record was updated.
        - >-
          If the typeId is unknown, suggest fetching available phone types
          first.
        - >-
          If creation fails due to a duplicate or invalid companyId, explain
          clearly and suggest corrective actions.
      x-ai-suggestions:
        - Use typeId=1 for primary work phone if unsure about the type.
        - >-
          After creating the phone, verify it appears in the company's contact
          list.
        - >-
          Consider adding multiple phone types (work, mobile) to ensure complete
          contact coverage.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /companies/{companyId}/phones/batch:
    post:
      tags:
        - Phones
      summary: Batch create phone
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                phones:
                  type: array
                  items:
                    type: object
                    properties:
                      phone:
                        type: string
                        minLength: 1
                        maxLength: 50
                      isMain:
                        type: boolean
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Phone'
      operationId: batchCreateCompanyPhones
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Bulk-assigns phone numbers to a CRM company record in a single atomic
        request. Use this instead of individual phone creation when onboarding a
        company with multiple contact numbers or migrating data from an external
        source. The `isMain` flag controls which number appears as the primary
        contact in the CRM UI and is used by default in outbound communication.
      x-ai-reasoning-instructions:
        - >-
          Ensure exactly one phone in the batch has `isMain: true`; having
          multiple main phones or none may cause ambiguity in the CRM.
        - >-
          Validate phone format before sending — the field accepts up to 50
          characters but does not enforce E.164 automatically.
        - >-
          Check if the company already has phones; batch creation may result in
          duplicates if the same numbers exist.
        - >-
          If the batch is large, consider splitting into smaller chunks to stay
          within payload limits.
      x-ai-responding-instructions:
        - >-
          Confirm how many phones were created and list their assigned IDs from
          the response `data` array.
        - Highlight which phone was set as the main contact.
        - >-
          If the operation partially fails, clarify which phones were not
          created and why.
        - >-
          Suggest verifying the result with a GET /companies/{companyId}/phones
          call.
      x-ai-suggestions:
        - >-
          Set `isMain: true` on the primary office number and `isMain: false` on
          all others.
        - Use E.164 format (e.g., +14155552671) for cross-region compatibility.
        - >-
          Batch all numbers in one request during initial company import to
          reduce API call overhead.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to add {{phones.length}} phone number(s) to company
            {{companyId}}. Proceed?
        security_info:
          data_handling:
            - ResourceStateUpdate
            - BulkWrite
  /companies/{companyId}/phones/{phoneId}:
    put:
      tags:
        - Phones
      summary: Update phone
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
        - name: phoneId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    isMain:
                      type: boolean
                    phone:
                      type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Phone'
      operationId: updateCompanyPhone
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Updates an existing phone record associated with a company entity in the
        CRM. The `isMain` flag controls which phone number is treated as the
        primary contact point — only one phone per entity should be marked as
        main at a time. Use this endpoint to correct phone numbers or promote a
        secondary number to primary status.
      x-ai-reasoning-instructions:
        - >-
          Verify the phoneId belongs to the specified companyId before
          attempting the update.
        - >-
          If setting isMain: true, warn the user that this may implicitly demote
          another phone to non-primary, depending on CRM behavior.
        - >-
          Validate phone format (E.164 recommended) before sending to avoid
          silent rejection or data inconsistency.
        - >-
          If only isMain is being toggled without changing the number, confirm
          the intent to avoid accidental data loss.
      x-ai-responding-instructions:
        - >-
          Confirm which field(s) were updated and reflect the new state back to
          the user.
        - >-
          If isMain was set to true, explicitly note that this phone is now the
          primary contact for the company.
        - >-
          Suggest verifying the full phone list via GET
          /companies/{companyId}/phones if the user needs to audit all contact
          numbers.
      x-ai-suggestions:
        - Toggle isMain to promote a backup number to primary contact.
        - >-
          Correct a mistyped phone number without removing and re-adding the
          record.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to overwrite the existing phone data for this company.
            Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Phones
      summary: Delete phone
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
        - name: phoneId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteCompanyPhone
      x-ai-role: crm_data_manager
      x-ai-description: >-
        Permanently removes a phone number record linked to a specific company
        entity. This is a destructive, irreversible action — once deleted, the
        phone cannot be recovered and any campaigns or automations referencing
        it may be affected.
      x-ai-reasoning-instructions:
        - >-
          Confirm the phoneId belongs to the specified companyId before
          proceeding — cross-entity deletions are not permitted.
        - Warn the user that deletion is permanent and cannot be undone.
        - >-
          Check if the phone number is referenced in active campaigns or
          workflows before deleting.
        - >-
          Ensure entityType is always 'company' for this endpoint — other entity
          types are not supported here.
      x-ai-responding-instructions:
        - >-
          Confirm successful deletion with a clear message that the phone record
          no longer exists.
        - >-
          If the response is 204 No Content, explicitly state that the operation
          succeeded even though no body is returned.
        - >-
          If a 404 is returned, clarify whether the companyId or phoneId was not
          found.
        - Suggest verifying remaining phones via a list endpoint after deletion.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete the phone record. This action cannot be
            undone.
        security_info:
          data_handling:
            - IrreversibleDelete
  /companies/{companyId}/messengers:
    get:
      tags:
        - messengers
      summary: Get messengers
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Messenger'
                  metadata:
                    type: object
                    properties:
                      total:
                        type: integer
      operationId: getCompanyMessengers
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Retrieves all messenger channels connected to a specific CRM company.
        This endpoint is the entry point for understanding which communication
        channels (WhatsApp, Telegram, Viber, etc.) are available for a given
        company, enabling multichannel outreach orchestration.
      x-ai-reasoning-instructions:
        - >-
          Verify the companyId exists and is accessible before interpreting an
          empty result as 'no messengers'.
        - >-
          Use the metadata.total field to detect pagination — if total exceeds
          the returned array length, additional pages may exist.
        - >-
          If the goal is to send a message, cross-reference available messengers
          with the contact's subscribed channels before selecting one.
      x-ai-responding-instructions:
        - >-
          List the available messenger types clearly (e.g., 'This company has
          WhatsApp and Telegram connected').
        - >-
          If the array is empty, suggest connecting a messenger channel in the
          SendPulse dashboard.
        - >-
          Highlight the total count from metadata when presenting results to
          give the user a complete picture.
      x-ai-suggestions:
        - >-
          Use the returned messenger IDs to send messages via the corresponding
          send-message endpoint.
        - >-
          Check this endpoint before initiating a campaign to ensure at least
          one active channel is available.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - messengers
      summary: Create messenger
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    typeId:
                      type: integer
                    login:
                      type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Messenger'
      operationId: createCompanyMessenger
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Connects a messenger channel (e.g., Telegram, Viber, WhatsApp) to a
        specific company entity in the CRM. This is a configuration step that
        enables omnichannel communication — once a messenger is linked, the
        company can send and receive messages through that channel. The typeId
        determines which messenger platform is being registered.
      x-ai-reasoning-instructions:
        - >-
          Resolve the correct entityType and entityId before calling — this
          endpoint uses path params that mirror the generic entity structure;
          for companies, entityType must be 'company'.
        - >-
          Check whether a messenger of the same typeId is already linked to this
          company to avoid duplicate channel registrations.
        - >-
          Verify that login format matches the requirements of the target
          messenger platform (e.g., phone number for WhatsApp, username for
          Telegram).
      x-ai-responding-instructions:
        - >-
          Confirm the created messenger by referencing its ID and type from the
          response.
        - >-
          Suggest activating or testing the messenger channel as an immediate
          next step.
        - >-
          If creation fails due to a conflict, explain that the channel may
          already be registered and suggest listing existing messengers first.
      x-ai-suggestions:
        - >-
          Use typeId=1 for Telegram, typeId=2 for Viber — verify the platform's
          type registry before calling.
        - >-
          After creation, associate the messenger with contacts to enable
          targeted messaging.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /companies/{companyId}/messengers/batch:
    post:
      tags:
        - messengers
      summary: Batch create messenger
      parameters:
        - name: companyId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                messengers:
                  type: array
                  items:
                    type: object
                    properties:
                      typeId:
                        type: integer
                      login:
                        type: string
                      botId:
                        type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/Messenger'
      operationId: batchCreateCompanyMessengers
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Bulk-registers multiple messenger channels (WhatsApp, Telegram, Viber,
        etc.) for a CRM company in a single atomic call. Use this instead of
        sequential single-messenger creation when onboarding a company that
        already operates across several platforms — it reduces round-trips and
        ensures all channels are provisioned together.
      x-ai-reasoning-instructions:
        - >-
          Verify that companyId exists before submitting — a 404 here silently
          discards the entire batch.
        - >-
          Check that each messenger's typeId corresponds to a supported platform
          type; unknown typeIds may cause partial failures.
        - >-
          Ensure no duplicate (typeId + login) pairs exist within the batch or
          in already-registered messengers for this company.
        - >-
          If botId is required for bot-based channels (e.g., Telegram), validate
          its presence before the call to avoid partial success.
        - >-
          Prefer this endpoint over repeated POST /messengers calls whenever two
          or more messengers must be created together.
      x-ai-responding-instructions:
        - >-
          Confirm how many messengers were successfully created out of how many
          were submitted.
        - >-
          List the returned messenger IDs and their associated typeId/login for
          traceability.
        - >-
          If the response includes partial failures, clearly identify which
          items failed and why.
        - >-
          Suggest verifying connectivity or triggering a test message as the
          immediate next step.
      x-ai-suggestions:
        - >-
          Combine all messenger channels known at company onboarding into one
          batch call.
        - >-
          After batch creation, use GET /companies/{companyId}/messengers to
          confirm all channels are active.
        - >-
          If a specific messenger type requires webhook configuration, do that
          immediately after this call.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to register {{count}} messenger channel(s) for company
            {{companyId}}. Proceed?
        security_info:
          data_handling:
            - ResourceStateUpdate
            - BulkWrite
  /companies/{companyId}/messengers/{messengerId}:
    put:
      tags:
        - messengers
      summary: Update messenger
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
        - name: messengerId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        description: ''
        content:
          application/json:
            schema:
              properties:
                data:
                  type: object
                  properties:
                    typeId:
                      type: integer
                    login:
                      type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/Messenger'
      operationId: updateCompanyMessenger
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Updates the messenger configuration linked to a specific company entity.
        A messenger in this context is a communication channel integration
        (e.g., Telegram, WhatsApp) tied to a company account. Modifying the
        typeId changes the channel type, while updating the login reassigns the
        account identifier — both can affect active chatbot routing and message
        delivery.
      x-ai-reasoning-instructions:
        - >-
          Fetch the current messenger record before updating to understand which
          fields are already set and avoid accidental overwrites.
        - >-
          Verify that the new typeId corresponds to a valid and supported
          messenger type in the system.
        - >-
          If changing the login, confirm the new account identifier belongs to
          the same company to prevent cross-account conflicts.
        - >-
          Check if the messenger is currently active and linked to any chatbot
          flows — modifying it may interrupt ongoing conversations.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated and reflect the new values in the
          response summary.
        - >-
          If the messenger type changed, note the implications for any chatbots
          or automation flows using this channel.
        - >-
          Suggest verifying the integration is still functional after the
          update, especially if the login was changed.
      x-ai-suggestions:
        - >-
          Use `getCompanyMessengers` first to retrieve the current state before
          patching.
        - >-
          After updating, verify connectivity with a test message if the
          messenger type supports it.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating a messenger may disrupt active chatbot flows using this
            channel. Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - messengers
      summary: Delete messenger
      parameters:
        - name: entityType
          in: path
          required: true
          schema:
            type: string
            enum:
              - company
        - name: entityId
          in: path
          required: true
          schema:
            type: integer
        - name: messengerId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteCompanyMessenger
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Permanently removes a messenger channel linked to a company entity. In
        SendPulse CRM, messengers are communication touchpoints — deleting one
        severs the channel and may affect active automation flows, ongoing
        conversations, and contact reachability. This action is irreversible.
      x-ai-reasoning-instructions:
        - >-
          Confirm that the messengerId belongs to the specified companyId before
          proceeding — a mismatch will result in a 404 or unintended deletion.
        - >-
          Check whether this messenger is referenced in active pipelines,
          automation sequences, or contact records before deletion.
        - >-
          Treat this as a destructive operation — ask for explicit user
          confirmation if context suggests the messenger may still be in active
          use.
        - >-
          entityType must be 'company' — validate this before constructing the
          request.
      x-ai-responding-instructions:
        - >-
          A 204 response means the messenger was successfully deleted — inform
          the user that the channel no longer exists.
        - >-
          Warn the user that any automation or contact flows relying on this
          messenger will be broken.
        - >-
          Suggest reviewing related pipelines or contacts to reassign a
          communication channel if needed.
      x-ai-suggestions:
        - >-
          After deletion, verify related contacts still have at least one active
          communication channel.
        - >-
          Use GET /companies/{companyId}/messengers to confirm the messenger
          list post-deletion.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: This will permanently delete the messenger and cannot be undone.
        security_info:
          data_handling:
            - ResourceDestruction
            - IrreversibleAction
  /deals/{dealId}/history:
    get:
      tags:
        - Deal history
      summary: Deal history
      description: Get deal history by ID within a date range.
      parameters:
        - name: dealId
          in: path
          required: true
          schema:
            type: integer
        - name: fromDate
          in: query
          required: true
          schema:
            type: string
            format: date-time
            example: 2024-12-12T12:12:12.000Z
        - name: toDate
          in: query
          required: true
          schema:
            type: string
            format: date-time
            example: 2024-12-12T12:12:12.000Z
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/DealHistory'
      operationId: getDealHistory
      x-ai-role: crm_sales_analyst
      x-ai-description: >-
        Retrieves the full chronological audit trail of all changes made to a
        specific deal within a defined time window. This endpoint is the primary
        tool for understanding deal progression, identifying stalled stages, and
        reconstructing the sales timeline for reporting or debugging purposes.
      x-ai-reasoning-instructions:
        - >-
          Verify that the dealId exists before querying history to avoid
          misleading empty results.
        - >-
          Ensure fromDate is earlier than toDate; if the user provides them in
          the wrong order, swap and notify.
        - >-
          When the user asks for 'recent history', default the range to the last
          30 days unless they specify otherwise.
        - >-
          If the returned history is empty, consider suggesting a wider date
          range rather than assuming no changes occurred.
      x-ai-responding-instructions:
        - >-
          Summarize the key changes in the history (e.g., status transitions,
          owner reassignments, value updates) rather than listing raw events.
        - >-
          Highlight any unusual patterns such as rapid stage changes or
          prolonged inactivity within the range.
        - >-
          If the range returns many events, group them by type or date for
          better readability.
        - >-
          Suggest follow-up actions such as updating the deal or contacting the
          assigned manager if the history reveals a stalled state.
      x-ai-suggestions:
        - >-
          Use a 30-day lookback window as a default starting point for deal
          audits.
        - >-
          Combine with getDeal to cross-reference current deal state with its
          historical changes.
        - Use this endpoint for generating sales pipeline health reports.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /contacts/{contactId}/history:
    get:
      tags:
        - Contact history
      summary: Contact history
      description: Get contact history by ID within a date range.
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: integer
        - name: fromDate
          in: query
          required: true
          schema:
            type: string
            format: date-time
            example: 2024-12-12T12:12:12.000Z
        - name: toDate
          in: query
          required: true
          schema:
            type: string
            format: date-time
            example: 2024-12-12T12:12:12.000Z
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ContactHistory'
      operationId: getContactHistory
      x-ai-role: crm_data_analyst
      x-ai-description: >-
        Retrieves the full interaction timeline for a specific contact within a
        defined date window. This endpoint is the primary audit trail for
        understanding what happened to a contact — what messages were sent, what
        automations were triggered, and how the contact responded. Use it for
        debugging campaign flows, auditing contact activity, or building
        timeline views in CRM interfaces.
      x-ai-reasoning-instructions:
        - >-
          Verify that `fromDate` is earlier than `toDate` before making the
          request.
        - >-
          If the user asks for 'recent history', default the range to the last
          30 days unless specified otherwise.
        - >-
          Note that date-time values must include time component — if only a
          date is provided, append 00:00:00 for `fromDate` and 23:59:59 for
          `toDate`.
        - >-
          Large date ranges may return extensive arrays — advise the user to
          narrow the range if performance is a concern.
        - >-
          If contactId is unknown, suggest resolving it first via a contact
          search endpoint.
      x-ai-responding-instructions:
        - >-
          Summarize the number of history entries returned and the date range
          covered.
        - >-
          Highlight any notable event types (e.g., unsubscribes, bounces,
          automation triggers) if present in the results.
        - >-
          If the array is empty, clarify that no activity was recorded in the
          given range — not that the contact doesn't exist.
        - >-
          Suggest narrowing or widening the date range if the result set seems
          unexpectedly small or large.
      x-ai-suggestions:
        - Use a 7-day window for recent activity checks.
        - Use a 30-day window for monthly campaign audits.
        - >-
          Combine with contact details endpoint to build a full contact profile
          view.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /tasks/{taskId}/history:
    get:
      tags:
        - Task history
      summary: Get task history
      description: Get task history by ID within a date range.
      parameters:
        - name: taskId
          in: path
          required: true
          schema:
            type: integer
        - name: fromDate
          in: query
          required: true
          schema:
            type: string
            format: date-time
            example: 2024-12-12T12:12:12.000Z
        - name: toDate
          in: query
          required: true
          schema:
            type: string
            format: date-time
            example: 2024-12-12T12:12:12.000Z
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: '#/components/schemas/TaskHistory'
      operationId: getTaskHistory
      x-ai-role: task_management_analyst
      x-ai-description: >-
        Retrieves a chronological audit trail of all state changes and events
        for a specific task within a bounded time window. This is not just a log
        — it is the source of truth for diagnosing automation failures,
        debugging trigger sequences, and auditing task execution history in CRM
        or workflow pipelines.
      x-ai-reasoning-instructions:
        - >-
          Ensure taskId refers to an existing task before querying; a missing
          task will return an empty or error response.
        - >-
          The fromDate and toDate range should be reasonable — overly broad
          ranges may return excessive data or hit pagination limits.
        - >-
          If the user is debugging a specific issue, narrow the date range to
          the suspected incident window for clarity.
        - >-
          Date-time values must be in the correct format (YYYY-MM-DD HH:MM:SS or
          ISO 8601); validate before submitting.
      x-ai-responding-instructions:
        - >-
          Summarize the number of history entries returned and the time range
          covered.
        - >-
          If the result is empty, suggest widening the date range or verifying
          that the taskId is correct.
        - >-
          Highlight any notable status transitions or anomalies in the history
          (e.g., repeated failures, unexpected state changes).
        - >-
          Suggest using this data for debugging task execution issues or
          auditing automation workflows.
      x-ai-suggestions:
        - >-
          Use a 24-hour window around a known incident to isolate the root
          cause.
        - >-
          Combine with task status endpoints to get current state alongside
          historical context.
        - >-
          Useful for compliance audits — export the history before deleting or
          archiving a task.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /products/all:
    post:
      tags:
        - ECommerce Product
      summary: Get products by filter
      requestBody:
        content:
          application/json:
            schema:
              properties:
                categoryId:
                  type: number
                  description: Category ID to filter products.
                dateFrom:
                  type: string
                  description: 'Start date for filtering (format: YYYY-MM-DD).'
                dateTo:
                  type: string
                  description: 'End date for filtering (format: YYYY-MM-DD).'
                search:
                  type: string
                  description: Text search by product name or code.
                balance:
                  type: object
                  description: Filter by product stock balance and unit type.
                  properties:
                    expression:
                      type: string
                      enum:
                        - '='
                        - '>='
                        - <=
                      description: Comparison operator for balance.
                    type:
                      type: number
                      enum:
                        - 1
                        - 2
                        - 3
                        - 4
                        - 5
                        - 6
                        - 7
                      description: Unit type of the product balance.
                    value:
                      type: number
                      description: Stock quantity value to compare.
                description:
                  type: string
                  description: Description for products
                purchases:
                  type: object
                  description: Filter by number of purchases.
                  properties:
                    expression:
                      type: string
                      enum:
                        - '='
                        - '>='
                        - <=
                      description: Comparison operator for purchases.
                    value:
                      type: number
                      description: Number of purchases to compare.
                price:
                  type: object
                  description: Filter by product price or old price.
                  properties:
                    expression:
                      type: string
                      enum:
                        - '='
                        - '>='
                        - <=
                      description: Comparison operator for price.
                    currency:
                      type: string
                      description: Currency of the price (e.g., USD, EUR).
                    value:
                      type: number
                      description: Current price value.
                    oldValue:
                      type: number
                      description: Previous price value.
                visible:
                  type: number
                  enum:
                    - 0
                    - 1
                  description: Product visibility status (0 = hidden, 1 = visible).
                typeProduct:
                  type: number
                  enum:
                    - 1
                    - 2
                  description: Product type (1 = physical, 2 = digital/service).
                limit:
                  type: number
                  description: Maximum number of results to return.
                offset:
                  type: number
                  description: Offset for pagination.
                orderBy:
                  type: object
                  description: Sorting options.
                  properties:
                    fieldName:
                      type: string
                      enum:
                        - id
                        - balance
                        - price
                      description: Field to sort by.
                    direction:
                      type: string
                      enum:
                        - asc
                        - desc
                      description: Sorting direction (asc or desc).
                sections:
                  type: array
                  description: Filter by section-specific key-value attributes.
                  items:
                    properties:
                      key:
                        type: string
                        example: new
                        description: Section attribute key (e.g., color).
                      value:
                        type: string
                        example: york
                        description: Section attribute value (e.g., red).
                categoryIds:
                  type: array
                  description: List of category IDs to include in filter.
                  items:
                    type: number
      responses:
        '200':
          description: Successful response containing product data.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    description: Product data result.
                    properties:
                      id:
                        type: integer
                        description: Product ID.
                      name:
                        type: string
                        description: Product name.
                      userId:
                        type: integer
                        description: Owner user ID.
                      images:
                        type: array
                        items:
                          type: string
                        default:
                          - url1
                          - url2
                        description: List of product image URLs.
                      vendorCode:
                        type: string
                        description: Product vendor or article code.
                      type:
                        type: number
                        description: Product internal type code.
                      categoryId:
                        type: number
                        description: Product category ID.
                      visible:
                        type: boolean
                        description: Visibility flag (true = visible).
                      balance:
                        type: object
                        description: Product stock info.
                        properties:
                          type:
                            type: number
                            description: Stock unit type (same as input).
                          value:
                            type: number
                            description: Stock quantity.
                      price:
                        type: object
                        description: Product pricing info.
                        properties:
                          id:
                            type: number
                            description: Price record ID.
                          currency:
                            type: string
                            description: Currency code (e.g., USD).
                          value:
                            type: number
                            description: Current price value.
                          oldValue:
                            type: number
                            description: Previous price value.
                      countSales:
                        type: number
                        description: Total number of product sales.
                      createdAt:
                        type: string
                        description: Product creation datetime.
                      typeProduct:
                        type: number
                        enum:
                          - 1
                          - 2
                        description: Product type (1 = physical, 2 = digital/service).
      operationId: getProductsByFilter
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Fetches a filtered, paginated list of products from the ECommerce
        catalog. This is the primary product discovery endpoint — it acts as a
        flexible query interface supporting multi-dimensional filtering by
        category, price range, stock balance, visibility, and custom section
        attributes. Use it to power catalog search, inventory audits, and
        campaign product selection.
      x-ai-reasoning-instructions:
        - >-
          Determine which filters are actually needed — avoid sending empty
          filter objects as they may affect query performance.
        - >-
          If the user wants all products, omit all filter fields and rely only
          on limit/offset for pagination.
        - >-
          When filtering by price, always specify currency to ensure correct
          comparison across multi-currency catalogs.
        - >-
          For stock balance filtering, clarify the unit type (enum 1–7) with the
          user if it's not obvious from context.
        - >-
          Use categoryIds (array) instead of categoryId (single) when the user
          wants to query multiple categories at once.
        - >-
          Always include limit and offset for large catalogs to avoid unintended
          full-dataset responses.
        - >-
          If the user wants to find new or featured items, use the sections
          filter with appropriate key-value pairs.
      x-ai-responding-instructions:
        - >-
          Report the number of products returned and indicate if pagination is
          needed (i.e., if count equals limit).
        - >-
          Highlight key fields in results: product name, vendorCode, price,
          balance, and visibility status.
        - >-
          If results are empty, suggest relaxing filters (e.g., broader date
          range, removing balance constraints).
        - >-
          When returning products for campaign use, suggest following up with an
          endpoint to attach products to a mailing or automation flow.
      x-ai-suggestions:
        - 'Filter by visible: 1 to fetch only publicly listed products.'
        - Use dateFrom/dateTo to find recently added or updated products.
        - >-
          Combine typeProduct: 2 with price filter to audit digital product
          pricing.
        - >-
          Use orderBy: { fieldName: 'price', direction: 'asc' } to surface
          cheapest products first.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /products/categories/{categoryId}/{productId}:
    get:
      tags:
        - ECommerce Product
      summary: Get products by id
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
        - name: categoryId
          in: path
          required: true
          schema:
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      description:
                        type: string
                      shortDescription:
                        type: string
                      images:
                        type: array
                        default:
                          - url1
                          - url2
                      vendorCode:
                        type: string
                      categoryId:
                        type: number
                      balance:
                        type: object
                        properties:
                          type:
                            type: number
                          value:
                            type: number
                      availability:
                        type: number
                      visible:
                        type: number
                      userId:
                        type: number
                      seo:
                        type: object
                        properties:
                          name:
                            type: string
                          description:
                            type: string
                          keys:
                            type: string
                      prices:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            currency:
                              type: string
                            value:
                              type: number
                            oldValue:
                              type: number
                            isDefault:
                              type: boolean
                            productId:
                              type: number
                      sections:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            name:
                              type: string
                            productId:
                              type: number
                            values:
                              type: array
                              items:
                                properties:
                                  id:
                                    type: number
                                  sectionId:
                                    type: number
                                  key:
                                    type: string
                                  value:
                                    type: string
                      categorySections:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            name:
                              type: string
                            categoryId:
                              type: number
                            values:
                              type: array
                              items:
                                properties:
                                  id:
                                    type: number
                                  sectionId:
                                    type: number
                                  key:
                                    type: string
                                  value:
                                    type: string
      operationId: getCategoryProduct
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Retrieves full product details within a specific category context,
        including pricing tiers, inventory balance, SEO metadata, and custom
        sections. This endpoint is the authoritative source for rendering a
        product page — it returns not just core product data but also
        category-scoped attribute sections (categorySections) alongside
        product-specific sections, enabling dynamic storefront rendering without
        additional calls.
      x-ai-reasoning-instructions:
        - >-
          Both categoryId and productId are required — verify both are available
          before calling; a mismatch (product not belonging to the category) may
          return empty or 404.
        - >-
          Check the `availability` field (0 = unavailable, 1 = available) to
          determine whether to surface add-to-cart actions.
        - >-
          Check the `visible` field before displaying the product — hidden
          products should not be rendered in public storefronts.
        - >-
          When multiple prices are returned, use the one with `isDefault: true`
          as the primary display price; others may represent currency variants
          or tiered pricing.
        - >-
          The `balance` object contains inventory state — use `type` to
          interpret the balance model (e.g., numeric stock vs. unlimited).
        - >-
          Use `sections` for product-specific attributes and `categorySections`
          for category-level attributes — both may need to be merged for
          complete spec display.
      x-ai-responding-instructions:
        - >-
          Present the product name, short description, and default price as the
          primary summary.
        - >-
          If the product is not visible or not available, proactively flag this
          to the user rather than silently returning raw data.
        - >-
          When showing prices, highlight the default currency/price and mention
          if multi-currency options exist.
        - >-
          List sections and categorySections as structured attributes (key-value
          pairs) for clarity.
        - >-
          If images are present, list URLs to assist with rendering or
          downloading assets.
        - >-
          Mention the vendorCode if present — it's useful for inventory
          reconciliation or external system lookups.
      x-ai-suggestions:
        - Use this endpoint to populate a product detail page before rendering.
        - >-
          Combine with category listing endpoints to build breadcrumb navigation
          using the returned categoryId.
        - >-
          Cross-reference `vendorCode` with external ERP or warehouse systems
          for stock sync.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /products/deals:
    post:
      tags:
        - ECommerce Product
      summary: Add product to deal
      requestBody:
        content:
          application/json:
            schema:
              properties:
                productId:
                  type: number
                dealId:
                  type: number
                productPriceISO:
                  type: string
                  default: UAH
                productPriceValue:
                  type: number
                quantity:
                  type: number
                allow_out_of_stock:
                  type: boolean
                  description: >-
                    When true the product is attached even if stock is zero and
                    inventory is not decremented
      responses:
        '200':
          description: OK
      operationId: addProductToDeal
      x-ai-role: ecommerce_sales_manager
      x-ai-description: >-
        Links a product to a CRM deal, capturing the exact commercial terms
        (price, currency, quantity) at the time of attachment. This is the core
        mechanism for building deal line-items — each attachment represents a
        unit of revenue within the deal pipeline and directly affects deal value
        calculations.
      x-ai-reasoning-instructions:
        - >-
          Verify that both productId and dealId exist before attempting to link
          them.
        - >-
          Confirm the currency ISO code is valid (e.g., UAH, USD, EUR) before
          submission.
        - >-
          If productPriceValue is not provided, check whether the product has a
          default price to suggest.
        - >-
          If stock availability is uncertain, ask the user whether to set
          allow_out_of_stock=true rather than defaulting silently.
        - >-
          Consider whether the same product is already attached to the deal to
          avoid duplicate line-items.
      x-ai-responding-instructions:
        - >-
          Confirm the product was successfully linked and mention both the
          product and deal IDs.
        - >-
          If allow_out_of_stock was set to true, note that inventory was not
          decremented.
        - Suggest reviewing total deal value after adding line-items.
        - >-
          On failure, clarify whether the issue is with the product, the deal,
          or the stock constraint.
      x-ai-suggestions:
        - >-
          After attaching all products, retrieve the deal summary to verify
          total value.
        - >-
          Use the deal update endpoint to adjust status if all required products
          are now linked.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Confirm attaching product {productId} to deal {dealId} at
            {productPriceValue} {productPriceISO} × {quantity}?
        security_info:
          data_handling:
            - ResourceStateUpdate
            - InventoryModification
  /products/deals/{dealId}:
    get:
      tags:
        - ECommerce Product
      summary: Get products by deal id
      parameters:
        - name: dealId
          in: path
          required: true
          schema:
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      totalAmount:
                        type: integer
                      currency:
                        type: string
                      items:
                        type: array
                        items:
                          properties:
                            id:
                              type: integer
                            name:
                              type: string
                            description:
                              type: string
                            images:
                              type: array
                              default:
                                - url1
                                - url2
                            vendorCode:
                              type: string
                            extra:
                              type: object
                              properties:
                                quantity:
                                  type: number
                                amount:
                                  type: number
                                currency:
                                  type: string
                                totalAmount:
                                  type: number
                                outOfStock:
                                  type: boolean
      operationId: getProductsByDealId
      x-ai-role: ecommerce_sales_analyst
      x-ai-description: >-
        Retrieves the full product lineup attached to a specific CRM deal,
        including pricing summary and per-item detail. This endpoint is the
        primary way to inspect what a deal is worth and what SKUs it contains —
        critical for order confirmation, invoice generation, and upsell
        analysis.
      x-ai-reasoning-instructions:
        - >-
          Verify the dealId exists before interpreting an empty response as 'no
          products' — the deal itself may not exist.
        - >-
          Check `totalAmount` against the sum of `extra.totalAmount` across
          items to detect data inconsistencies.
        - >-
          If `extra.outOfStock` is true for any item, flag it to the user before
          proceeding with order or quote workflows.
        - >-
          Note that `currency` at the top level may differ from `extra.currency`
          per item — surface any mismatch.
      x-ai-responding-instructions:
        - >-
          Present a concise summary: total amount, currency, and item count
          before listing individual products.
        - Highlight any out-of-stock items prominently.
        - >-
          If the items array is empty, suggest verifying the dealId or checking
          whether products have been added to the deal.
        - >-
          When relevant, suggest following up with a deal-update endpoint to add
          or modify products.
      x-ai-suggestions:
        - Use this endpoint to build a pre-invoice product summary for a deal.
        - >-
          Combine with deal metadata endpoints to produce a full sales order
          view.
        - >-
          Cross-reference `vendorCode` with your inventory system to verify
          stock levels.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /products/deals/{headId}:
    put:
      tags:
        - ECommerce Product
      summary: Update quantity or amount products in deal
      parameters:
        - name: headId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              properties:
                quantity:
                  type: integer
                  description: Product quantity in the deal
                amount:
                  type: integer
                  description: Product amount in the deal
      responses:
        '200':
          description: OK
      operationId: updateProductsInDeal
      x-ai-role: ecommerce_sales_manager
      x-ai-description: >-
        Updates the quantity or monetary amount of products attached to a
        specific deal head. This is a core operation for maintaining accurate
        deal valuations in CRM pipelines — incorrect product quantities directly
        affect deal totals, forecasts, and revenue reporting.
      x-ai-reasoning-instructions:
        - >-
          Verify that the deal with the given headId exists before attempting an
          update.
        - >-
          At least one of `quantity` or `amount` must be provided — warn the
          user if both are omitted.
        - >-
          Clarify with the user whether `amount` represents unit price or total
          line value, as this affects downstream deal totals.
        - >-
          If updating quantity, consider whether the amount should be
          recalculated proportionally.
      x-ai-responding-instructions:
        - Confirm which fields were updated (quantity, amount, or both).
        - >-
          Suggest verifying the updated deal total using a deal retrieval
          endpoint.
        - >-
          If the deal is in a closed/won stage, warn that modifying product
          values may affect historical reporting.
      x-ai-suggestions:
        - >-
          Fetch the current deal state before updating to avoid overwriting
          stale data.
        - >-
          Use `getDealProducts` after updating to confirm the new values are
          reflected correctly.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating product values in a deal affects deal totals and may impact
            revenue forecasts.
        security_info:
          data_handling:
            - ResourceStateUpdate
  /products/contacts/{contactId}/deals:
    get:
      tags:
        - ECommerce Product
      summary: Get products by contact id
      parameters:
        - name: contactId
          in: path
          required: true
          schema:
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      totalAmount:
                        type: integer
                      currency:
                        type: string
                      items:
                        type: array
                        items:
                          properties:
                            id:
                              type: integer
                            name:
                              type: string
                            description:
                              type: string
                            images:
                              type: array
                              default:
                                - url1
                                - url2
                            vendorCode:
                              type: string
                            extra:
                              type: object
                              properties:
                                quantity:
                                  type: number
                                amount:
                                  type: number
                                currency:
                                  type: string
                                totalAmount:
                                  type: number
                                outOfStock:
                                  type: boolean
      operationId: getProductsByContactDeals
      x-ai-role: ecommerce_crm_analyst
      x-ai-description: >-
        Retrieves the list of products associated with deals linked to a
        specific CRM contact. This endpoint bridges CRM and eCommerce data — it
        allows agents to understand what products a contact has purchased or is
        interested in based on their deal history, enabling personalized
        follow-ups, upsell recommendations, and revenue attribution per contact.
      x-ai-reasoning-instructions:
        - >-
          Verify that the contactId corresponds to an existing CRM contact
          before calling this endpoint.
        - >-
          Treat the response as deal-scoped product data — the same product may
          appear across multiple deals; aggregate carefully if computing totals.
        - >-
          Check the `outOfStock` flag on individual items before recommending
          re-purchase or upsell actions.
        - >-
          Use `currency` fields at both the deal and item level — they may
          differ if the account supports multi-currency.
      x-ai-responding-instructions:
        - >-
          Summarize the deal's total amount and currency alongside the product
          list for immediate business context.
        - >-
          Highlight any items where `outOfStock` is true and suggest
          alternatives or follow-up actions.
        - >-
          If multiple products are returned, group them logically (e.g., by
          category or vendor code) to aid readability.
        - >-
          If the response is empty, clarify that this contact has no deals with
          associated products yet.
      x-ai-suggestions:
        - >-
          Use this endpoint before launching a re-engagement campaign to
          personalize product recommendations.
        - >-
          Combine with contact profile data to build a complete purchase history
          view.
        - >-
          Cross-reference `vendorCode` with your product catalog to enrich the
          response with additional metadata.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /products/categories/{categoryId}/{productId}/deals/{headId}:
    delete:
      tags:
        - ECommerce Product
      summary: Detach products from deal
      parameters:
        - name: categoryId
          in: path
          required: true
          schema:
            type: number
        - name: productId
          in: path
          required: true
          schema:
            type: number
        - name: headId
          in: path
          required: true
          schema:
            type: number
      responses:
        '200':
          description: OK
      operationId: detachProductFromDeal
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Removes a product from a specific deal within a category, breaking the
        association between the product and the deal head. Use this when a
        product should no longer participate in a promotional deal or bundle
        without deleting the product or deal itself.
      x-ai-reasoning-instructions:
        - >-
          Confirm that the deal (headId) currently includes the specified
          product before attempting detachment to avoid misleading 404 errors.
        - >-
          Verify that detaching this product will not violate any deal
          minimum-product requirements (e.g., a deal requiring at least one
          product).
        - >-
          If bulk detachment is needed, check whether the API supports batch
          operations before calling this endpoint repeatedly.
      x-ai-responding-instructions:
        - Confirm that the product has been successfully detached from the deal.
        - >-
          Clarify that neither the product nor the deal was deleted — only their
          association was removed.
        - >-
          Suggest reviewing remaining deal products via the appropriate GET
          endpoint to verify deal integrity after detachment.
      x-ai-suggestions:
        - >-
          After detachment, use the deal GET endpoint to confirm remaining
          associated products.
        - >-
          If you need to remove the deal entirely, use the delete deal endpoint
          instead.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will detach product #{productId} from deal #{headId}. The
            product and deal will remain intact, but their link will be removed.
        security_info:
          data_handling:
            - RelationshipDelete
  /products/{productId}:
    get:
      tags:
        - ECommerce Product
      summary: Get products by id
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      description:
                        type: string
                      shortDescription:
                        type: string
                      images:
                        type: array
                        default:
                          - url1
                          - url2
                      vendorCode:
                        type: string
                      type:
                        type: number
                      categoryId:
                        type: number
                      balance:
                        type: object
                        properties:
                          type:
                            type: number
                          value:
                            type: number
                      availability:
                        type: number
                      visible:
                        type: number
                      userId:
                        type: number
                      seo:
                        type: object
                        properties:
                          name:
                            type: string
                          description:
                            type: string
                          keys:
                            type: string
                      prices:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            currency:
                              type: string
                            value:
                              type: number
                            oldValue:
                              type: number
                            isDefault:
                              type: boolean
                            productId:
                              type: number
                      sections:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            name:
                              type: string
                            productId:
                              type: number
                            values:
                              type: array
                              items:
                                properties:
                                  id:
                                    type: number
                                  sectionId:
                                    type: number
                                  key:
                                    type: string
                                  value:
                                    type: string
                      categorySections:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            name:
                              type: string
                            categoryId:
                              type: number
                            values:
                              type: array
                              items:
                                properties:
                                  id:
                                    type: number
                                  sectionId:
                                    type: number
                                  key:
                                    type: string
                                  value:
                                    type: string
      operationId: getProductById
      x-ai-role: ecommerce_catalog_specialist
      x-ai-description: >-
        Retrieves the full product record by its unique identifier, including
        pricing tiers, inventory balance, SEO metadata, custom sections, and
        category-level attribute sections. This is the canonical source of truth
        for a single product entity and serves as the primary read operation
        before any update, display, or recommendation workflow.
      x-ai-reasoning-instructions:
        - >-
          Confirm that productId is a valid numeric identifier before calling —
          string slugs or SKUs will not work here.
        - >-
          Check the `availability` field to determine whether the product can be
          sold or shown to end users.
        - >-
          Use `balance.type` and `balance.value` together to interpret stock
          semantics — type may indicate unit (pieces, weight, etc.).
        - >-
          If the goal is to display pricing, iterate `prices` and filter by
          `isDefault: true` for the primary price; use `oldValue` to detect
          discounted items.
        - >-
          For personalization or filtering use cases, `sections` holds
          product-specific attributes while `categorySections` holds
          category-level attributes — treat them separately.
        - >-
          If `visible` is 0, the product is hidden from the storefront; flag
          this to the user before proceeding with campaigns or recommendations.
      x-ai-responding-instructions:
        - Lead with the product name and its current availability status.
        - >-
          Surface the default price prominently; mention if a discounted price
          (oldValue) exists.
        - >-
          If sections or categorySections are present, summarize the key
          attributes (e.g., color, size) rather than dumping raw arrays.
        - >-
          Highlight SEO fields if the user's context involves content or
          marketing tasks.
        - >-
          If the product is not visible or out of stock, clearly flag this as a
          potential issue for the intended workflow.
      x-ai-suggestions:
        - >-
          Use `vendorCode` to cross-reference with external inventory or ERP
          systems.
        - >-
          After retrieval, consider calling the product update endpoint if any
          fields need correction.
        - Use `categoryId` to fetch sibling products or category-level settings.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    put:
      tags:
        - ECommerce Product
      summary: Update product by id
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
          description: ID of the product to update
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Product name
                description:
                  type: string
                  description: Full product description
                shortDescription:
                  type: string
                  description: Short product summary
                images:
                  type: array
                  default:
                    - url1
                    - url2
                  description: Array of product image URLs
                vendorCode:
                  type: string
                  description: Vendor or manufacturer code
                categoryId:
                  type: number
                  description: Category ID the product belongs to
                balance:
                  type: object
                  description: Stock balance information
                  properties:
                    type:
                      type: number
                      description: Balance type (e.g. available, reserved)
                    value:
                      type: number
                      description: Balance quantity
                availability:
                  type: number
                  description: Product availability status
                visible:
                  type: number
                  description: Visibility flag (0 - hidden, 1 - visible)
                seo:
                  type: object
                  description: SEO-related metadata
                  properties:
                    name:
                      type: string
                      description: SEO title
                    description:
                      type: string
                      description: SEO description
                    keys:
                      type: string
                      description: SEO keywords
                digitalInfo:
                  type: object
                  description: Digital product details
                  properties:
                    productLink:
                      type: string
                      description: Direct link to digital product
                    productLinkPreview:
                      type: string
                      description: Link to preview of digital product
                    isProductLinkExternal:
                      type: boolean
                      description: Is product link external
                    isProductLinkPreviewExternal:
                      type: boolean
                      description: Is preview link external
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Product ID
                      name:
                        type: string
                        description: Product name
                      description:
                        type: string
                        description: Full product description
                      shortDescription:
                        type: string
                        description: Short product summary
                      images:
                        type: array
                        default:
                          - url1
                          - url2
                        description: Array of product image URLs
                      vendorCode:
                        type: string
                        description: Vendor or manufacturer code
                      type:
                        type: number
                        description: Product type
                      categoryId:
                        type: number
                        description: Category ID
                      balance:
                        type: object
                        description: Stock balance info
                        properties:
                          type:
                            type: number
                            description: Balance type
                          value:
                            type: number
                            description: Balance value
                      availability:
                        type: number
                        description: Availability status
                      visible:
                        type: number
                        description: Visibility flag
                      userId:
                        type: number
                        description: ID of the user who owns or created the product
                      seo:
                        type: object
                        description: SEO metadata
                        properties:
                          name:
                            type: string
                            description: SEO title
                          description:
                            type: string
                            description: SEO description
                          keys:
                            type: string
                            description: SEO keywords
                      prices:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                              description: Price ID
                            currency:
                              type: string
                              description: Currency code
                            value:
                              type: number
                              description: Current price
                            oldValue:
                              type: number
                              description: Old price (before discount)
                            isDefault:
                              type: boolean
                              description: Flag indicating default price
                            productId:
                              type: number
                              description: Associated product ID
                      sections:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                              description: Section ID
                            name:
                              type: string
                              description: Section name
                            productId:
                              type: number
                              description: Related product ID
                            status:
                              type: number
                              description: Section status
                            values:
                              type: array
                              items:
                                properties:
                                  id:
                                    type: number
                                    description: Value ID
                                  sectionId:
                                    type: number
                                    description: Section ID this value belongs to
                                  key:
                                    type: string
                                    description: Parameter key
                                  value:
                                    type: string
                                    description: Parameter value
                                  status:
                                    type: number
                                    description: Status of the parameter
                      digitalInfo:
                        type: object
                        description: Digital product info
                        properties:
                          productLink:
                            type: string
                            description: Digital product link
                          productLinkPreview:
                            type: string
                            description: Preview link for digital product
                          isProductLinkExternal:
                            type: boolean
                            description: Is digital product link external
                          isProductLinkPreviewExternal:
                            type: boolean
                            description: Is preview link external
      operationId: updateProduct
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Performs a partial or full update of an existing product in the
        e-commerce catalog. This endpoint is the primary mechanism for keeping
        product data current — including stock balance, pricing visibility, SEO
        metadata, and digital delivery links. Changes take effect immediately
        and can affect storefront display, search indexing, and purchase
        availability.
      x-ai-reasoning-instructions:
        - >-
          Only include fields that need to be changed — omitted fields retain
          their current values.
        - >-
          Before updating `categoryId`, confirm the target category exists to
          avoid orphaned product assignments.
        - >-
          When toggling `visible` to 0, consider whether active campaigns or
          automations reference this product.
        - >-
          If updating `balance.value` to 0, verify whether this should also set
          `availability` to unavailable (e.g., 0).
        - >-
          For digital products, ensure `digitalInfo.productLink` is accessible
          and not behind auth if `isProductLinkExternal` is true.
        - >-
          SEO fields (`seo.name`, `seo.description`, `seo.keys`) directly affect
          search engine indexing — changes may take time to propagate.
        - >-
          If updating images, provide the full desired array — it replaces the
          existing image list, not appends to it.
      x-ai-responding-instructions:
        - >-
          Confirm the update by referencing the product ID and name from the
          response.
        - >-
          If `visible` was changed, explicitly state the new storefront
          visibility status.
        - >-
          If stock balance was updated, mention the new balance value and type
          for clarity.
        - >-
          Suggest reviewing prices or sections if a category change was made, as
          those may need alignment.
        - >-
          For digital products, confirm the delivery link is set correctly and
          note whether it's external or internal.
      x-ai-suggestions:
        - To restock a product, update `balance.value` with the new quantity.
        - To hide a product temporarily without deleting it, set `visible` to 0.
        - >-
          After updating SEO fields, allow up to 24–48 hours for search engines
          to re-index.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to update product {productId}. Confirm the changes
            before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - StorefrontVisibilityChange
    delete:
      tags:
        - ECommerce Product
      summary: Delete product by id
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
          description: ID of the product to delete
      responses:
        '204':
          description: OK
      operationId: deleteProduct
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Permanently removes a product from the catalog by its unique identifier.
        This is a destructive, irreversible operation that should be used when a
        product is discontinued or was created in error. Deletion may affect
        active campaigns, automations, or recommendations referencing this
        product.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, verify the productId exists to avoid misleading 404
          errors.
        - >-
          Warn the user if the product may be referenced in active email
          campaigns or automation flows.
        - >-
          Confirm the intent — deletion is permanent and cannot be undone via
          the API.
        - >-
          If the goal is to hide a product rather than remove it, suggest
          disabling it instead if such an option exists.
      x-ai-responding-instructions:
        - >-
          Confirm the product was successfully deleted (HTTP 204 means no
          content — operation succeeded).
        - >-
          Remind the user that any campaigns or automations using this product
          ID may now reference a non-existent resource.
        - >-
          Suggest auditing related automations or product blocks in emails after
          deletion.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This action permanently deletes the product and cannot be undone.
            Confirm the productId before proceeding.
        security_info:
          data_handling:
            - IrreversibleDelete
  /products/categories/{categoryId}:
    put:
      tags:
        - ECommerce Product
      summary: Update users category by id
      parameters:
        - name: categoryId
          in: path
          required: true
          schema:
            type: number
      requestBody:
        content:
          application/json:
            schema:
              properties:
                parentId:
                  type: number
                name:
                  type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      userId:
                        type: integer
                      parentId:
                        type: integer
      operationId: updateProductCategory
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Updates an existing product category in the e-commerce catalog.
        Categories form a hierarchical tree via parentId — changing parentId
        relocates the category within the taxonomy, which may affect storefront
        navigation, filtering logic, and any products already associated with
        this category.
      x-ai-reasoning-instructions:
        - >-
          Before updating, confirm the categoryId exists to avoid a silent no-op
          or 404.
        - >-
          If parentId is being changed, verify the new parent exists and is not
          the category itself or one of its descendants — circular hierarchies
          are invalid.
        - >-
          If only name is provided, treat it as a rename-only operation and
          preserve the existing parentId.
        - >-
          Check whether any active products or subcategories depend on this
          category before renaming, as it may affect external integrations or
          URLs.
      x-ai-responding-instructions:
        - >-
          Confirm the update by echoing back the updated category name and its
          id.
        - >-
          If parentId was changed, note the new position in the hierarchy
          explicitly.
        - >-
          Suggest verifying affected products or subcategories as a follow-up if
          a structural (parentId) change was made.
      x-ai-suggestions:
        - Rename a category without changing its position by omitting parentId.
        - Move a subcategory to the root level by setting parentId to 0 or null.
        - >-
          Use GET /products/categories to retrieve the full hierarchy before
          restructuring.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Confirm before changing parentId as it restructures the category
            hierarchy and may affect storefront navigation.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - ECommerce Product
      summary: Delete users category by id
      parameters:
        - name: categoryId
          in: path
          required: true
          schema:
            type: number
      responses:
        '204':
          description: OK
      operationId: deleteProductCategory
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Permanently removes a product category from the store catalog. Deleting
        a category may affect product visibility and navigation structure —
        products assigned exclusively to this category may become uncategorized
        or hidden, impacting storefront display and SEO.
      x-ai-reasoning-instructions:
        - >-
          Before deleting, check whether any products are assigned to this
          category to avoid orphaning items.
        - >-
          Warn the user that this action is irreversible — the category and its
          hierarchy position cannot be restored.
        - >-
          If the category is a parent of subcategories, clarify whether child
          categories will also be removed or reassigned.
        - >-
          Confirm the correct categoryId is targeted, especially in bulk
          operations.
      x-ai-responding-instructions:
        - Confirm successful deletion with the categoryId that was removed.
        - >-
          If products were associated with this category, suggest reassigning
          them to another category immediately.
        - >-
          If deletion fails (e.g., category not found or has dependencies),
          explain the reason and suggest resolution steps.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            Deleting a category is permanent and may affect product visibility.
            Confirm before proceeding.
        security_info:
          data_handling:
            - DestructiveOperation
            - ResourceStateUpdate
  /contacts/external/{externalContactId}:
    get:
      tags:
        - Contacts
      summary: Get contact exists by external contact Id
      parameters:
        - name: externalContactId
          in: path
          required: true
          description: External contact id from another source system
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      data:
                        $ref: '#/components/schemas/Contact'
      operationId: getContactByExternalId
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Looks up a SendPulse contact using an ID from an external system (e.g.,
        your CRM, e-commerce platform, or data warehouse). This is the bridge
        endpoint for cross-system identity resolution — it lets you avoid
        storing SendPulse-internal IDs in your own database by querying via the
        ID you already own.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint when the caller has an external system ID but not
          the SendPulse contact ID.
        - >-
          If the response returns no contact, suggest verifying that the
          external ID was previously linked during contact creation or update.
        - >-
          Prefer this over a full contact search when the external ID mapping is
          known — it is more precise and avoids pagination overhead.
        - >-
          Consider caching the resolved SendPulse contact ID on your side to
          reduce repeated lookups.
      x-ai-responding-instructions:
        - >-
          Return the resolved contact object and highlight the SendPulse contact
          ID for the user.
        - >-
          If the contact is not found (404 or empty data), explain that the
          external ID may not have been mapped in SendPulse yet.
        - >-
          Suggest follow-up actions such as updating contact data or triggering
          a flow based on the resolved contact.
      x-ai-suggestions:
        - >-
          Use the returned contact ID with `updateContact` to sync field changes
          from your source system.
        - >-
          If the contact is not found, use `createContact` with the same
          externalContactId to establish the mapping.
        - >-
          Chain with `getContactDeals` or `getContactTasks` for a full CRM
          context view.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /products/categories:
    get:
      tags:
        - ECommerce Product
      summary: Get users categories
      responses:
        '200':
          description: List of user categories in a nested tree structure
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: array
                    items:
                      properties:
                        tree:
                          type: array
                          description: Hierarchical structure of categories
                          items:
                            properties:
                              id:
                                type: integer
                                description: Category ID
                              name:
                                type: string
                                description: Category name
                              parent_id:
                                type: integer
                                description: ID of the parent category
                              depth:
                                type: integer
                                description: Level of category in the tree
                              path:
                                type: integer
                                description: Encoded tree path or identifier
                              children:
                                type: array
                                description: List of subcategories
                                items:
                                  properties:
                                    id:
                                      type: integer
                                      description: Category ID
                                    name:
                                      type: string
                                      description: Category name
                                    parent_id:
                                      type: integer
                                      description: ID of the parent category
                                    depth:
                                      type: integer
                                      description: Level of category in the tree
                                    path:
                                      type: integer
                                      description: Encoded tree path or identifier
                                    children:
                                      type: array
                                      description: Nested children categories
                        count:
                          type: integer
                          description: Total number of categories
      operationId: getProductCategories
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Retrieves the full category tree for the user's e-commerce store.
        Categories are returned as a nested hierarchical structure with depth
        and path metadata, which is essential for building navigation menus,
        filtering product listings, and assigning products to the correct
        taxonomy nodes. The tree shape means that root categories contain
        children arrays — traverse recursively to get the full picture.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint before creating or updating products to determine
          valid category IDs for assignment.
        - >-
          The response is a full tree — if you need a flat list of all
          categories, flatten the nested `children` arrays recursively.
        - >-
          Pay attention to `depth` and `parent_id` to understand hierarchy
          level; root categories have `parent_id` of null or 0.
        - >-
          If the category count is large, consider caching the result
          client-side rather than calling repeatedly within the same workflow.
      x-ai-responding-instructions:
        - >-
          Present the category structure in a human-readable tree format, not as
          raw JSON.
        - Highlight the total count of categories returned.
        - >-
          If the user is looking for a specific category, suggest filtering by
          name from the returned list.
        - >-
          Suggest using the retrieved category IDs as input for product creation
          or filtering endpoints.
      x-ai-suggestions:
        - >-
          Use returned category IDs with `createProduct` or `updateProduct` to
          assign products to correct categories.
        - >-
          If no categories exist, suggest creating root categories first before
          adding products.
        - >-
          Use `depth` field to distinguish root (0) from subcategories when
          rendering navigation.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - ECommerce Product
      summary: Store users categories
      requestBody:
        content:
          application/json:
            schema:
              properties:
                parentId:
                  type: number
                  description: ID of parent category. Null for root.
                name:
                  type: string
                  description: Name of the category
                sections:
                  type: array
                  description: Sections belonging to the category
                  items:
                    properties:
                      name:
                        type: string
                        description: Section name
                      status:
                        type: integer
                        description: Section status (e.g., 1 - active)
                      values:
                        type: array
                        description: List of values for the section
                        items:
                          properties:
                            key:
                              type: string
                              description: Attribute key
                            value:
                              type: string
                              description: Attribute value
                            status:
                              type: integer
                              description: Status of the attribute value
      responses:
        '201':
          description: Category successfully created
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                        description: Newly created category ID
                      name:
                        type: string
                        description: Name of the created category
                      userId:
                        type: integer
                        description: ID of the user who created the category
                      parentId:
                        type: integer
                        description: ID of the parent category
      operationId: createProductCategory
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Creates a new product category in the SendPulse e-commerce catalog.
        Categories define the hierarchical taxonomy of the product tree — root
        categories group high-level domains, while nested categories and
        sections carry structured attribute schemas (e.g., size, color,
        material) that will be inherited by products assigned to this category.
      x-ai-reasoning-instructions:
        - >-
          Check if a category with the same name already exists at the same
          hierarchy level to avoid duplicate taxonomy entries.
        - >-
          If parentId is null, this will become a root category — confirm with
          the user that the top-level placement is intentional.
        - >-
          Validate that section values have consistent key naming conventions
          (e.g., snake_case) to ensure compatibility with product attribute
          assignment later.
        - >-
          If sections are provided, verify that each section has at least one
          value with a valid status to be immediately usable.
      x-ai-responding-instructions:
        - >-
          Confirm successful creation by stating the new category ID and its
          position in the hierarchy (root vs. child).
        - >-
          If sections with values were included, briefly summarize how many
          attribute groups were attached.
        - >-
          Suggest the next step: assigning products to this category or creating
          sub-categories using the same endpoint with the returned ID as
          parentId.
      x-ai-suggestions:
        - Electronics > Smartphones
        - Clothing > Men > Outerwear
        - Home & Garden > Furniture
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /products/{productId}/prices:
    put:
      tags:
        - ECommerce Product
      summary: Update price in product
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
          description: ID of the product to update prices for
      requestBody:
        content:
          application/json:
            schema:
              properties:
                prices:
                  type: array
                  description: List of prices for the product
                  items:
                    properties:
                      id:
                        type: number
                        description: ID of the price record
                      currency:
                        type: string
                        description: Currency code (e.g., USD, EUR)
                      value:
                        type: number
                        description: Current price value
                      oldValue:
                        type: number
                        description: Previous price value
                      isDefault:
                        type: boolean
                        description: Whether this price is the default one
      responses:
        '200':
          description: Prices successfully updated
      operationId: updateProductPrices
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Updates the pricing configuration for a specific product, supporting
        multi-currency price records with optional 'old price' for visual
        discounts. This is a full replacement of the price list for the given
        product — missing price IDs may be removed depending on backend
        behavior. Setting a default price affects which value is shown first in
        storefronts and used in automated flows.
      x-ai-reasoning-instructions:
        - >-
          Confirm the productId exists before attempting the update to avoid
          silent failures.
        - >-
          Ensure exactly one price has `isDefault: true`; having none or
          multiple defaults may cause inconsistent storefront behavior.
        - >-
          Validate that all currency codes follow ISO 4217 (e.g., USD, EUR, UAH)
          before submitting.
        - >-
          If `oldValue` is provided, verify it is greater than `value` —
          otherwise it has no visual discount effect and may mislead customers.
        - >-
          Treat this as a replacement operation: if existing price records are
          omitted, confirm with the user whether deletion is intended.
      x-ai-responding-instructions:
        - >-
          Confirm which currencies were updated and which price is now marked as
          default.
        - >-
          If `oldValue` was set, mention that the discount indicator will be
          visible on the storefront.
        - >-
          Suggest verifying the result by fetching the product's current prices
          after the update.
      x-ai-suggestions:
        - >-
          Set `isDefault: true` on the primary currency price (e.g., USD) to
          ensure consistent checkout behavior.
        - >-
          Use `oldValue` to display a strikethrough 'was' price for promotional
          campaigns.
        - >-
          After updating prices, consider triggering a product sync if
          integrated with an external storefront.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to overwrite all price records for this product.
            Please confirm the new price list is complete.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PotentialDataLoss
  /products/{productId}/sections:
    post:
      tags:
        - ECommerce Product
      summary: Update section in product
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
          description: ID of the product to update sections for
      requestBody:
        content:
          application/json:
            schema:
              properties:
                sections:
                  type: array
                  description: List of sections to update
                  items:
                    properties:
                      id:
                        type: number
                        description: ID of the section
                      name:
                        type: string
                        description: Section name
                      status:
                        type: number
                        description: Section status (e.g., 1 - active)
                      values:
                        type: array
                        description: Attributes or values inside the section
                        items:
                          properties:
                            id:
                              type: number
                              description: ID of the value
                            key:
                              type: string
                              description: Name of the attribute
                            value:
                              type: string
                              description: Value of the attribute
                            status:
                              type: number
                              description: Status of the attribute value
      responses:
        '201':
          description: Sections successfully created
      operationId: updateProductSections
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Replaces or creates sections within a specific product — sections are
        structured attribute groups (e.g., 'Specifications', 'Dimensions') that
        organize key-value metadata shown to customers. This endpoint is the
        primary mechanism for defining or updating a product's structured
        content beyond basic fields.
      x-ai-reasoning-instructions:
        - Verify the productId exists before sending the request to avoid a 404.
        - >-
          Each section can contain multiple attribute values via the `values`
          array — confirm all required attributes are included to avoid
          incomplete product data.
        - >-
          If updating existing sections, include their `id` fields; omitting
          `id` may result in duplicate sections depending on API behavior.
        - >-
          Check `status` semantics: value `1` is active — set inactive sections
          to `0` rather than deleting them to preserve historical data.
        - >-
          Validate that `key` names within `values` are consistent across
          products to maintain catalog uniformity.
      x-ai-responding-instructions:
        - >-
          Confirm which sections were updated and how many attribute values were
          affected.
        - >-
          If the response is 201, clarify to the user that sections were
          successfully applied, even though this is a POST (not PATCH).
        - >-
          Suggest verifying the result by fetching the product to confirm
          section structure.
        - >-
          If sections contain pricing or availability attributes, warn the user
          that changes may be immediately visible to customers.
      x-ai-suggestions:
        - >-
          Use distinct `name` values per section such as 'Technical
          Specifications', 'Physical Dimensions', 'Compatibility'.
        - >-
          Set `status: 1` for all active sections; use `status: 0` to soft-hide
          a section without removing it.
        - >-
          After updating sections, call the product retrieval endpoint to verify
          the final structure.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            Updating product sections may overwrite existing structured
            attributes visible to customers. Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - CustomerFacingDataChange
    put:
      tags:
        - ECommerce Product
      summary: Update section in product
      parameters:
        - name: productId
          in: path
          required: true
          schema:
            type: number
          description: ID of the product to update sections for
      requestBody:
        content:
          application/json:
            schema:
              properties:
                sections:
                  type: array
                  description: List of sections to update
                  items:
                    properties:
                      id:
                        type: number
                        description: ID of the section
                      name:
                        type: string
                        description: Section name
                      status:
                        type: number
                        description: Section status (e.g., 1 - active)
                      values:
                        type: array
                        description: Attributes or values inside the section
                        items:
                          properties:
                            id:
                              type: number
                              description: ID of the value
                            key:
                              type: string
                              description: Name of the attribute
                            value:
                              type: string
                              description: Value of the attribute
                            status:
                              type: number
                              description: Status of the attribute value
      responses:
        '200':
          description: Sections successfully updated
      operationId: updateProductSections
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Updates structured content sections within a product, including their
        names, statuses, and typed attribute values. Sections define the
        product's informational schema — each section groups related attributes
        (key-value pairs) that describe characteristics like materials,
        dimensions, or specifications. Modifying sections affects how the
        product is displayed and indexed across the catalog.
      x-ai-reasoning-instructions:
        - >-
          Fetch the current product sections before updating to identify
          existing IDs and avoid accidental data loss.
        - >-
          Ensure each section `id` in the payload corresponds to an existing
          section — omitting or mismatching IDs may silently drop sections.
        - >-
          When updating `values`, include all existing value entries alongside
          new ones; partial arrays may overwrite and discard unlisted values.
        - >-
          Validate that `status` fields use recognized values (e.g., 1 = active,
          0 = inactive) per the platform's enumeration.
        - >-
          If updating attribute keys (`key` field), verify uniqueness within the
          section to prevent schema conflicts.
      x-ai-responding-instructions:
        - >-
          Confirm which sections and attributes were updated, referencing
          section names where possible.
        - >-
          If the response indicates partial failure, clearly identify which
          sections or values were not applied.
        - >-
          Suggest reviewing the product detail endpoint to verify the changes
          are reflected correctly.
        - >-
          Warn the user if they appear to be replacing all sections with a
          reduced set, as this may remove existing data.
      x-ai-suggestions:
        - >-
          Retrieve current sections first via GET /products/{productId} to build
          a complete update payload.
        - >-
          After updating, validate the result with a GET request to confirm
          section structure integrity.
        - >-
          Use status=0 to deactivate a section without deleting it, preserving
          historical data.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This operation overwrites section data. Confirm the payload includes
            all sections and values intended to remain active.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - PotentialDataLoss
  /products/{productId}/sections/{sectionId}:
    delete:
      tags:
        - ECommerce Product
      summary: Delete products section
      parameters:
        - name: productId
          in: path
          required: true
          description: ID of the product to delete sections from
          schema:
            type: number
        - name: sectionId
          in: path
          required: true
          schema:
            type: number
          description: ID of the section to delete
      responses:
        '204':
          description: OK
      operationId: deleteProductSection
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Permanently removes a specific section from a product, including all
        content nested within it. Sections structure the product page layout —
        deleting one collapses that part of the product presentation. This is a
        destructive, irreversible operation that directly affects what customers
        see on the storefront.
      x-ai-reasoning-instructions:
        - >-
          Confirm that both productId and sectionId are valid and belong to the
          same product before proceeding.
        - >-
          Warn the user that this action is irreversible — all content within
          the section will be lost.
        - >-
          Check if this is the last section on the product; removing it may
          result in an incomplete or broken product page.
        - >-
          If operating in an automated flow, require explicit confirmation
          before executing deletion.
      x-ai-responding-instructions:
        - >-
          Confirm the section was successfully deleted (204 No Content means
          success).
        - >-
          Remind the user that the change is permanent and the section cannot be
          restored.
        - >-
          Suggest reviewing the product page after deletion to ensure the layout
          remains valid.
        - >-
          If an error occurs, clarify whether it was due to an invalid
          productId, sectionId, or insufficient permissions.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This will permanently delete section {sectionId} from product
            {productId}. This action cannot be undone.
        security_info:
          data_handling:
            - IrreversibleDelete
            - ResourceStateUpdate
  /contacts/messenger-external/{messengerContactId}:
    get:
      tags:
        - Contacts
      summary: Get contact by messenger contact id
      parameters:
        - name: messengerContactId
          in: path
          required: true
          description: External contact id from messenger
          schema:
            type: string
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    properties:
                      data:
                        $ref: '#/components/schemas/Contact'
      operationId: getContactByMessengerExternalId
      x-ai-role: crm_integration_specialist
      x-ai-description: >-
        Resolves a CRM contact record using a messenger-side identifier. This is
        the bridge endpoint between external chat platforms (e.g., Telegram,
        Facebook Messenger) and the SendPulse CRM — use it when you have a
        messenger user ID but need the full CRM contact profile to read history,
        tags, or custom fields.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint when the available identifier is a messenger contact
          ID, not a CRM-native contact ID.
        - >-
          Verify that the messengerContactId originates from a connected
          messenger integration; unregistered IDs will return 404.
        - >-
          If the goal is to enrich or update the contact after lookup, follow up
          with a PATCH/PUT contact endpoint using the returned CRM contact ID.
      x-ai-responding-instructions:
        - >-
          Confirm which contact was resolved by referencing their name or email
          from the response.
        - >-
          If the contact is not found, clarify that the messenger contact may
          not be linked to any CRM record yet and suggest triggering a
          conversation flow to capture it.
        - >-
          Surface the internal CRM contact ID from the response so the user can
          reference it in subsequent operations.
      x-ai-suggestions:
        - >-
          After retrieving the contact, use the CRM contact ID to fetch their
          deal pipeline or tag history.
        - >-
          If lookup fails, consider using the contact search endpoint with
          messenger channel filters as a fallback.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /contacts/{contactId}/relation/{companyId}:
    post:
      tags:
        - Contacts
      summary: Add contact to a company
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID you want to add to the company. It can be obtained with
            the "Get a list of contacts" method
          schema:
            type: integer
        - name: companyId
          in: path
          required: true
          description: >-
            Company ID you want to add to the contact. It can be obtained with
            the "Get a list of company" method
          schema:
            type: integer
      responses:
        '200':
          description: Contact successfully added to a company
      operationId: addContactCompanyRelation
      x-ai-role: crm_relationship_manager
      x-ai-description: >-
        Establishes a many-to-one relationship between a contact and a company
        in the CRM graph. This is not just a tag — it links the contact to the
        company's hierarchy, enabling company-level analytics, bulk actions, and
        deal attribution across all contacts belonging to that company.
      x-ai-reasoning-instructions:
        - >-
          Verify that both contactId and companyId exist before attempting to
          link — use 'Get a list of contacts' and 'Get a list of company' to
          resolve IDs if only names are provided.
        - >-
          Check whether the contact is already linked to this company to avoid
          duplicate relation requests.
        - >-
          If linking multiple contacts to the same company, consider whether a
          bulk operation is available instead of sequential calls.
      x-ai-responding-instructions:
        - >-
          Confirm the relation was created by restating which contact was linked
          to which company.
        - >-
          Suggest following up with 'Get contact details' to verify the updated
          company association.
        - >-
          If either ID is invalid or the relation already exists, explain
          clearly and offer to look up the correct IDs.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contacts' to find contactId by name or email before
          calling this endpoint.
        - Use 'Get a list of company' to resolve companyId by company name.
        - >-
          After linking, consider updating the contact's role or deal stage
          within that company.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to link contact #{contactId} to company #{companyId}.
            Confirm?
        security_info:
          data_handling:
            - RelationshipCreate
    delete:
      tags:
        - Contacts
      summary: Delete a contact from the company
      parameters:
        - name: contactId
          in: path
          required: true
          description: >-
            Contact ID you want to delete from the company. It can be obtained
            with the "Get a list of contacts" method
          schema:
            type: integer
        - name: companyId
          in: path
          required: true
          description: >-
            Company ID you want to delete from the contact. It can be obtained
            with the "Get a list of company" method
          schema:
            type: integer
      responses:
        '200':
          description: Contact successfully deleted from the company
      operationId: deleteContactCompanyRelation
      x-ai-role: crm_relationship_manager
      x-ai-description: >-
        Removes the association between a specific contact and a company in the
        CRM. This is a structural operation that affects the contact's
        organizational affiliation — it does not delete the contact or the
        company, only the link between them. Use when a contact changes
        employer, leaves a company, or was incorrectly assigned.
      x-ai-reasoning-instructions:
        - >-
          Before proceeding, confirm that both the contactId and companyId are
          valid and that the relation actually exists — otherwise the operation
          may fail silently or return a misleading error.
        - >-
          Warn the user that this is irreversible: the relation must be
          re-created manually if removed by mistake.
        - >-
          If the intent is to reassign the contact to a different company,
          advise creating the new relation first before deleting this one.
      x-ai-responding-instructions:
        - >-
          Confirm that the contact has been successfully unlinked from the
          company, mentioning both IDs.
        - >-
          Clarify that neither the contact nor the company record was deleted —
          only the relationship was removed.
        - >-
          Suggest verifying the contact's current company associations using
          'Get a list of contacts' if the user needs to confirm the resulting
          state.
      x-ai-suggestions:
        - >-
          Use 'Get a list of contacts' to retrieve the contactId before calling
          this endpoint.
        - >-
          Use 'Get a list of company' to retrieve the companyId before calling
          this endpoint.
        - >-
          After deletion, consider creating a new relation if the contact should
          be linked to a different company.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the contact-company association.
            Proceed?
        security_info:
          data_handling:
            - RelationshipDeletion
  /manager-settings/sections:
    get:
      tags:
        - ManagerSettings
      summary: Get all sections
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/ManagerSettings'
      operationId: listManagerSettingsSections
      x-ai-role: crm_configuration_specialist
      x-ai-description: >-
        Retrieves the full list of manager settings sections available in the
        account. Sections represent logical groupings of configurable parameters
        for CRM managers — such as access control, interface preferences, or
        notification rules. Use this endpoint to discover what configuration
        domains exist before reading or modifying specific settings.
      x-ai-reasoning-instructions:
        - >-
          Call this endpoint first when the user wants to configure or inspect
          manager settings — it provides the valid section identifiers.
        - >-
          If the user asks about a specific setting, match it against the
          returned sections before proceeding.
        - >-
          Treat the response as a discovery step: the section list may vary by
          account tier or role.
      x-ai-responding-instructions:
        - >-
          List the returned sections by name so the user can identify which one
          is relevant to their goal.
        - >-
          If the list is empty, inform the user that no sections are configured
          and suggest checking account permissions.
        - >-
          Suggest a follow-up action such as fetching details for a specific
          section.
      x-ai-suggestions:
        - >-
          Use the returned section identifiers to fetch or update specific
          manager settings.
        - >-
          Combine with role/permission data to determine which sections the
          current manager can modify.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /manager-settings/managers:
    get:
      tags:
        - ManagerSettings
      summary: Get all managers
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/ManagerSettings'
      operationId: getManagerSettingsManagers
      x-ai-role: crm_operations_manager
      x-ai-description: >-
        Retrieves the full list of managers configured in the account along with
        their settings. This endpoint is the entry point for any manager-related
        orchestration — use it to discover available managers, verify assignment
        coverage, or audit access distribution before creating or updating CRM
        workflows.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint before assigning a manager to a deal or contact to
          ensure the target manager exists and is active.
        - >-
          If the response list is empty, inform the user that no managers have
          been configured yet and suggest navigating to account settings.
        - >-
          When the user asks 'who is responsible for X', fetch this list first
          to map manager IDs to names.
      x-ai-responding-instructions:
        - >-
          Present managers as a structured list with their key identifiers (id,
          name, email) for easy selection.
        - >-
          If the list is large, offer to filter by a specific attribute the user
          is looking for.
        - >-
          Suggest follow-up actions such as assigning a manager to a pipeline
          stage or updating manager settings.
      x-ai-suggestions:
        - >-
          Use the returned manager IDs with endpoints that accept a `manager_id`
          parameter.
        - >-
          Cross-reference with deal or contact assignment endpoints to audit
          coverage gaps.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /manager-settings:
    post:
      tags:
        - ManagerSettings
      summary: Create managers from category
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                sectionId:
                  type: integer
                responsibleIds:
                  type: array
                  items:
                    type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ManagerSettings'
      operationId: createManagerSettings
      x-ai-role: crm_access_control_specialist
      x-ai-description: >-
        Assigns responsible managers to a specific CRM section (category),
        establishing ownership and routing rules. This is a foundational
        access-control operation — without it, incoming deals or contacts in a
        given section may go unassigned, causing missed follow-ups.
      x-ai-reasoning-instructions:
        - >-
          Verify that the sectionId exists before calling this endpoint —
          assigning to a non-existent section will silently fail or produce an
          error.
        - >-
          Confirm that all IDs in responsibleIds correspond to active manager
          accounts; deactivated users may cause inconsistent behavior.
        - >-
          Check whether the section already has assigned managers — this call
          may overwrite existing assignments depending on API semantics.
        - >-
          If the user provides only a section name, resolve it to a sectionId
          first using the appropriate list endpoint.
      x-ai-responding-instructions:
        - >-
          Confirm which section received the manager assignments and list the
          assigned manager IDs.
        - >-
          If the response returns the full ManagerSettings object, highlight the
          effective assignment (section → managers mapping).
        - >-
          Suggest verifying the assignment by fetching the section's current
          settings afterward.
      x-ai-suggestions:
        - >-
          Assign a single manager as the primary owner and add others as
          backups.
        - >-
          Use this after creating a new CRM section to ensure it is never left
          unmanaged.
        - >-
          Bulk-assign the same manager to multiple sections by calling this
          endpoint once per section.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will assign managers to the specified section, potentially
            replacing existing assignments.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - AccessControlChange
  /manager-settings/{settingId}:
    put:
      tags:
        - ManagerSettings
      summary: Update managers from category
      parameters:
        - name: settingId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                sectionId:
                  type: integer
                responsibleIds:
                  type: array
                  items:
                    type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    $ref: '#/components/schemas/ManagerSettings'
      operationId: updateManagerSetting
      x-ai-role: crm_operations_manager
      x-ai-description: >-
        Updates the assignment of responsible managers for a specific
        manager-settings configuration. This endpoint controls which team
        members are accountable for a given section within a category, directly
        affecting routing, visibility, and ownership of CRM entities. Changing
        responsible IDs can redistribute workloads and alter access patterns
        across the CRM.
      x-ai-reasoning-instructions:
        - >-
          Before updating, verify that the settingId exists to avoid a silent
          no-op or 404.
        - >-
          Confirm that all IDs in responsibleIds correspond to active managers
          in the account.
        - >-
          Check whether the sectionId belongs to the category referenced by
          settingId to prevent cross-category misassignment.
        - >-
          If responsibleIds is empty, clarify with the user whether they intend
          to remove all responsible managers — this may leave the section
          unowned.
      x-ai-responding-instructions:
        - >-
          Confirm the update by referencing the settingId and the new list of
          responsible managers.
        - >-
          If the response includes the updated ManagerSettings object, highlight
          the changed fields.
        - >-
          Suggest verifying the assignment by fetching the setting or reviewing
          the section in the CRM UI.
        - >-
          If the update affects a live category with active deals or contacts,
          warn the user about potential ownership reassignment.
      x-ai-suggestions:
        - >-
          Use GET /manager-settings to retrieve all settings and find the
          correct settingId before updating.
        - >-
          Pair with a manager list endpoint to resolve manager names from
          responsibleIds before presenting to the user.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          reason: >-
            Changing responsible managers affects routing and ownership of CRM
            records.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - ManagerSettings
      summary: Delete managers from category
      parameters:
        - name: settingId
          in: path
          required: true
          schema:
            type: integer
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                responsibleIds:
                  type: array
                  items:
                    type: integer
      responses:
        '204':
          description: Successfully deleted
      operationId: deleteManagersFromManagerSetting
      x-ai-role: crm_access_control_manager
      x-ai-description: >-
        Removes one or more responsible managers from a specific manager
        settings category. This operation adjusts accountability scope —
        unassigned managers will no longer receive tasks, notifications, or
        routing events tied to this category. Use with caution in active
        pipelines where unassignment may create orphaned leads.
      x-ai-reasoning-instructions:
        - >-
          Confirm that settingId refers to an existing category before
          proceeding.
        - >-
          Verify that responsibleIds are currently assigned to this setting —
          removing non-assigned managers may silently succeed but is a no-op.
        - >-
          If responsibleIds is omitted or empty, clarify with the user which
          managers should be removed to avoid unintended full unassignment.
        - >-
          Check if the setting requires at least one responsible manager —
          removing all may break routing or automation rules dependent on this
          category.
      x-ai-responding-instructions:
        - >-
          Confirm that the specified managers have been removed from the
          category (204 = success, no body).
        - Mention which manager IDs were unassigned and from which settingId.
        - >-
          Suggest reviewing remaining assigned managers to ensure the category
          is still properly staffed.
        - >-
          If the user likely wants to reassign rather than simply remove,
          suggest the update/assign operation as a follow-up.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will unassign the selected managers from the category. Leads or
            tasks routed through this category may be affected.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - IrreversibleWithoutReassignment
  /manager-settings/{sectionId}:
    get:
      tags:
        - ManagerSettings
      summary: Get managers by section
      parameters:
        - name: sectionId
          in: path
          required: true
          schema:
            type: integer
      responses:
        '200':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    items:
                      $ref: '#/components/schemas/ManagerSettings'
      operationId: getManagersBySection
      x-ai-role: crm_configuration_specialist
      x-ai-description: >-
        Retrieves the list of managers assigned to a specific CRM section.
        Sections act as organizational units (e.g., sales, support) that group
        managers for routing, permissions, and reporting purposes. Use this to
        inspect who is responsible for a given section before assigning leads or
        configuring automation rules.
      x-ai-reasoning-instructions:
        - >-
          Verify that the sectionId exists before making the call; an invalid ID
          will return an empty or error response.
        - >-
          Use this endpoint to audit manager assignments when debugging lead
          routing or access control issues.
        - >-
          If the result is empty, consider that the section may exist but have
          no managers assigned yet.
      x-ai-responding-instructions:
        - >-
          List the returned managers clearly, highlighting their names and roles
          if available in the schema.
        - >-
          If the list is empty, inform the user that no managers are currently
          assigned to this section and suggest using the appropriate assignment
          endpoint.
        - >-
          Mention the sectionId used in the request to provide clear context in
          the response.
      x-ai-suggestions:
        - >-
          Use the returned manager IDs to assign leads or configure notification
          rules for this section.
        - >-
          Cross-reference with section listing endpoints to enumerate all valid
          sectionId values.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
  /custom-tab:
    get:
      tags:
        - Custom Tab
      summary: Get all users custom tabs
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                type: object
                properties:
                  contact:
                    type: array
                    items:
                      $ref: '#/components/schemas/CustomTabWithAttribute'
                  pipeline:
                    type: array
                    items:
                      $ref: '#/components/schemas/CustomTabWithAttribute'
                  board:
                    type: array
                    items:
                      $ref: '#/components/schemas/CustomTabWithAttribute'
                  company:
                    type: array
                    items:
                      $ref: '#/components/schemas/CustomTabWithAttribute'
      operationId: getCustomTabs
      x-ai-role: crm_configuration_specialist
      x-ai-description: >-
        Retrieves all custom tab definitions configured for the current user
        account, organized by entity type. Custom tabs extend the default CRM
        interface by adding domain-specific views to contacts, pipelines,
        boards, and companies. This endpoint is the entry point for
        understanding what custom UI structure is active before rendering or
        modifying CRM entities.
      x-ai-reasoning-instructions:
        - >-
          Use this endpoint to discover available custom tabs before attempting
          to create or update tab configurations.
        - >-
          Check all four entity categories (contact, pipeline, board, company)
          even if only one is needed — the full structure prevents stale UI
          assumptions.
        - >-
          If the response arrays are empty, it means no custom tabs have been
          defined yet — suggest creating them rather than assuming a default
          layout.
      x-ai-responding-instructions:
        - >-
          Present the tabs grouped by entity type (contact, pipeline, board,
          company) for clarity.
        - >-
          Highlight the total count per entity to help the user understand the
          current configuration scope.
        - >-
          If any entity has no tabs, explicitly note it as unconfigured rather
          than omitting it from the response summary.
      x-ai-suggestions:
        - >-
          Use the returned tab IDs as references when creating or updating
          specific custom tab entries.
        - >-
          If tabs are missing for an entity, suggest using the corresponding
          POST endpoint to create them.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ReadOnly
    post:
      tags:
        - Custom Tab
      summary: Create custom tab
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                name:
                  type: string
                  description: Name of custom tab
                entityType:
                  type: integer
                  enum:
                    - 0
                    - 1
                    - 2
                    - 3
                  description: 0 - contact, 1 - pipeline, 2 - board, 3 - company
                entityId:
                  type: integer
                  description: Related entity ID. Only for pipelines and boards
      responses:
        '201':
          description: created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTab'
      operationId: createCustomTab
      x-ai-role: crm_configuration_specialist
      x-ai-description: >-
        Creates a custom tab that extends the UI and data model of a specific
        CRM entity (contact, pipeline, board, or company). Custom tabs allow
        teams to attach domain-specific views and structured data sections
        directly to core CRM objects, enabling tailored workflows without
        modifying the base schema.
      x-ai-reasoning-instructions:
        - >-
          Clarify the target entity type before proceeding: 0=contact,
          1=pipeline, 2=board, 3=company.
        - >-
          If entityType is 1 (pipeline) or 2 (board), require entityId — it is
          mandatory for those types.
        - >-
          For entityType 0 (contact) or 3 (company), entityId is typically not
          needed; warn the user if they provide it unexpectedly.
        - >-
          Check whether a tab with the same name already exists on the target
          entity to prevent duplicates.
        - >-
          Use a descriptive, purpose-reflecting name (e.g., 'Billing Info',
          'Deal Checklist') rather than generic labels.
      x-ai-responding-instructions:
        - >-
          Confirm creation by referencing the returned CustomTab ID and the
          entity it was attached to.
        - >-
          If entityType requires entityId and it was omitted, explain the
          constraint clearly.
        - >-
          Suggest adding fields or sections to the newly created tab as an
          immediate next step.
      x-ai-suggestions:
        - Billing Details
        - Onboarding Checklist
        - Technical Requirements
        - SLA Tracking
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
  /custom-tab/{customTabId}:
    put:
      tags:
        - Custom Tab
      summary: Update custom tabs
      parameters:
        - name: customTabId
          in: path
          required: true
          schema:
            type: number
          description: Custom tab ID
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                order:
                  type: integer
                  description: Custom tab order
                name:
                  type: string
                  description: Custom tab name
                isVisible:
                  type: boolean
                  description: Indicates whether the entity is visible to users
                entityType:
                  type: integer
                  enum:
                    - 0
                    - 1
                    - 2
                    - 3
                  description: 0 - contact, 1 - pipeline, 2 - board, 3 - company
                entityId:
                  type: integer
                  description: Related entity ID. Only for pipelines and boards
      responses:
        '200':
          description: Ok
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomTab'
      operationId: updateCustomTab
      x-ai-role: crm_interface_designer
      x-ai-description: >-
        Modifies the configuration of a custom tab in the CRM interface. Custom
        tabs extend the default UI by surfacing context-specific data (contacts,
        pipelines, boards, companies) directly within a record view. Updating a
        tab's visibility, order, or entity binding allows teams to tailor the
        workspace layout to their workflow without creating new tabs.
      x-ai-reasoning-instructions:
        - >-
          Retrieve the current tab configuration first to avoid overwriting
          fields that are not being changed.
        - >-
          If `entityType` is 0 (contact) or 3 (company), `entityId` is not
          applicable — do not include it in the payload.
        - >-
          If `entityType` is 1 (pipeline) or 2 (board), `entityId` is required —
          validate its presence before making the call.
        - >-
          Changing `isVisible` to false hides the tab from all users; confirm
          the intent if the action was not explicitly requested.
        - >-
          Check that `order` value does not conflict with other tabs' ordering
          to avoid unexpected reordering side effects.
      x-ai-responding-instructions:
        - >-
          Confirm which fields were updated and reflect the new values back to
          the user.
        - >-
          If `isVisible` was set to false, warn the user that the tab will no
          longer appear in the UI for any user.
        - >-
          Suggest verifying the updated tab by fetching the current tab list or
          reloading the relevant entity view.
      x-ai-suggestions:
        - 'Set `isVisible: false` to temporarily hide a tab without deleting it.'
        - >-
          Use `order` to reposition the tab relative to other custom tabs on the
          same entity.
        - >-
          To reassign a tab from one pipeline to another, update both
          `entityType` (1) and `entityId` together.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          reason: >-
            Setting isVisible to false affects all users; entity reassignment
            may cause data display inconsistencies.
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Custom Tab
      summary: Delete custom tabs
      parameters:
        - name: customTabId
          in: path
          required: true
          schema:
            type: number
          description: Custom tab ID
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                entityType:
                  type: integer
                  enum:
                    - 0
                    - 1
                    - 2
                    - 3
                  description: 0 - contact, 1 - pipeline, 2 - board, 3 - company
                entityId:
                  type: integer
                  description: Related entity ID. Only for pipelines and boards
      responses:
        '204':
          description: deleted
      operationId: deleteCustomTab
      x-ai-role: crm_configuration_specialist
      x-ai-description: >-
        Permanently removes a custom tab from a CRM entity view. Custom tabs are
        UI extensions that group custom fields — deleting one affects the
        display layer for all users with access to the related entity type
        (contact, pipeline, board, or company). This is a destructive,
        non-reversible action with potential UX impact across the team.
      x-ai-reasoning-instructions:
        - >-
          Confirm the customTabId is valid and belongs to the expected entity
          type before proceeding.
        - >-
          Warn the user that deletion is permanent and will affect the interface
          for all team members who use this entity type.
        - >-
          For pipelines (entityType=1) and boards (entityType=2), verify that
          entityId is provided — it is required for those contexts.
        - >-
          For contacts (entityType=0) and companies (entityType=3), entityId is
          not needed; clarify this if the user provides one unnecessarily.
        - >-
          If the tab contains active custom fields, inform the user that those
          fields may become inaccessible or lose their display context.
      x-ai-responding-instructions:
        - >-
          Confirm the deletion with reference to the customTabId that was
          removed.
        - >-
          Mention the affected entity type in the confirmation to avoid
          ambiguity.
        - >-
          If the response is 204 No Content, explicitly state that the operation
          was successful despite no body being returned.
        - >-
          Suggest reviewing remaining custom tabs via a list endpoint if the
          user needs to verify the current configuration.
      x-ai-suggestions:
        - >-
          Use this after confirming the tab is no longer needed across all team
          workflows.
        - >-
          Consider exporting or documenting existing custom field configurations
          before deletion.
        - >-
          Follow up with a list of remaining custom tabs to confirm the desired
          state.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            This action permanently deletes the custom tab and cannot be undone.
            Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceDestruction
            - IrreversibleAction
  /custom-tab/{customTabId}/relation:
    post:
      tags:
        - Custom Tab
      summary: Add new relation with attribute
      parameters:
        - name: customTabId
          in: path
          required: true
          schema:
            type: number
          description: Custom tab ID
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                entityType:
                  type: integer
                  enum:
                    - 0
                    - 1
                    - 2
                    - 3
                  description: 0 - contact, 1 - pipeline, 2 - board, 3 - company
                entityId:
                  type: integer
                  description: Related entity ID. Only for pipelines and boards
                entityIds:
                  type: array
                  items:
                    type: integer
                  description: Related attributes IDs.
      responses:
        '200':
          description: OK
      operationId: addCustomTabRelation
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Links a CRM entity (contact, pipeline, board, or company) to a specific
        custom tab, enabling contextual data grouping and cross-entity
        relationships. This is the binding operation that makes custom tab
        attributes visible and filterable in the context of a chosen entity
        type.
      x-ai-reasoning-instructions:
        - >-
          Determine the entityType before calling: 0=contact, 1=pipeline,
          2=board, 3=company.
        - >-
          For pipelines (1) and boards (2), provide a single entityId; for
          contacts and companies, use entityIds array.
        - >-
          Verify the customTabId exists before attempting to add a relation to
          avoid 404 errors.
        - >-
          Avoid duplicate relations — check existing relations for this tab and
          entity combination if idempotency is required.
      x-ai-responding-instructions:
        - Confirm which entity type and ID(s) were linked to the custom tab.
        - >-
          If the operation succeeds, suggest verifying the relation by
          retrieving the custom tab's relations.
        - >-
          If an error occurs, clarify whether the issue is with the customTabId,
          entityType mismatch, or invalid entityId(s).
      x-ai-suggestions:
        - >-
          Use entityType=0 with entityIds to bulk-link multiple contacts to the
          tab.
        - >-
          Use entityType=1 or entityType=2 with a single entityId for
          pipeline/board-scoped tabs.
        - >-
          After adding relations, retrieve the tab data to confirm the binding
          is reflected.
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
    delete:
      tags:
        - Custom Tab
      summary: Delete relation with attribute
      parameters:
        - name: customTabId
          in: path
          required: true
          schema:
            type: number
          description: Custom tab ID
      requestBody:
        content:
          application/json:
            schema:
              type: object
              properties:
                entityType:
                  type: integer
                  enum:
                    - 0
                    - 1
                    - 2
                    - 3
                  description: 0 - contact, 1 - pipeline, 2 - board, 3 - company
                entityId:
                  type: integer
                  description: Related entity ID. Only for pipelines and boards
                entityIds:
                  type: array
                  items:
                    type: integer
                  description: Related attributes IDs.
      responses:
        '200':
          description: OK
      operationId: deleteCustomTabRelation
      x-ai-role: crm_data_architect
      x-ai-description: >-
        Removes the association between a custom tab and one or more related
        entities (contacts, pipelines, boards, or companies). This operation
        detaches the tab's visibility or binding from the specified entity scope
        — it does not delete the tab itself or the entities, only the relational
        link between them.
      x-ai-reasoning-instructions:
        - >-
          Clarify entityType before proceeding: 0=contact, 1=pipeline, 2=board,
          3=company — wrong type silently targets the wrong scope.
        - >-
          entityId is applicable only for pipelines (1) and boards (2); for
          contacts (0) and companies (3) use entityIds only.
        - >-
          entityIds holds attribute IDs to unlink, not entity IDs — confirm the
          user understands the difference before executing.
        - >-
          Deletion of relations is irreversible; if the user is unsure, suggest
          listing current relations first.
        - >-
          If entityIds is empty or omitted, ask for clarification — the behavior
          with an empty array may be a no-op or remove all relations.
      x-ai-responding-instructions:
        - >-
          Confirm which relations were removed by echoing back the entityType
          label (e.g., 'pipeline') and the affected IDs.
        - >-
          Clarify that the custom tab and the entities themselves remain intact
          — only the link was deleted.
        - >-
          If the operation succeeds, suggest verifying the tab configuration or
          re-linking with a different set of attributes if needed.
      x-ai-suggestions:
        - >-
          Use entityType=1 with entityId to unlink a specific pipeline from this
          tab.
        - >-
          Use entityType=0 with entityIds to batch-remove contact attribute
          relations.
        - >-
          To inspect current relations before deleting, retrieve the custom tab
          details first.
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            This will permanently remove the specified relations from the custom
            tab. Proceed?
        security_info:
          data_handling:
            - RelationDelete
  /products:
    post:
      tags:
        - ECommerce Product
      summary: Create a new product
      requestBody:
        content:
          application/json:
            schema:
              properties:
                name:
                  type: string
                  description: Product name. Max length 255
                description:
                  type: string
                  description: Product description. Max length 10000
                shortDescription:
                  type: string
                  description: Product short description. Max length 10000
                images:
                  type: array
                  default:
                    - url1
                    - url2
                  description: Product images. Path from File manager service
                vendorCode:
                  type: string
                  description: Product vendor code. Max length 255
                type:
                  type: number
                  default: 1
                  description: >-
                    Product type . 1 - product, 2 - service, 3 - subscription
                    (expected soon)
                productType:
                  type: number
                  default: 1
                  enum:
                    - 1
                    - 2
                    - 3
                  description: Product type. 1 - physical, 2 - digital
                categoryId:
                  type: number
                  description: >-
                    Category ID. It can be obtained with the "Get users
                    categories" method
                balance:
                  type: object
                  properties:
                    type:
                      type: number
                      description: >-
                        Product balance type. 1 - piece, 2 - service, 3 - meter,
                        4 - set, 5 - liter, 6 - kilogram, 7 - package
                    value:
                      type: number
                      description: Product balance value. Max 11 digits
                    oldValue:
                      type: number
                      description: Product balance value. Max 11 digits
                  description: Product balance.
                availability:
                  type: number
                  enum:
                    - 1
                    - 2
                    - 3
                  description: >-
                    Product availability. 1 - available, 2 - unavailable, 3 -
                    expecting
                visible:
                  type: number
                  enum:
                    - 0
                    - 1
                  description: Product visibility. 0 - not visible, 1 - visible
                digitalInfo:
                  type: object
                  properties:
                    productLink:
                      type: string
                      description: >-
                        Product link. Max length 255. Path from File manager
                        service
                    productLinkPreview:
                      type: string
                      description: >-
                        Product link preview. Max length 255. Path from File
                        manager service
                    isProductLinkExternal:
                      type: boolean
                      description: >-
                        Flag which indicates whether the product link is
                        external.
                    isProductLinkPreviewExternal:
                      type: boolean
                      description: >-
                        Flag which indicates whether the product link preview is
                        external.
                  description: Product digital info.
                seo:
                  type: object
                  properties:
                    name:
                      type: string
                      description: Product name. Max length 255
                    description:
                      type: string
                      description: Product description. Max length 255
                    keys:
                      type: string
                      description: Product keys. Max length 255
                  description: Product SEO info.
                prices:
                  type: array
                  items:
                    properties:
                      currency:
                        type: string
                        description: Product currency. Max length 3. ISO CODE
                      value:
                        type: number
                        description: Product price. Between 0.01,999999999.99
                      oldValue:
                        type: number
                        description: Product old price. Between 0.01,999999999.99
                      isDefault:
                        type: boolean
                        description: >-
                          Flag which indicates whether the product price is
                          default.
                sections:
                  type: array
                  items:
                    properties:
                      name:
                        type: string
                        description: Product section name. Max length 255
                      status:
                        type: number
                        description: Product section status. 1 - active, 0 - inactive
                      values:
                        type: array
                        items:
                          properties:
                            key:
                              type: string
                              description: Product section key. Max length 255
                            value:
                              type: string
                              description: Product section value. Max length 2000
                            status:
                              type: number
                              description: >-
                                Product section value status. 1 - active, 0 -
                                inactive
                        description: Product section values.
                  description: Product sections.
      responses:
        '201':
          description: ''
          content:
            application/json:
              schema:
                properties:
                  data:
                    type: object
                    properties:
                      id:
                        type: integer
                      name:
                        type: string
                      description:
                        type: string
                      shortDescription:
                        type: string
                      images:
                        type: array
                        default:
                          - url1
                          - url2
                      vendorCode:
                        type: string
                      type:
                        type: number
                      categoryId:
                        type: number
                      balance:
                        type: object
                        properties:
                          type:
                            type: number
                          value:
                            type: number
                      availability:
                        type: number
                      visible:
                        type: number
                      userId:
                        type: number
                      productType:
                        type: number
                        default: 1
                        enum:
                          - 1
                          - 2
                      seo:
                        type: object
                        properties:
                          name:
                            type: string
                          description:
                            type: string
                          keys:
                            type: string
                      prices:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            currency:
                              type: string
                            value:
                              type: number
                            oldValue:
                              type: number
                            isDefault:
                              type: boolean
                            productId:
                              type: number
                      sections:
                        type: array
                        items:
                          properties:
                            id:
                              type: number
                            name:
                              type: string
                            productId:
                              type: number
                            status:
                              type: number
                            values:
                              type: array
                              items:
                                properties:
                                  id:
                                    type: number
                                  sectionId:
                                    type: number
                                  key:
                                    type: string
                                  value:
                                    type: string
                                  status:
                                    type: number
                      digitalInfo:
                        type: object
                        properties:
                          productLink:
                            type: string
                          productLinkPreview:
                            type: string
                          isProductLinkExternal:
                            type: boolean
                          isProductLinkPreviewExternal:
                            type: boolean
      operationId: createProduct
      x-ai-role: ecommerce_catalog_manager
      x-ai-description: >-
        Створює новий товар у каталозі SendPulse eCommerce. Товар є центральним
        об'єктом магазину — до нього прив'язуються ціни в різних валютах,
        залишки, SEO-метадані, цифрові файли та кастомні секції з
        характеристиками. Від правильного заповнення залежить видимість у
        вітрині, коректна обробка замовлень і якість пошукової індексації.
      x-ai-reasoning-instructions:
        - >-
          Перевір, чи вже існує товар із таким самим `vendorCode` або `name` в
          категорії, щоб уникнути дублювання.
        - >-
          Визнач `type` (1=product/2=service) та `productType`
          (1=physical/2=digital) до передачі запиту — від цього залежить
          необхідність заповнення `digitalInfo` та `balance`.
        - >-
          Якщо `productType=2` (digital), переконайся, що передано
          `digitalInfo.productLink`; поле `balance` для цифрових товарів
          зазвичай не актуальне.
        - >-
          Для `prices` завжди встановлюй одну ціну з `isDefault: true`; валюта
          має відповідати ISO 4217 (3 літери).
        - >-
          Якщо передаються `images` або `digitalInfo.productLink` — це шляхи до
          файлів із File Manager, а не зовнішні URL; для зовнішніх URL
          використовуй відповідні прапорці `isProductLinkExternal`.
        - >-
          Перед визначенням `categoryId` отримай список категорій через
          `getUsersCategories`, щоб передати валідний ідентифікатор.
        - >-
          Якщо товар ще не готовий до продажу, встанови `visible: 0` або
          `availability: 2` (unavailable), щоб не показувати його у вітрині
          передчасно.
      x-ai-responding-instructions:
        - Підтверди успішне створення, назвавши новий `data.id` товару.
        - Якщо передано ціни — перелічи їх у відповіді з валютою та значенням.
        - >-
          Нагадай про наступні логічні кроки: додати варіанти товару, пов'язати
          зі знижками або опублікувати (встановити `visible: 1`).
        - >-
          У разі помилки валідації (наприклад, відсутній `isDefault` у `prices`)
          — поясни конкретне поле та очікуване значення.
      x-ai-suggestions:
        - Premium Wireless Headphones
        - Digital Marketing Course — PDF + Video
        - Monthly SaaS Subscription Plan
      x-ai-capabilities:
        confirmation:
          type: None
        security_info:
          data_handling:
            - ResourceStateUpdate
            - FileReference
  /payments:
    post:
      tags:
        - Payments
      summary: Create  payment
      description: Create new manual payment.
      requestBody:
        content:
          application/json:
            schema:
              properties:
                dealId:
                  type: integer
                  description: Deal ID for which you need to create payment.
                contactId:
                  type: integer
                  description: Contact ID for which you need to create payment.
                description:
                  type: string
                price:
                  type: integer
                  description: Payment amount
                currency:
                  type: string
                  description: Payment currency
      responses:
        '201':
          description: created
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Payment'
      operationId: createPayment
      x-ai-role: crm_revenue_manager
      x-ai-description: >-
        Records a manual payment event against a CRM deal or contact. This is
        not an online payment gateway call — it registers an already-received or
        offline payment into the pipeline, updating deal financials and contact
        billing history. Critical for keeping revenue data accurate without
        going through an automated checkout flow.
      x-ai-reasoning-instructions:
        - >-
          Require either dealId or contactId — ideally both to anchor the
          payment in context; warn the user if neither is provided.
        - >-
          Validate that price is a positive integer and currency is a recognized
          ISO 4217 code before submitting.
        - >-
          If dealId is provided, consider fetching the deal first to confirm it
          is in an active stage before attaching a payment.
        - >-
          Avoid creating duplicate payments: check whether a payment with the
          same amount and description already exists on the deal.
      x-ai-responding-instructions:
        - >-
          Confirm success by surfacing the new Payment ID and its associated
          deal/contact.
        - >-
          Remind the user that this is a manual record — no actual money
          transfer is initiated.
        - >-
          If the deal stage implies the payment closes the deal, suggest
          updating the deal status accordingly.
      x-ai-suggestions:
        - 'Deposit for contract #2024-117'
        - Final invoice payment
        - Prepayment — Phase 1
      x-ai-capabilities:
        confirmation:
          type: Recommended
          message: >-
            You are about to record a manual payment of {price} {currency}
            against deal/contact. This will affect revenue reporting. Confirm?
        security_info:
          data_handling:
            - ResourceStateUpdate
            - FinancialDataWrite
  /payments/{paymentId}/approve:
    post:
      tags:
        - Payments
      summary: Approve manual payment.
      description: Set approval status for manually created payment
      parameters:
        - name: paymentId
          in: path
          required: true
          schema:
            type: number
          description: The unique identifier of the manually created payment to approve
      responses:
        '200':
          description: Payment successfully approved
      operationId: approvePayment
      x-ai-role: financial_operations_manager
      x-ai-description: >-
        Finalizes a manually created payment by setting its approval status.
        This is a critical financial workflow step — manual payments remain in a
        pending state until explicitly approved by an authorized actor. Approval
        triggers downstream processing (invoicing, access grants, status
        notifications).
      x-ai-reasoning-instructions:
        - >-
          Confirm the payment exists and is in a pending/unapproved state before
          attempting approval — approving an already-approved or non-existent
          payment will return an error.
        - >-
          Verify the caller has sufficient privileges to approve payments; this
          action is typically restricted to billing administrators.
        - >-
          Treat this as an irreversible financial action — once approved, the
          payment may trigger downstream effects (subscription activation,
          invoice generation) that cannot be undone via API.
      x-ai-responding-instructions:
        - Confirm the approval by stating the paymentId that was approved.
        - >-
          Inform the user of any downstream effects triggered by the approval
          (e.g., subscription activated, invoice issued).
        - >-
          If the operation fails, clarify whether the payment was already
          approved, does not exist, or the caller lacks permission.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            Approving a payment is a financial action with downstream effects.
            Confirm before proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - FinancialTransaction
  /payments/{paymentId}/cancel:
    post:
      tags:
        - Payments
      summary: Cancel manual payment
      description: Set payment status to canceled for manually created payment.
      parameters:
        - name: paymentId
          in: path
          required: true
          schema:
            type: number
          description: The unique identifier of the payment to cancel
      responses:
        '200':
          description: Payment successfully canceled
      operationId: cancelPayment
      x-ai-role: billing_operations_specialist
      x-ai-description: >-
        Terminates a manually created payment by transitioning its status to
        'canceled'. This is a financial state mutation — once canceled, the
        payment cannot be resumed or charged. Use when a customer requests
        cancellation, a billing error is detected, or a manual invoice needs to
        be voided before processing.
      x-ai-reasoning-instructions:
        - >-
          Confirm the payment exists and belongs to the current account before
          attempting cancellation.
        - >-
          Verify the payment was created manually — this endpoint is not
          applicable to automated or subscription-based payments.
        - >-
          Check the current payment status: only non-terminal statuses (e.g.,
          pending, created) can be canceled; already completed or failed
          payments may be rejected.
        - >-
          Treat this as an irreversible action — prompt the user to confirm
          intent if there is any ambiguity.
      x-ai-responding-instructions:
        - Confirm the cancellation by echoing the paymentId that was canceled.
        - >-
          Clarify that the action is irreversible and the payment can no longer
          be charged.
        - >-
          If cancellation fails due to status conflict, explain the current
          payment state and what terminal state prevents the action.
        - >-
          Suggest creating a new manual payment if the user needs to restart the
          billing process.
      x-ai-capabilities:
        confirmation:
          type: Required
          message: >-
            Canceling payment {paymentId} is irreversible. Confirm before
            proceeding.
        security_info:
          data_handling:
            - ResourceStateUpdate
            - IrreversibleAction
tags:
  - description: ''
    name: Pipelines
  - description: ''
    name: Pipeline Steps
  - description: ''
    name: Deals
  - description: ''
    name: Deal notes
  - description: ''
    name: Deal contacts
  - description: ''
    name: Deal history
  - description: ''
    name: Contacts
  - description: ''
    name: Contact phone number
  - description: ''
    name: Contact email addresses
  - description: ''
    name: Contacts messengers
  - description: ''
    name: Contact tags
  - description: ''
    name: Contact history
  - description: ''
    name: Users
  - description: ''
    name: Messengers types
  - description: ''
    name: Custom Tab
  - description: ''
    name: ManagerSettings
  - description: ''
    name: Payments
  - description: ''
    name: Telephony
