Skip to main content

Installation

Quick Start

See Market Data → Search Markets for the full list of filters. The SDK signs every REST request and WebSocket handshake locally with Ed25519. Your private key never leaves the process. See Authentication for the canonical-string spec if you need to verify what the SDK is producing.

Async Support

Trading

Place an Order

List Orders

Cancel an Order

Complex Orders

Complex orders let you place iceberg slices, pegged orders, smart-taker orders, and take-profit / stop-loss triggers. Pass exactly one of iceberg_order_params, peg_order_params, smart_taker_order_params, or conditional_order_params along with subaccount_id and either river_id or generic_asset_id. The endpoint returns 202 with the order in PENDING status — it’s activated asynchronously.

Iceberg

Peg

Smart Taker

Take-profit attached to a parent order

Standalone stop

  • Prices and limit_price are 0–1 (Kalshi-style probability), not dollars.
  • For TP/SL you must supply parent_river_order_id (or parent_complex_order_id to chain). For standalone STOP, omit parents and set stop_order_price.
  • TriggerOrder.price is required when order_type="LIMIT", omit for "MARKET".

Portfolio

Get Positions

Get Fills

Market Data

Search Markets

status defaults to "active"; pass status="all" to also include closed markets. When using a free-text q=, always pair it with date filters (expiration_date_start, start_datetime_after/before) — otherwise the ranking can be dominated by stale markets. See the Quick Start above for the recommended shape.

Parameters

string
Search query.
string
Filter by exchange name (KALSHI, POLYMARKET).
list[string]
Filter by canonical category. Pass a list to filter to multiple: Sports, Crypto, Politics, Finance, Entertainment, Science & Tech, Weather, World Affairs, Health, Social, Other.
string
Filter by subcategory (e.g. Basketball, Football).
string
default:"active"
Filter by instrument status: active (default), closed, inactive, or all for active and closed markets.
string (ISO 8601)
Start of expiration date range (inclusive).
string (ISO 8601)
End of expiration date range (exclusive).
string (ISO 8601)
Filter to markets with start_datetime >= this.
string (ISO 8601)
Filter to markets with start_datetime < this.
string
Filter by event_ticker (exact match).
string
Sort mode for event-based pagination: trending, volume, newest, ending-soon, start-time.
string
default:"exclude"
How to treat Kalshi parlays (combos): exclude (default), include alongside standard markets, or only combos. Combo results carry is_combo=True and each combo paginates as its own event.
integer
default:"20"
Maximum number of results (1–1000).
integer
default:"0"
Offset for pagination.
integer
Paginate by events instead of markets. Up to 200 by default; values above that require start_datetime_after or start_datetime_before.
integer
Event offset for event-based pagination.

Combos

Kalshi parlays (combos) are excluded from search by default. Browse them with include_combos, then resolve a combo’s constituent legs — legs come back hydrated with the full market row when the leg market is in the universe.
list[integer]
required
Combo river_ids to resolve (max 200). Non-combo ids, or combos whose legs have not been ingested yet, return an empty legs list.

Orderbook

Price History

Realtime (WebSockets)

The async client exposes four live data feeds at client.realtime. Each returns a Subscription you use as an async context manager and async iterator. Disconnects are handled transparently — the client reconnects and re-sends the active subscription set, so iteration just resumes. The underlying wire protocol is documented under WS API Reference.

Orderbook stream

You can mutate the subscription on the fly:

Order status stream

Order updates are pinned to one subaccount at handshake — there is no subscribe/unsubscribe frame.

Trade tape

Fill stream

Like order updates, fills are pinned to one subaccount at handshake — there is no subscribe/unsubscribe frame. Each frame is one discrete execution.

Notes

  • All four subscriptions reconnect transparently on disconnect; the iterator simply pauses and resumes.
  • In Jupyter, drop asyncio.run(...) and use top-level await directly in a cell.
  • Subscription works as a context manager — exiting the async with block closes the socket cleanly.
  • Message.type is always set; endpoint-specific fields (data, river_id, orders, code, message) are accessed as attributes or via msg.model_extra.

Subaccounts

Watchlists

Named, ordered lists of markets owned by a subaccount.

Error Handling

The SDK raises typed exceptions for API errors:

Configuration

GitHub

View the source code and contribute on GitHub.