---
title: "Search Markets"
method: GET
path: "/v1/markets/search"
tags: ["markets"]
---

# Search Markets

`GET /v1/markets/search`

Search and browse markets across all exchanges.

Supports:
- Exact match on ticker, condition_id, slug, river_id
- Full-text search on name, description, tags
- Browse by filters (no query required)
- Results ranked by relevance

Defaults to status=active; pass status=all to include closed markets.

## Query parameters

- `q` string, nullable — Search query
- `exchange_name` string, nullable — Filter by exchange name (KALSHI, POLYMARKET)
- `category` string[], nullable — Filter by canonical category. Repeat the param to filter to multiple categories (Sports, Crypto, Politics, Finance, Entertainment, Science & Tech, Weather, World Affairs, Health, Social, Other).
- `subcategory` string, nullable — Filter by subcategory (e.g. Basketball, Football)
- `status` 'active' | 'closed' | 'inactive' | 'all' — ``status`` query values for market search. ALL matches any status except inactive (never-activated exchange junk), which stays opt-in via INACTIVE.
- `expiration_date_start` string, date-time, nullable — Start of expiration date range (inclusive, ISO 8601)
- `expiration_date_end` string, date-time, nullable — End of expiration date range (exclusive, ISO 8601)
- `start_datetime_after` string, date-time, nullable — Filter to markets with start_datetime >= this (ISO 8601)
- `start_datetime_before` string, date-time, nullable — Filter to markets with start_datetime < this (ISO 8601)
- `event_ticker` string, nullable — Filter by event_ticker (exact match)
- `last_price_min` number, nullable — Filter to markets with last_price >= this value (0.0–1.0 YES probability).
- `last_price_max` number, nullable — Filter to markets with last_price <= this value (0.0–1.0 YES probability).
- `volume_min` integer, nullable — Filter to events whose total summed volume >= this value.
- `sort_by` string, nullable — Sort mode for event-based pagination: trending, volume, newest, ending-soon, start-time, price
- `include_combos` 'exclude' | 'include' | 'only' — How ``/v1/markets/search`` treats Kalshi parlay containers (``is_combo``). - EXCLUDE (default): drop combos — standard markets/browse behaviour. - INCLUDE: return combos alongside standard markets. - ONLY: return combos exclusively (the Combos browse tab / parlay search).
- `limit` integer — Maximum number of results
- `offset` integer — Offset for pagination
- `event_limit` integer, nullable — Paginate by events instead of markets. Up to 200 by default; values above that require start_datetime_after or start_datetime_before.
- `event_offset` integer, nullable — Event offset for event-based pagination
- `markets_per_event` integer, nullable — With event pagination, cap the markets returned per event to the top N by volume (query-matched markets always survive the cap). Each row's event_market_count carries the event's full market count so clients can lazy-load the rest.

## Response `200`

Successful Response

- MarketSearchResponse — Schema for market search response.
  - `query` string, required
  - `results` MarketSearchResult[], required
    - `river_id` integer, required
    - `exchange_value` integer, required
    - `exchange_name` string, required
    - `ticker` string, nullable
    - `token_id_yes` string, nullable
    - `token_id_no` string, nullable
    - `slug` string, nullable
    - `tick_size_price` number, required
    - `tick_size_qty` number, required
    - `tick_structure` string
    - `minimum_order_size` number, required
    - `expiration_datetime` string, nullable — Market expiration datetime (UTC)
    - `start_datetime` string, nullable — Game/event start datetime (UTC). Populated for sports; null otherwise.
    - `neg_risk` boolean, required
    - `neg_risk_id` string, nullable
    - `condition_id` string, nullable
    - `name` string, required
    - `subtitle` string, nullable
    - `description` string, nullable
    - `status` 'active' | 'closed' | 'inactive', required — Instrument status derived in instruments table from exchange-specific fields. Kalshi: maps from kalshi_markets.status - 'active' -> ACTIVE - everything else (closed, determined, finalized, settled, amended, inactive, initialized) -> CLOSED Polymarket: maps from polymarket_markets.closed and polymarket_markets.active booleans - closed=true -> CLOSED - active=true (and not closed) -> ACTIVE - else (active=false, closed=false) -> INACTIVE
    - `category` string
    - `subcategory` string, nullable
    - `rank` number, nullable
    - `event_ticker` string, nullable
    - `event_title` string, nullable
    - `is_combo` boolean — True for parlays.
    - `volume` integer, nullable
    - `volume_24h` integer, nullable
    - `series_ticker` string, nullable
    - `image` string, nullable
    - `last_price` number, nullable — Most recent YES price normalized to 0.0–1.0 (probability). Kalshi cents / 100; Polymarket already 0.0–1.0. NULL when no trade has been observed.
    - `primary_entity_name` string, nullable — Resolved display name of the canonical structured-target entity (player, team, competitor, …) referenced by the market. NULL for markets without a structured target. Kalshi only — Polymarket has no equivalent concept.
    - `event_market_count` integer, nullable — Total number of markets in this row's event. Only populated on the event-paginated path; when markets_per_event trims an event, this is how clients know more markets exist than were returned.
  - `total` integer, required
  - `total_events` integer, nullable

## Other responses

- `422` — Validation Error

---

[API](https://skmtc.net/rivermarkets/apis/river-finance-api.md) · [All operations](https://skmtc.net/rivermarkets/apis/river-finance-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/rivermarkets/river-finance-api/revisions/c90d562d4ad1/schema)
