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

# Semantic search across knowledge bases



## OpenAPI

````yaml /api-reference/openapi.json post /v1/knowledge-base/search
openapi: 3.1.0
info:
  title: Feather API
  description: >-
    Unified customer experience platform API. Manages identity, conversations,
    memory, agents, procedures, policies, model routing, knowledge bases,
    integrations, and runtime execution.
  version: 1.21.0
servers:
  - url: https://api-sandbox.featherhq.com
    description: Sandbox
  - url: http://localhost:8000
    description: Local dev
security: []
paths:
  /v1/knowledge-base/search:
    post:
      tags:
        - knowledge-base
      summary: Semantic search across knowledge bases
      operationId: searchKnowledgeBase
      requestBody:
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/SearchRequest'
        required: true
      responses:
        '200':
          description: Successful Response
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
        '400':
          description: Bad request
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '401':
          description: Authentication required
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
        '422':
          description: Validation Error
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/HTTPValidationError'
      security:
        - APIKeyHeader: []
components:
  schemas:
    SearchRequest:
      properties:
        query:
          type: string
          title: Query
        kb_ids:
          items:
            type: string
            format: uuid
          type: array
          minItems: 1
          title: Kb Ids
        rerank:
          type: boolean
          title: Rerank
          description: >-
            Request semantic reranking of the candidate set. For mixed embedding
            spaces, the service may still rerank automatically when Cohere is
            configured because raw vector scores are not comparable across
            spaces.
          default: false
        limit:
          type: integer
          maximum: 100
          minimum: 1
          title: Limit
          default: 30
        prefer_draft:
          type: boolean
          title: Prefer Draft
          default: false
        version_overrides:
          anyOf:
            - additionalProperties:
                type: string
                format: uuid
              propertyNames:
                format: uuid
              type: object
            - type: 'null'
          title: Version Overrides
        alpha:
          type: number
          maximum: 1
          minimum: 0.1
          title: Alpha
          description: >-
            Hybrid search weighting between dense and sparse vectors.
            `alpha=1.0` is dense-only, `alpha=0.5` weights both equally. Minimum
            is 0.1: sparse-dominant queries on this hybrid index starve dense
            signal without materially improving recall, and pure sparse
            (`alpha=0.0`) sends a degenerate all-zero dense vector that Pinecone
            rejects.
          default: 0.5
      type: object
      required:
        - query
        - kb_ids
      title: SearchRequest
    SearchResponse:
      properties:
        results:
          items:
            $ref: '#/components/schemas/SearchResult'
          type: array
          title: Results
        total_results:
          type: integer
          title: Total Results
          description: >-
            Total candidate count before the flat `results` list is truncated by
            `limit`.
        grouped_results:
          anyOf:
            - items:
                $ref: '#/components/schemas/SearchResultGroup'
              type: array
            - type: 'null'
          title: Grouped Results
          description: >-
            Present only when mixed embedding spaces were searched without
            reranking. In that case the response is grouped by embedding space
            instead of pretending there is one globally ranked list.
        ranking_mode:
          type: string
          enum:
            - global_score
            - reranked
            - grouped_unranked
          title: Ranking Mode
          description: >-
            `global_score` means one embedding space ranked by raw vector score;
            `reranked` means a text reranker determined final ordering;
            `grouped_unranked` means mixed embedding spaces were returned as
            separate groups.
        answerability:
          anyOf:
            - $ref: '#/components/schemas/SearchAnswerability'
            - type: 'null'
          description: >-
            Retrieval-confidence verdict for this search (ENG-671). Present only
            when the answerability gate is enabled (shadow/enforce) for the org;
            null when the gate is off. The public search API returns the verdict
            as DATA only — chunk suppression is the agent-path behavior and
            never applies to this endpoint.
      type: object
      required:
        - results
        - total_results
        - ranking_mode
      title: SearchResponse
    ErrorResponse:
      properties:
        error:
          type: string
          title: Error
        message:
          type: string
          title: Message
      type: object
      required:
        - error
        - message
      title: ErrorResponse
      description: Standard error response returned by all API error handlers.
    HTTPValidationError:
      properties:
        detail:
          items:
            $ref: '#/components/schemas/ValidationError'
          type: array
          title: Detail
      type: object
      title: HTTPValidationError
    SearchResult:
      properties:
        chunk_id:
          type: string
          title: Chunk Id
        kb_id:
          type: string
          format: uuid
          title: Kb Id
        document_id:
          type: string
          format: uuid
          title: Document Id
        version_id:
          type: string
          title: Version Id
          default: ''
        document_title:
          type: string
          title: Document Title
        source_type:
          type: string
          title: Source Type
        content:
          type: string
          title: Content
        score:
          type: number
          title: Score
        chunk_index:
          type: integer
          title: Chunk Index
        position:
          anyOf:
            - $ref: '#/components/schemas/TextPosition'
            - type: 'null'
        sensitivity:
          anyOf:
            - type: string
            - type: 'null'
          title: Sensitivity
        sensitivity_level:
          anyOf:
            - type: integer
            - type: 'null'
          title: Sensitivity Level
        pii_status:
          type: string
          title: Pii Status
          default: ''
        pii_sensitivity:
          type: string
          title: Pii Sensitivity
          default: ''
        pii_coverage_status:
          type: string
          title: Pii Coverage Status
          default: ''
      type: object
      required:
        - chunk_id
        - kb_id
        - document_id
        - document_title
        - source_type
        - content
        - score
        - chunk_index
      title: SearchResult
    SearchResultGroup:
      properties:
        embedding_model:
          type: string
          title: Embedding Model
        embedding_dimensions:
          type: integer
          title: Embedding Dimensions
        kb_ids:
          items:
            type: string
            format: uuid
          type: array
          title: Kb Ids
        results:
          items:
            $ref: '#/components/schemas/SearchResult'
          type: array
          title: Results
      type: object
      required:
        - embedding_model
        - embedding_dimensions
        - kb_ids
        - results
      title: SearchResultGroup
    SearchAnswerability:
      properties:
        label:
          type: string
          enum:
            - answerable
            - low_confidence
            - not_answerable
            - unknown
          title: Label
          description: Retrieval-confidence verdict for the query against the searched KBs.
        reason_code:
          type: string
          enum:
            - no_results
            - below_low_threshold
            - weak_band
            - above_high_threshold
            - not_actionable_basis
            - verdict_failed
          title: Reason Code
          description: Why the verdict landed where it did.
        raw_top_score:
          anyOf:
            - type: number
            - type: 'null'
          title: Raw Top Score
          description: >-
            Top pre-normalization retrieval score; null on an empty or non-raw
            result set.
        score_basis:
          type: string
          enum:
            - raw_dotproduct
            - minmax_norm
            - cohere_rerank
            - grouped
          title: Score Basis
          description: >-
            Retrieval-path regime the score is on: `raw_dotproduct` /
            `minmax_norm` / `cohere_rerank` / `grouped`. The verdict is only
            actionable on `raw_dotproduct`.
      type: object
      required:
        - label
        - reason_code
        - score_basis
      title: SearchAnswerability
      description: >-
        Curated, consumer-facing slice of the retrieval-confidence verdict
        (ENG-671).


        Deliberately a SUBSET of the internal ``AnswerabilityDecision``: the
        public

        search API exposes the verdict + why, NOT internal gate config (``mode``
        /

        ``caller`` / ``action`` / ``suppressed`` / thresholds). Those are
        operational

        details — and on this endpoint ``action`` is always ``pass`` anyway, so

        surfacing them would only be noise + needless coupling for API
        consumers.
    ValidationError:
      properties:
        loc:
          items:
            anyOf:
              - type: string
              - type: integer
          type: array
          title: Location
        msg:
          type: string
          title: Message
        type:
          type: string
          title: Error Type
        input:
          title: Input
        ctx:
          type: object
          title: Context
      type: object
      required:
        - loc
        - msg
        - type
      title: ValidationError
    TextPosition:
      properties:
        type:
          type: string
          const: text
          title: Type
          default: text
        start_char:
          type: integer
          minimum: 0
          title: Start Char
        end_char:
          type: integer
          minimum: 0
          title: End Char
      type: object
      required:
        - start_char
        - end_char
      title: TextPosition
      description: >-
        Character-offset position for text and markdown chunks.


        `start_char` and `end_char` are **Unicode code-point** offsets into the

        decoded UTF-8 source text. In Python: ``text[start_char:end_char]``.


        JavaScript's ``String.prototype.slice()`` counts UTF-16 code units,
        which

        differ from code-point offsets for non-BMP characters (emoji, some CJK).

        JS consumers should convert with ``Array.from(str)`` before slicing —
        see

        the API docs for a helper.
  securitySchemes:
    APIKeyHeader:
      type: apiKey
      in: header
      name: x-api-key

````