> ## Documentation Index
> Fetch the complete documentation index at: https://docs.enneo.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Get a list of tickets

> Get a list of tickets in compact format for performance.

⚠️ IMPORTANT: This endpoint returns a COMPACT version of tickets. The following fields are EXCLUDED from the response:
- body, bodyPlain, bodyClean
- attachments
- template
- workitem

Also note:
- customer: Only includes {tagIds: [], tags: []} structure, NOT the full customer object
- `ticketScope=skills` activates routing context: spam tickets (`spamStatus` in `auto_spam`, `auto_programmatic`, `manual_spam`) are excluded automatically. Backlog spam filter (both whitelist `in`): spam → those statuses; not spam → `null`, `auto_clean`, `manual_clean`.

To get the full ticket data including these fields, use GET /ticket/{id}.



## OpenAPI

````yaml https://dev.enneo.dev/api/mind/docs/open-api post /ticket/search
openapi: 3.0.0
info:
  version: '1'
  title: enneo.MIND API
  description: This describes the API of enneo Mind, the main ticketing backend
  contact:
    name: enneo GmbH
    email: richard@enneo.ai
  license:
    name: Proprietary software
    url: https://enneo.ai
servers:
  - url: https://demo.enneo.ai/api/mind
    description: Production server, demo client
  - url: https://main.enneo.dev/api/mind
    description: Development main branch
  - url: http://localhost:8005/api/mind
    description: Local development server
security:
  - bearerAuth:
      - api
  - cookieAuth:
      - api
paths:
  /ticket/search:
    post:
      tags:
        - Ticket
      summary: Get a list of tickets
      description: >-
        Get a list of tickets in compact format for performance.


        ⚠️ IMPORTANT: This endpoint returns a COMPACT version of tickets. The
        following fields are EXCLUDED from the response:

        - body, bodyPlain, bodyClean

        - attachments

        - template

        - workitem


        Also note:

        - customer: Only includes {tagIds: [], tags: []} structure, NOT the full
        customer object

        - `ticketScope=skills` activates routing context: spam tickets
        (`spamStatus` in `auto_spam`, `auto_programmatic`, `manual_spam`) are
        excluded automatically. Backlog spam filter (both whitelist `in`): spam
        → those statuses; not spam → `null`, `auto_clean`, `manual_clean`.


        To get the full ticket data including these fields, use GET
        /ticket/{id}.
      operationId: getTickets
      requestBody:
        description: Search parameters for tickets
        required: false
        content:
          application/json:
            schema:
              type: object
              properties:
                limit:
                  type: integer
                  description: The number of items to return
                  default: 100
                  minimum: 1
                  maximum: 500
                  example: 100
                offset:
                  type: integer
                  description: The number of items to skip
                  default: 0
                  minimum: 0
                  example: 0
                orderByField:
                  type: string
                  description: |
                    The field to order by
                    t = ticket
                    i = intent
                    tt = ticket_tag
                  enum:
                    - t.id
                    - t.channel
                    - t.subchannelId
                    - t.channelId
                    - t.direction
                    - t.status
                    - t.priority
                    - t.agentId
                    - t.customerId
                    - t.contractId
                    - t.partnerId
                    - t.isCustomerActive
                    - t.aiSupportLevel
                    - i.aiAgentId
                    - t.createdAt
                    - t.modifiedAt
                    - t.firstResponseDueBy
                    - t.dueBy
                    - t.lastMessageAt
                    - t.lastCustomerMessageAt
                    - tt.tagId
                    - t.sentiment
                    - t.language
                    - t.languageCode
                    - t.from
                  default: t.id
                  example: t.id
                orderByDirection:
                  type: string
                  description: The direction to order by
                  enum:
                    - asc
                    - desc
                  default: desc
                  example: asc
                ticketScope:
                  type: string
                  description: >
                    Restrict the list to tickets matching the agent's configured
                    skill tags.

                    - all (default): no skill-based restriction — standard
                    backlog search

                    - skills: routing-scoped view; activates assignee-bypass so
                    a restricted agent
                      still sees tickets assigned to them even when they carry routing-excluded tags.
                      Also activates NRR-tag stripping (non-routing-relevant tags are ignored for
                      skill-match purposes). Matches the behaviour of Report dashboard `ticketScope=skills`.
                  enum:
                    - all
                    - skills
                  default: all
                  example: all
                filters:
                  type: array
                  description: An array of objects containing filters
                  items:
                    $ref: '#/components/schemas/Filter'
      responses:
        '200':
          description: Successful operation
          content:
            application/json:
              schema:
                type: object
                properties:
                  tickets:
                    type: array
                    items:
                      $ref: '#/components/schemas/Ticket'
                  total:
                    type: integer
                    description: Total number of tickets that match the filter
                    example: 21
                  offset:
                    type: integer
                    description: Offset used
                    example: 0
                  limit:
                    type: integer
                    description: Limit used
                    example: 100
        '403':
          description: Unauthorized
        '404':
          description: Ticket not found
        '500':
          description: Internal error
