{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://artifacts.apis.io/upriver-ai/json-schema/upriver-ai-search-topics-request-schema.json",
  "title": "SearchTopicsRequest",
  "description": "Request for searching breakout topics.",
  "x-generated": "2026-10-31",
  "x-method": "derived",
  "x-generator": "derive-json-schema.py",
  "x-source": "openapi/upriver-ai-openapi.json#/components/schemas/SearchTopicsRequest",
  "properties": {
    "query": {
      "type": "string",
      "minLength": 1,
      "title": "Query",
      "description": "Search query text"
    },
    "feed": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Feed",
      "description": "Entitled private feed whose Breakout topics should be searched."
    },
    "vertical": {
      "anyOf": [
        {
          "type": "string"
        },
        {
          "type": "null"
        }
      ],
      "title": "Vertical",
      "description": "Filter by vertical (e.g., 'sports')"
    },
    "mode": {
      "$ref": "#/$defs/SearchMode",
      "description": "Search mode: vector, keyword, hybrid",
      "default": "hybrid"
    },
    "surface_mode": {
      "$ref": "#/$defs/ListSurfaceMode",
      "description": "Return raw topics or deduped derived story surfaces",
      "default": "topic"
    },
    "limit": {
      "type": "integer",
      "maximum": 100.0,
      "minimum": 1.0,
      "title": "Limit",
      "description": "Maximum number of results. Requesting more than 20 results requires a credits-based plan.",
      "default": 20
    },
    "include": {
      "items": {
        "type": "string",
        "enum": [
          "citations",
          "entities"
        ]
      },
      "type": "array",
      "title": "Include",
      "description": "Optional expansions to include in the response. Allowed values: citations, entities. Example: [\"citations\", \"entities\"]"
    },
    "include_citations": {
      "type": "boolean",
      "title": "Include Citations",
      "description": "Deprecated: use include=[\"citations\",\"entities\"] instead.",
      "default": false
    },
    "query_context": {
      "anyOf": [
        {
          "$ref": "#/$defs/SearchQueryContext"
        },
        {
          "type": "null"
        }
      ],
      "description": "Optional source-aware context for query rewriting. Useful for terse external prompts such as Kalshi markets."
    },
    "kalshi_event_url": {
      "anyOf": [
        {
          "type": "string",
          "maxLength": 500
        },
        {
          "type": "null"
        }
      ],
      "title": "Kalshi Event Url",
      "description": "Optional Kalshi event URL or ticker. When provided, the server resolves event metadata and uses it for query planning. Mutually exclusive with query_context."
    },
    "citation_sources": {
      "anyOf": [
        {
          "items": {
            "$ref": "#/$defs/CitationSourceCategory"
          },
          "type": "array"
        },
        {
          "type": "null"
        }
      ],
      "title": "Citation Sources",
      "description": "Restrict returned citations to these source categories (news, reddit, twitter). Omit for all sources. Only applies when surface_mode=topic."
    },
    "llm_relevance": {
      "type": "boolean",
      "title": "Llm Relevance",
      "description": "Enable enhanced relevance scoring for search results. When true, results are scored and re-ranked by how well they match the query intent.",
      "default": true
    }
  },
  "type": "object",
  "required": [
    "query"
  ],
  "$defs": {
    "CitationSourceCategory": {
      "type": "string",
      "enum": [
        "news",
        "reddit",
        "twitter"
      ],
      "title": "CitationSourceCategory",
      "description": "Citation source categories usable as a citation filter.\n\nA subset of the ``source_category`` values that appear on returned citations —\nthe categories worth filtering on. Other categories (web, tiktok, trends) can\nstill appear on citations but are not offered as filter values."
    },
    "ListSurfaceMode": {
      "type": "string",
      "enum": [
        "topic",
        "story"
      ],
      "title": "ListSurfaceMode",
      "description": "List surface mode for breakout browse responses."
    },
    "SearchMode": {
      "type": "string",
      "enum": [
        "vector",
        "keyword",
        "hybrid"
      ],
      "title": "SearchMode",
      "description": "Search mode for topic search."
    },
    "SearchQueryContext": {
      "properties": {
        "source": {
          "type": "string",
          "title": "Source",
          "description": "Optional source hint for query rewriting. Currently only 'kalshi' changes search behavior."
        },
        "series_title": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Series Title",
          "description": "Source series/event family title for broader context."
        },
        "market_subtitle": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Market Subtitle",
          "description": "Source subtitle, often containing compact participant codes."
        },
        "competition": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Competition",
          "description": "Source competition or league label, e.g. 'Pro Basketball (M)'."
        },
        "competition_scope": {
          "anyOf": [
            {
              "type": "string"
            },
            {
              "type": "null"
            }
          ],
          "title": "Competition Scope",
          "description": "Source event scope such as Game, Future, or Tournament."
        },
        "contract_tickers": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Contract Tickers",
          "description": "Structured contract tickers associated with the source market."
        },
        "contract_titles": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Contract Titles",
          "description": "Optional contract display titles from the source market."
        },
        "contract_subtitles": {
          "items": {
            "type": "string"
          },
          "type": "array",
          "title": "Contract Subtitles",
          "description": "Optional contract subtitles from the source market."
        }
      },
      "type": "object",
      "required": [
        "source"
      ],
      "title": "SearchQueryContext",
      "description": "Optional caller context for source-aware search planning.\n\nToday this is used for Kalshi-originated queries, where the visible query text\nis often too terse to retrieve the right breakout topics without extra market\nmetadata. Unknown sources are accepted but ignored by the current API logic."
    }
  }
}