components:
  schemas:
    Filter:
      type: object
      properties:
        key:
          type: string
          enum:
            - t.id
            - t.channel
            - t.subchannelId
            - t.channelId
            - t.direction
            - t.status
            - t.priority
            - t.agentId
            - t.customerId
            - t.contractId
            - t.partnerId
            - t.isCustomerActive
            - t.aiSupportLevel
            - i.aiAgentId
            - t.createdAt
            - t.modifiedAt
            - t.firstResponseDueBy
            - t.dueBy
            - t.lastMessageAt
            - t.lastCustomerMessageAt
            - tt.tagId
            - t.sentiment
            - t.language
            - t.languageCode
            - t.modelRunAt
            - t.externalTicketId
            - t.from
            - t.spamStatus
            - w.id
            - q
          example: channel
        comparator:
          type: string
          description: >-
            Possible values: =, !=, >, >=, <, <=, in, not in, between, not
            between
          example: in
        values:
          type: array
          description: >-
            Used for "in" and "not in" comparators.


            Include the sentinel string `null` to match SQL NULL rows together
            with other values:

            - `in` + `["null", "a"]` → `(col IS NULL OR col IN ('a'))`
            (whitelist)

            - `not in` + `["null", "a"]` → `(col IS NULL OR col NOT IN ('a'))`
            (blacklist complement)

            - `["null"]` only → `col IS NULL` (`in`) or `col IS NOT NULL` (`not
            in`)


            Example: backlog not-spam filter uses `in` with `["null",
            "auto_clean", "manual_clean"]`; spam filter uses `in` with spam
            statuses only.
          items:
            type: string
            example: email
        value:
          type: string
          description: Used for "=", "!=", ">", ">=", "<", "<=" comparators
          example: 1609459200
        from:
          type: string
          description: Used for "between" and "not between" comparators
          example: 1609459200
        to:
          type: string
          description: Used for "between" and "not between" comparators
          example: 1612051200
    Ticket:
      type: object
      description: >-
        A ticket, e.g. an email conversation, call or chat conversation.


        ⚠️ Response format varies by endpoint:

        - POST /ticket/search: Returns compact format (excludes: body,
        bodyPlain, bodyClean, attachments, template, workitem)

        - GET /ticket/{id}: Returns full ticket data with all fields
      properties:
        id:
          type: integer
          example: 376189
        direction:
          type: string
          description: Direction of the ticket
          enum:
            - in
            - out
            - internal
          example: in
        from:
          oneOf:
            - type: string
              format: email
              description: >-
                Sender of email. Used when channel is not call. Null is
                channel=system
              nullable: true
              example: tom@gmail.com
            - type: integer
              example: 491721041689
              description: Requester's telephone number address, used when channel is call
            - type: integer
              format: ipv4
              example: 12.23.45.67
              description: >-
                Requester's IP address, used when channel is chat AND the user
                did not provide an email to the chat bot yet
        fromName:
          type: string
          description: >-
            Provided when customer's request included a Name, e.g. 'Tom
            Mustermann <tom@mm.com>' for an email or during the chat bot
            initialization. Null when not set
          nullable: true
          example: Tom Mustermann
        to:
          description: >-
            Recipent of request. Can be an array of email addresses, but also a
            phone number or chat group name depending on channel
          oneOf:
            - type: array
              items:
                type: string
                format: email
                example: service@energy.com
                description: E-Mail address, used when channel is email,portal,chat
            - type: integer
              example: 49303000001
              description: >-
                Client's customer service center telephone number address, used
                when channel is call
        ccEmails:
          type: array
          deprecated: true
          description: >-
            ⚠️ DEPRECATED: Use replyRecipients.cc instead. Any emails in CC.
            Used when channel=email, otherwise empty array
          items:
            type: string
            format: email
            example: secondlevel@enneo.ai
        bccEmails:
          type: array
          deprecated: true
          description: >-
            ⚠️ DEPRECATED: Use replyRecipients.bcc instead. Any emails in BCC.
            Used when channel=email, otherwise empty array
          items:
            type: string
            format: email
            example: archive@enneo.ai
        replyCcEmails:
          type: array
          deprecated: true
          description: >-
            ⚠️ DEPRECATED: Use replyRecipients.cc instead. Any emails in CC for
            a reply. Used when channel=email, otherwise empty array
          items:
            type: string
            format: email
        replyRecipients:
          $ref: '#/components/schemas/ReplyRecipients'
        subchannelId:
          type: integer
          description: ID of the subchannel
          nullable: true
        externalTicketId:
          type: string
          description: >-
            Unique identifier from an external ticketing system.


            Can be provided when creating a ticket via POST /ticket to prevent
            duplicates. If a ticket with this externalTicketId already exists,
            it will be updated instead of creating a new one.
          nullable: true
          example: EXT-12345
        sentiment:
          type: string
          description: AI-detected sentiment
          nullable: true
          example: positive
        language:
          type: string
          description: Detected language name
          nullable: true
          example: English
        languageCode:
          type: string
          description: Detected language code
          nullable: true
          example: en
        autoExecuteAt:
          type: string
          format: date-time
          description: When the ticket should be auto-executed
          nullable: true
        aiSupportLevel:
          type: string
          enum:
            - unprocessed
            - human
            - bot
            - automated
          description: Level of AI support for this ticket
        spamStatus:
          type: string
          enum:
            - auto_spam
            - auto_clean
            - auto_programmatic
            - manual_spam
            - manual_clean
          description: >-
            Spam classification status of the ticket. Primary marker for routing
            and backlog spam filters.


            - `auto_spam` / `auto_clean` / `auto_programmatic`: Set
            automatically (headers, Cortex). `auto_programmatic` = header rule
            marked programmatic.

            - `manual_spam` / `manual_clean`: Set manually via API. Manual
            statuses are not overwritten by automatic detection.


            Spam statuses (`auto_spam`, `auto_programmatic`, `manual_spam`)
            exclude tickets from routing (`ticketScope=skills`).

            Backlog filter: `t.spamStatus` with `in` / `not in` and spam status
            values (`not in` includes NULL as not-spam).


            Tickets marked as spam are skipped during automatic AI processing. A
            configured `spamDetectionTagIds` tag also marks spam at runtime
            (`Ticket::isSpam()`), but SQL filters use this column only.
          nullable: true
          example: auto_clean
        isCustomerActive:
          type: boolean
          description: Whether the customer is currently active
        interface:
          type: string
          enum:
            - internal
          description: Name of the ticketing system interface
          example: internal
        priority:
          $ref: '#/components/schemas/Priority'
        channel:
          $ref: '#/components/schemas/Channel'
        channelId:
          type: string
          description: Unique ID of chat conversation. Used when channel=chat
          example: 32291c7e-1cce-4d4c-8269-15e6a6501466
          nullable: true
        status:
          $ref: '#/components/schemas/Status'
        summary:
          type: string
          description: Summary of request
          example: I want to relocate and send you a meter reading
        subject:
          type: string
          description: Subject of email
          example: I want to relocate and send you a meter reading
        bodyPlain:
          type: string
          description: >-
            Body of request in plain text form (no HTML).


            ⚠️ Only included in GET /ticket/{id}, NOT in POST /ticket/search
            responses.

            May be null if ticket has no body content.
          nullable: true
          example: >-
            Sehr geehrter Kundenservice,


            könnten Sie bitte den beiliegenden Zählerstand meines Zählers in Ihr
            System eintragen und mir eine Zwischenrechnung zukommen lassen?
            Außerdem würde ich gerne zu meiner neuen Adresse Hugo-Junkers-Str. 5
            in 82031 Grünwald wechseln. Ich ziehe nächsten Donnerstag ein.
            Können Sie meinen alten Vertrag zum 1. November für mich kündigen?


            Ich danke Ihnen, Tom
        body:
          type: string
          description: >-
            Body of request in originial form (incl. HTML).


            ⚠️ Only included in GET /ticket/{id}, NOT in POST /ticket/search
            responses.

            May be null if ticket has no body content.
          nullable: true
          example: >-
            <p>Sehr geehrter Kundenservice,</p><p>k&#246;nnten Sie bitte den
            beiliegenden Z&#228;hlerstand meines Z&#228;hlers in Ihr System
            eintragen und mir eine Zwischenrechnung zukommen lassen?
            Au&#223;erdem w&#252;rde ich gerne zu meiner neuen Adresse
            Hugo-Junkers-Str. 5 in 82031 Gr&#252;nwald wechseln. Ich ziehe
            n&#228;chsten Donnerstag ein. K&#246;nnen Sie meinen alten Vertrag
            zum 1. November f&#252;r mich k&#252;ndigen?</p><p>Ich danke Ihnen,
            Tom</p>
        bodyClean:
          type: string
          description: >-
            Version of body without any footers, signatures or other
            non-relevant content. Used as input for AI models.


            ⚠️ Only included in GET /ticket/{id}, NOT in POST /ticket/search
            responses.

            May be null if ticket has no body content.
          nullable: true
          example: >-
            Sehr geehrter Kundenservice, könnten Sie bitte den beiliegenden
            Zählerstand meines Zählers in Ihr System eintragen und mir eine
            Zwischenrechnung zukommen lassen?
        isEscalated:
          type: boolean
          example: false
        createdAt:
          type: string
          format: DateTime
          example: '2022-12-13 22:18:06'
        modifiedAt:
          type: string
          format: DateTime
          nullable: true
          description: Last change of this ticket
          example: null
        firstResponseDueBy:
          type: string
          format: DateTime
          nullable: true
          description: >-
            Latest date by when this ticket should be responded to, but not
            necessarily solved
          example: '2022-12-14 22:18:06'
        dueBy:
          type: string
          format: DateTime
          nullable: true
          description: Latest date by when this ticket should be resolved
          example: '2022-12-15 22:18:06'
        closedAt:
          type: string
          format: DateTime
          nullable: true
          description: Date when this ticket was closed/resolved
          example: null
        customer:
          description: |-
            Customer information associated with this ticket.

            ⚠️ Format varies by endpoint:
            - POST /ticket/search: Compact format with limited properties
            - GET /ticket/{id}: Full Customer object with all properties
          allOf:
            - $ref: '#/components/schemas/Customer'
          additionalProperties: true
        customerId:
          type: string
          example: '123'
          description: >-
            Associated primary customer id of that ticket. Null if not detected
            by AI or not set by user
          nullable: true
        contractId:
          type: string
          example: '746839'
          description: >-
            Associated primary contract id of that ticket. Null if not detected
            by AI or not set by user
          nullable: true
        partnerId:
          type: integer
          example: 123
          description: >-
            Associated partner id of that ticket. Null if not detected by AI or
            not set by user
          nullable: true
        customerLegitimation:
          type: integer
          description: >
            Customer legitimation score:

            - 0 = No customer identified or no contract associated

            - 10 = Default confidence for email/portal/chat channels when no
            other criteria match

            - 12 = Email not found in ERP system

            - 13 = Matching contract/customer ID and lastname found in message

            - 15 = Matching contract and customer ID found in message

            - 20 = High confidence cases:
              * System channel or outgoing/internal messages
              * Sender email matches contract/customer email
              * For letters: address matches customer/contract address
            - 30 = Manually confirmed by agent or AI during chat

            - 40+ = Custom level that will be set by agent/chatbot for more
            strict customer verification
          example: 30
        customerLegitimationMessage:
          type: string
          description: >-
            Human-readable message explaining the customer legitimation status.
            Only provided when customerLegitimation is between 10 and 19.
          nullable: true
          example: Customer could not be confirmed
        responderId:
          type: integer
          description: User ID of agent that authored the latest response to this ticket.
          nullable: true
          example: null
        agentId:
          type: integer
          description: Agent ID associated to this ticket (if any).
          nullable: true
          example: null
        agent:
          $ref: '#/components/schemas/AuthProfile'
          description: >-
            Agent profile associated to this ticket. Null if no agent is
            assigned.
        assignedAgentIds:
          type: array
          description: Array of agent IDs that are assigned to this ticket
          items:
            type: integer
            description: Agent ID
            example: 123
        assignedAgents:
          type: array
          description: Array of agents that are assigned to this ticket
          items:
            $ref: '#/components/schemas/AuthProfile'
        workedOnByIds:
          type: array
          description: Array of agent IDs that worked on this ticket in last hour
          items:
            type: integer
            description: Agent ID
            example: 123
        workedOnBy:
          type: array
          description: Array of agent IDs that worked on this ticket in last hour
          items:
            $ref: '#/components/schemas/AuthProfile'
        attachments:
          type: array
          description: >-
            Attachments associated with this ticket (filtered: non-inline
            attachments or PDFs only).


            ⚠️ Only included in GET /ticket/{id}, NOT in POST /ticket/search
            responses.
          items:
            $ref: '#/components/schemas/Attachment'
        additionalData:
          type: object
          description: Client-specific data objects can be included here
          additionalProperties: true
          nullable: true
          example: null
        template:
          type: string
          description: >-
            Generic email template with placeholders like "Hello
            {{customer.firstname}}, %MESSAGE%, Best regards
            {{agent.firstName}}".


            ⚠️ Only included in GET /ticket/{id}, NOT in POST /ticket/search
            responses.

            May be null if no template is configured for this subchannel.
          nullable: true
          example: >-
            <p>Hallo {{customer.firstname}},</p><p>%MESSAGE%</p><p>Viele
            Grüße,<br>{{agent.firstName}}</p>
        tags:
          type: array
          description: Tags loaded from intents
          items:
            $ref: '#/components/schemas/Tag'
        tagIds:
          type: array
          description: >-
            List of tag IDs. When updating, replaces all existing tags. Cannot
            be used together with addTagIds/removeTagIds
          items:
            type: integer
          example:
            - 62
            - 61
        addTagIds:
          type: array
          description: >-
            List of tag IDs to add to existing tags (for bulk update). Cannot be
            used together with tagIds
          writeOnly: true
          items:
            type: integer
          example:
            - 62
        removeTagIds:
          type: array
          description: >-
            List of tag IDs to remove from existing tags (for bulk update).
            Cannot be used together with tagIds
          writeOnly: true
          items:
            type: integer
          example:
            - 61
        refresh:
          type: boolean
          deprecated: true
          description: >-
            Deprecated. Use `refreshMode=full` instead. Special flag for bulk
            update — if true, skips saving the ticket to database and webhooks
            execution, and schedules a full AI re-run.
          writeOnly: true
          example: true
        refreshTags:
          type: boolean
          deprecated: true
          description: >-
            Deprecated. Use `refreshMode=tags` instead. Special flag for bulk
            update — if true, only AI tag detection will be performed (faster
            than full processing). Skips saving to database and webhooks
            execution.
          writeOnly: true
          example: true
        refreshMode:
          type: string
          enum:
            - full
            - summaryAndText
            - customer
            - tags
            - tagsRuleBased
            - agents
          description: >
            Special flag for bulk update. Schedules a selective AI re-run and
            skips saving the ticket to database and webhooks execution.

            - `full` — re-run all AI checks (equivalent to the legacy `refresh`
            flag).

            - `summaryAndText` — re-run summary, body extraction, sentiment.

            - `customer` — re-detect customer; if a new customer is detected, AI
            agents re-run too.

            - `tags` — clear manual tags (auto-assigned tags are preserved) and
            re-detect via AI (equivalent to the legacy `refreshTags` flag).

            - `tagsRuleBased` — like `tags` but rule-based only
            (channel/subchannel/condition tags); no LLM or embedding calls.

            - `agents` — re-run AI agents only.
          writeOnly: true
          example: tags
        agentSkillsMatch:
          type: boolean
          description: If false, the agent doesn't have the skills to handle the ticket
          example: true
        intents:
          type: array
          description: >-
            AI-detected intents for this ticket.


            ⚠️ Format varies by endpoint:

            - POST /ticket/search: Only {id, aiAgentId, name, confidenceColor,
            infos} properties are included

            - GET /ticket/{id}: Full Intent objects with all properties
          items:
            $ref: '#/components/schemas/Intent'
        rawData:
          type: object
          description: >-
            Raw source data from the originating system in its proprietary
            format.


            Only included if explicitly requested via includeRawData=true query
            parameter.
          nullable: true
          additionalProperties: true
          example: null
        workitem:
          type: object
          description: >-
            Additional metadata for system-generated tickets (channel=system).
            Used internally for automated processes.


            ⚠️ Only included in GET /ticket/{id} AND only when channel=system.
            Returns null for all other tickets.
          nullable: true
          additionalProperties: true
    ReplyRecipients:
      type: object
      nullable: true
      description: >-
        Recommended recipients for replying to this ticket. Calculated based on
        channel, direction, latest conversation, and ERP data.

        Returns null for system tickets (cannot be replied to).
      properties:
        to:
          type: array
          description: >-
            Primary recipients (email addresses or postal addresses depending on
            channel)
          items:
            type: string
          example:
            - customer@example.com
        cc:
          type: array
          description: CC recipients (email addresses only)
          items:
            type: string
          example:
            - cc@example.com
        bcc:
          type: array
          description: BCC recipients (email addresses only)
          items:
            type: string
          example: []
      example:
        to:
          - customer@example.com
        cc:
          - manager@example.com
        bcc: []
    Priority:
      type: string
      description: Priority of ticket
      enum:
        - low
        - medium
        - high
        - urgent
      example: low
    Channel:
      type: string
      description: Channel of ticket
      enum:
        - email
        - portal
        - phone
        - letter
        - system
        - chat
        - walkIn
      example: email
    Status:
      type: string
      description: Status of ticket
      enum:
        - open
        - pending
        - closed
      example: open
    Customer:
      type: object
      properties:
        id:
          type: integer
          example: 83771
        emailMatches:
          type: boolean
          example: true
          description: >-
            If false, the customer sent the email from an account that doesn't
            match our records. Always returns 'null' when customer is retrieved
            by customerId and not by ticketId
          nullable: true
        business:
          type: boolean
          example: false
        company:
          type: string
          description: >-
            Name of the company. Null when customer is not a business but
            private
          nullable: true
          example: null
        firstname:
          type: string
          example: Tom
        lastname:
          type: string
          example: Mustermann
        address:
          type: string
          example: Hugo-Junkers-Str. 5
        phone:
          type: string
          example: 49123456789
        email:
          type: string
          example: tom@mustermann.de
          format: email
        tags:
          type: array
          items:
            type: object
            properties:
              id:
                type: integer
                example: 2
              color:
                type: string
                enum:
                  - green
                  - yellow
                  - red
                  - blue
                  - grey
                example: green
              name:
                type: string
                example: VIP
        contracts:
          type: array
          description: Contracts that this customer has
          items:
            $ref: '#/components/schemas/Contract'
        additionalData:
          type: object
          description: Client-specific data objects can be included here
          additionalProperties: true
      nullable: true
    AuthProfile:
      type: object
      properties:
        id:
          type: integer
          description: User ID
          example: 1
        firstName:
          type: string
          description: First name
          example: Max
        lastName:
          type: string
          description: Last name
          example: Mustermann
        email:
          type: string
          description: Email address (read only)
          example: demo@enneo.dev
        phone:
          type: string
          description: Phone number
          example: +49 123 456789
        image:
          type: string
          format: base64
          description: Image
          writeOnly: true
          example: >-
            iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNk+A8AAQUBAScY42YAAAAASUVORK5CYII=
        password:
          type: string
          description: Password
          writeOnly: true
          example: 123456
        lastSeen:
          type: string
          format: DateTime
          description: The last time the user was seen (read only)
          example: '2022-08-12 12:21:21'
        type:
          type: string
          description: The type of the user
          example: enneo
        isSsoOnly:
          type: integer
          description: >-
            If 1, the user can only login via SSO. If 0, the user can login with
            password or SSO
          enum:
            - 0
            - 1
          example: 0
        lang:
          type: string
          description: The language of the user
          example: de
        nameAlias:
          type: string
          description: Alternative display name or alias for the user
          example: Johnny
        externalId:
          type: string
          description: >-
            External identifier such as employee number or ID from external
            system
          example: EMP-12345
    Attachment:
      type: object
      properties:
        id:
          type: integer
          description: id of attachment
          example: 103013960646
        url:
          type: string
          format: uri
          example: >-
            https://client.enneo.ai/attachments/reading_w23po_107647890574i49994_(1).pdf
        name:
          type: string
          example: reading_w23po_107647890574i49994_(1).pdf
        size:
          type: integer
          description: size of attachment in bytes.
          example: 721592
        width:
          type: integer
          description: >-
            width of image attachment in pixels. Can be ommitted for non-image
            attachments.
          example: 3120
        height:
          type: integer
          description: >-
            height of image attachment in pixels. Can be ommitted for non-image
            attachments.
          example: 4160
        inline:
          type: boolean
          description: true if attachment is an inline image
          example: false
        fileEnding:
          type: string
          description: file ending of attachment
          example: pdf
        contentType:
          type: string
          description: content type of attachment
          example: application/pdf
        originalUrl:
          type: string
          format: uri
          description: >-
            url of original attachment, most likely contains invalid temporary
            access token
          example: >-
            https://storage.example.com/attachments/reading_w23po_107647890574i49994_(1).pdf
        extractedData:
          type: object
          description: >-
            data extracted from the attachment, e.g. a PDF text or a meter
            reading
        extractionStatus:
          type: string
          description: >-
            Status of the current extraction. Valid options: "notStarted",
            "inProgress", "success", "error"
          example: notStarted
        extractionData:
          type: object
          description: Data extracted from the attachment by meterReadingMicroservice
          example:
            confidence: 1
            meterValue: 1234
      example:
        id: 103013960646,
        url: >-
          https://storage.googleapis.com/enneo-attachments-public/a1/103013960646-4b1aa775/IMG_20230301_192712.jpg
        name: IMG_20230301_192712.jpg
        size: 2292952
        width: 3120
        height: 4160
        inline: false
        fileEnding: jpg
        contentType: image/jpeg
        originalUrl: https://storage.example.com/attachments/IMG_20230301_192712.jpg
        extractedData: null
        extractionStatus: success
        extractionData:
          confidence: 0.815
          meterValue: 87870.5
    Tag:
      type: object
      description: Tag object
      properties:
        id:
          type: integer
          description: Internal id, e.g. 123
          nullable: true
          example: 123
        name:
          type: string
          description: e.g. "Complaint"
          example: Complaint
        fullName:
          type: string
          description: The full name when not shown in a tree
          example: 'Second Level: Complaint'
        parent:
          type: integer
          description: >-
            The id of the parent tag. null if on root level. Can be created to
            create the tree structure of tags
          nullable: true
          example: 6
        reference:
          type: string
          description: To what this tag can be assigned to
          enum:
            - ticket
            - contract
            - customer
          example: ticket
        type:
          type: string
          description: Type of the tag
          enum:
            - skill
            - product
            - brand
            - customerProperty
            - contractProperty
            - other
          example: skill
        visibility:
          type: string
          description: Visibility of the tag
          enum:
            - public
            - private
            - disabled
          default: public
          example: public
        color:
          type: string
          description: Color of the tag. Default is grey
          enum:
            - grey
            - green
            - red
            - blue
            - yellow
            - purple
            - orange
            - teal
          example: grey
          default: grey
        properties:
          type: array
          description: >-
            An array of strings that specify special properties. Currently only
            ['defaultSkill'], if this tag should be assigned if no skill was
            found
          items:
            type: string
            enum:
              - defaultSkill
          example: []
        complexity:
          type: string
          description: The complexity of the tag
          example: moderate
        sla:
          type: number
          format: float
          description: >-
            SLA in business hours. So if we have business hours from 9-17h, an 8
            hour SLA means ticket has to be solved within one day. NULL means no
            SLA is assigned.
          nullable: true
          example: 8
        priority:
          type: string
          description: >-
            If set to anything other than do-not-change, then the ticket
            priority will be set to this value if the tag was assigned (either
            manually or via AI)
          enum:
            - do-not-change
            - low
            - medium
            - high
          example: do-not-change
        channels:
          type: array
          description: >-
            Channels for which this tag can be detected. If empty or null, then
            this tag can be assigned to all channels.
          nullable: true
          items:
            type: string
          example:
            - email
            - chat
        subchannels:
          type: array
          description: >-
            Subchannels (=Mailboxes/Chat channels) for which this tag can be
            detected. If empty or null, then this tag can be assigned to all
            subchannels.
          nullable: true
          items:
            type: number
            format: int
          example:
            - 2
            - 4
        routingRelevance:
          type: boolean
          description: >-
            If false, this tag is ignored in routing skill-matching filters.
            Tags used only for reporting or classification should set this to
            false so they don't block ticket routing.
          default: true
          example: true
        detectionDetails:
          type: object
          description: Details how the AI agent is detected
        assignment:
          type: array
          description: >-
            Specifies how this tag is being assigned. The details in the
            assignment are specified in the settings page of the tag. So for
            example 'assignBySubchannel', 'assignByCustomLogic' means this tag
            is auto-assigned for certain subchannels, and using a custom logic
            defined in an executor.
          deprecated: true
          items:
            type: string
            enum:
              - assignByChannel
              - assignBySubchannel
              - assignByTicketProperty
              - assignByContractProperty
              - assignByCustomerProperty
              - assignByCustomLogic
              - assignByAI
          example:
            - assignBySubchannel
            - assignByCustomLogic
        testCase:
          type: object
          description: Test case for the tag
        modifiedBy:
          type: string
          description: The user that last modified the tag
          example: John Doe
        modifiedAt:
          type: string
          format: DateTime
          description: The date and time when the tag was last modified
          example: '2024-08-29 14:38:12'
    Intent:
      type: object
      description: An intent of a customer that he wants to be resolved by contacting us
      properties:
        id:
          type: integer
          description: Internal ID of intent
          example: 1211221
        code:
          type: string
          nullable: true
          description: >-
            Intent model code that resolves a specific issue. Currently
            supported is process_meter_reading, process_bank_data and
            process_installment_change
          example: process_meter_reading
        name:
          type: string
          description: User-readable name of intent as defined by client
          example: Process a meter reading
        contractId:
          type: string
          example: '746839'
        status:
          type: string
          description: >
            Lifecycle status of the intent. `preview` — created as a
            non-persisted preview. `ready` — active, waiting for agent action.
            `executed` — action taken, but dialogue may continue (interaction
            with remaining options). `archived` — terminal: action taken and
            dialogue is closed (text reply sent, or interaction with no
            remaining options). Preserved as audit history. `invalidated` —
            underlying data changed, will be re-processed on next load.
            `deleted` — soft-deleted.
          enum:
            - preview
            - ready
            - executed
            - archived
            - invalidated
            - deleted
          example: ready
        confidence:
          type: number
          format: float
          description: >-
            Confidence how certain the AI is that this is correct. 0.95 means
            for example 95% certain. Defaults to 100% when verified by human.
          example: 0.95
        confidenceColor:
          type: string
          example: warning
          description: >-
            A color indication of an intent showing the user how much user
            interaction is needed. 'success' indicates the AI is ready to
            execute, all other codes require user interaction first
          enum:
            - success
            - neutral
            - warning
            - danger
        verified:
          type: boolean
          description: True if intent has been verified by human
          example: false
        context:
          type: object
          description: >-
            Intent-specific additional data to be shown to the user so he has
            relevant information about the intent. Data type varies by intent
            code
        messagePreview:
          type: string
          nullable: true
          description: >-
            A preview of the response a customer would receive when executing
            this intent. Not always available, e.g. when the respond depends on
            user-input
          example: We have successfully processed your meter reading
        recipient:
          type: string
          example: john@smith.com
        tags:
          type: string
          description: >-
            Tags to show to the user. prePopulated means that all properties are
            already pre-filled by the AI and the user can just insert the
            template to the body. adaptionNeeded is the opposite, and means the
            user still needs to modify the text. writesToErp means that upon
            execution of the intent a write is done to the ERP system, like a
            insertion of a meter reading or the creation of a bill.
          enum:
            - prePopulated
            - adaptionNeeded
            - writesToErp
        data:
          type: object
          description: >-
            Intent-specific data object showing all the data that was extracted
            from the ticket in a structured form. Data type varies by intent
            code
        options:
          description: >-
            Different options that the user is given. Every option is a new
            button in the UI
          type: array
          items:
            $ref: '#/components/schemas/IntentOption'
          example:
            - type: enter_into_system
              name: Eintragen
              icon: check
              recommended: true
              order: 1
            - type: ignore
              name: Ignorieren
              icon: cancel
              recommended: false
              order: 2
            - type: forward_to_vnb
              name: An VNB verweisen
              icon: questionMark
              recommended: false
              order: 3
        infos:
          type: array
          items:
            $ref: '#/components/schemas/IntentInfo'
        extraInfo:
          type: string
          example: null
          nullable: true
          description: Extra-Information shown in tooltip. Info-Icon only shown if not null
        outcome:
          $ref: '#/components/schemas/IntentOutcome'
    Contract:
      type: object
      description: >-
        A contract of a customer. Either electricity or gas. IDs match the
        backend system (powercloud)
      properties:
        id:
          type: integer
          example: 746839
        orderId:
          type: integer
          example: 123
        tenant:
          type: string
          description: >-
            If a customer has multiple tenants/brands, this is the tenant name.
            Currently only used for SAP
          nullable: true
          example: null
        customerId:
          type: string
          example: '123'
        signupDate:
          type: string
          format: date
          example: 1661126400
        status:
          type: string
          example: active
        statusCode:
          type: integer
          example: 5000
        statusCodeTitle:
          type: string
          example: active
        energy:
          type: string
          example: electricity
        energyTypeId:
          type: integer
          example: 1
        energySubTypeId:
          type: integer
          example: 1
        email:
          type: string
          example: johndoe@example.com
        firstname:
          type: string
          example: John
        lastname:
          type: string
          example: Doe
        deliveryAddress:
          type: string
          description: Address where the electricity/gas is being delivered to
          example: Hugo-Junkers-Str. 5, 82031 Grünwald
        iban:
          type: string
          example: DE89370400440532013000
          nullable: true
        monthlyDeposit:
          type: number
          format: integer
          example: 53
          nullable: true
        startDate:
          type: string
          format: date
          example: 1661990400
          nullable: true
        endDate:
          type: string
          example: null
          nullable: true
        consumption:
          type: integer
          example: 3477
          nullable: true
        counterNumber:
          type: string
          example: 1ESY1160669167
          nullable: true
        productId:
          type: integer
          example: 1
          nullable: true
        productName:
          type: string
          example: Flex 24
          nullable: true
        productCode:
          type: string
          example: flx_24
          nullable: true
        campaignId:
          type: integer
          example: 1
          nullable: true
        salesChannelId:
          type: integer
          example: 1
          nullable: true
        unpaidDebt:
          type: number
          format: float
          example: 109.21
          nullable: true
        vatRate:
          type: number
          format: float
          example: 0.09
          description: VAT Rate, usually 0.19 (=19%) for electricity and 0.07 (=7%) for gas
          nullable: true
        basePrice:
          type: number
          format: float
          example: 0.09
          nullable: true
        workingPrice:
          type: number
          format: float
          example: 0.09
          nullable: true
        billingAddress:
          type: string
          description: >-
            Address where written communication should be sent to. NULL if same
            as delivery address
          example: Rechnungssstraße 24, 10587 Berlin
          nullable: true
        business:
          type: boolean
          example: false
          nullable: true
        phone:
          type: string
          example: 491721041689
          nullable: true
        gridOperatorName:
          type: string
          example: E.ON Bayern AG
          nullable: true
        gridOperatorCode:
          type: string
          example: 1000000000000
          nullable: true
        registers:
          type: array
          items:
            type: object
          nullable: true
        erpUrls:
          type: array
          items:
            type: object
            properties:
              url:
                type: string
                example: https://erp-system.com/contract/123
              logo:
                type: string
                description: Logo the FE should show when processing an URL of this type
                enum:
                  - powercloud
                  - lynqtech
                  - sap
                example: powercloud
          nullable: true
        rawData:
          nullable: true
          type: object
          description: >-
            Raw source data from the originating ERP system in the
            ERP-proprietary format is included here. Only provided on request.
          additionalProperties: true
          example: null
        agentPreview:
          type: array
          description: Preview information shown to agents in the UI
          items:
            type: object
            properties:
              label:
                type: string
                description: Label text shown to the agent
                example: Tarif
              value:
                type: string
                description: Value text shown to the agent
                example: Flex 24
              tooltip:
                type: string
                nullable: true
                description: Optional tooltip shown on hover
                example: |-
                  AP: 28.5 ct/kWh
                  GP: 149.88 €/Jahr
              url:
                type: string
                nullable: true
                description: Optional URL that opens when clicking the preview item
                example: https://erp.example.com/contract/123
        tabPreview:
          type: object
          nullable: true
          description: Preview information shown in contract tabs
          properties:
            color:
              type: string
              enum:
                - blue
                - green
                - red
                - grey
                - yellow
                - purple
                - orange
                - teal
              description: Color indicator for contract status
              example: green
            icon:
              type: string
              enum:
                - electricity
                - gas
                - other
              description: Icon shown in the tab
              example: electricity
    IntentOption:
      type: object
      properties:
        type:
          type: string
        name:
          type: string
        icon:
          type: string
        recommended:
          type: boolean
        order:
          description: Buttons ordered from lowest (shown first) to highest (shown last)
          type: integer
    IntentInfo:
      type: object
      description: Info areas shown to the user
      properties:
        code:
          type: string
          nullable: true
          description: >-
            Machine-readable code identifying the info type, e.g. "plausible",
            "USER_WARNING", "TRACE_INFO", "ERROR_MESSAGE"
          example: USER_WARNING
        type:
          type: string
          example: warning
          enum:
            - success
            - neutral
            - warning
            - danger
        message:
          type: string
          example: Reading is plausible
        extraInfo:
          type: string
          example: >-
            Expected reading was 421 kWh. Plausbible because difference to 317
            kWh is below threshold of 200 kWh
          description: Extra-Information shown in tooltip. Info-Icon only shown if not null
          nullable: true
    IntentOutcome:
      type: object
      nullable: true
      description: Shows the outcome (if the intent was already executed)
      properties:
        aiAgentId:
          type: integer
          format: int32
          description: ID of the AI agent that was executed
          example: 1
        success:
          type: boolean
          example: true
        messageLocalized:
          description: >-
            Human-readable message, usually from the backend system. Already
            localized.
          type: string
          example: Powercloud accepted meter reading
        internalData:
          type: object
          description: Technical output for debugging purposes
          additionalProperties: true
          example:
            requestEndpoint: saveReadingByContractId
            requestParams: readingValue=21;date=2022-12-31
        executedAt:
          type: string
          description: Date and time when intent was executed
          format: DateTime
          example: '2022-12-13 22:18:06'
        userId:
          type: integer
          description: User ID of user that triggered the intent. 0 for system user
          example: 1
        sent:
          description: >-
            Was the email / chat message / etc. described in this object 
            successfully sent?
          type: boolean
        ticketClosed:
          description: Was the ticket closed?
          type: boolean
          example: true
        recipient:
          type: string
          example: john@smith.com
        message:
          type: string
          nullable: true
          example: >-
            We successfully processed your meter reading of 21 kWh dated Dec 31,
            2022
        template:
          type: string
          example: <p>Dear John,</p><p>%MESSAGE%</p><i>Mike from your service team</i>
          nullable: true
        sources:
          type: array
          description: Any sources that were used to create the result
          items:
            $ref: '#/components/schemas/Source'
        txId:
          type: string
          example: c916167c94
          description: Unique transaction id. Corresponds to a log entry in enneo
    Source:
      type: object
      description: A source that was used by an AI model / intent
      properties:
        type:
          type: string
          description: >
            The type of source used. ticket = A similar ticket existed and that
            response was used as a basis

            knowledgeSource = An external knowledge source was used, usually a
            company Wiki or FAQ

            template = A predefined text template could be applied

            languageModel = If the AI model did not use anything end created the
            answer by itself
          enum:
            - ticket
            - knowledgeSource
            - template
            - languageModel
          example: knowledgeSource
        id:
          type: integer
          description: Reference to the entry id, e.g. ticketId (if type=ticket)
          example: 376189
          nullable: true
        name:
          type: string
          description: Name of reference (e.g. FAQ title or ticket title)
          example: Opening hours
        url:
          type: string
          description: >-
            URL to associated source. null for sources with internal ids
            (tickets and templates) or if non-existant (language model source)
          example: https://company.com/faq/376189
          nullable: true
        text:
          type: string
          description: Full text that was used as source
          example: >-
            Our service hours are from 8am to 5pm. We are closed on weekends.
            [...]
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: JWT-based authentication
      x-scopes:
        api: Full access to the API
    cookieAuth:
      type: apiKey
      in: cookie
      name: connect.sid
      description: Cookie-based authentication
      x-scopes:
        api: Full access to the API

````