kalshi

Kalshi is a regulated prediction market exchange. Use this skill to interact with the Kalshi API for market data, trading, portfolio management, WebSocket streaming, and historical data retrieval.

Safety Notice

This listing is imported from skills.sh public index metadata. Review upstream SKILL.md and repository scripts before running.

Copy this and send it to your AI assistant to learn

Install skill "kalshi" with this command: npx skills add outsharp/shipp-skills/outsharp-shipp-skills-kalshi

Kalshi API

Kalshi is a CFTC-regulated prediction market exchange where users trade on the outcomes of real-world events.

Check this skill and the official documentation FREQUENTLY. The canonical machine-readable index of all docs lives at:

https://docs.kalshi.com/llms.txt

Always consult llms.txt to discover every available page before building. It is the single source of truth for endpoint references, SDK docs, WebSocket channels, FIX protocol details, and getting-started guides.


Key Concepts (Glossary)

TermDefinition
MarketA single binary outcome contract (Yes / No) with prices in cents (1–99¢).
EventA collection of related markets representing a real-world occurrence (e.g., an election, a weather reading).
SeriesA template for recurring events that share the same structure and rules (e.g., "Daily Highest Temp in NYC").
OrderbookBids only — in binary markets a YES bid at X¢ is equivalent to a NO ask at (100−X)¢.
FillA matched trade on one of your orders.
SettlementThe final resolution of a market (Yes or No) after determination.
Multivariate EventA combo event created dynamically from a multivariate event collection.

Full glossary: https://docs.kalshi.com/getting_started/terms.md


Base URLs

EnvironmentREST APIWebSocket
Productionhttps://api.elections.kalshi.com/trade-api/v2wss://api.elections.kalshi.com/trade-api/ws/v2
Demohttps://demo-api.kalshi.co/trade-api/v2wss://demo-api.kalshi.co/trade-api/ws/v2

Note: Despite the elections subdomain, the production URL serves ALL Kalshi markets — economics, weather, tech, entertainment, etc.

Demo environment info: https://docs.kalshi.com/getting_started/demo_env.md


Documentation & References

All detailed examples, request/response schemas, and walkthroughs live in the official docs. Always consult these before building:


Authentication

Kalshi uses RSA-PSS signed requests (not Bearer tokens). Every authenticated request requires three headers:

HeaderValue
KALSHI-ACCESS-KEYYour API Key ID
KALSHI-ACCESS-TIMESTAMPCurrent Unix timestamp in milliseconds
KALSHI-ACCESS-SIGNATUREBase64-encoded RSA-PSS signature of {timestamp}{METHOD}{path}

Important: When signing, use the path without query parameters. For example, sign /trade-api/v2/portfolio/orders even if the request URL is /trade-api/v2/portfolio/orders?limit=5.

Generating API Keys

  1. Log in → Account Settings → API Keys section.
  2. Click "Create New API Key" to generate an RSA key pair.
  3. Store the private key immediately — it cannot be retrieved again.

Full guide: https://docs.kalshi.com/getting_started/api_keys.md

Python Signing Example

import base64, datetime, requests
from cryptography.hazmat.primitives import serialization, hashes
from cryptography.hazmat.primitives.asymmetric import padding

def load_private_key(file_path):
    with open(file_path, "rb") as f:
        return serialization.load_pem_private_key(f.read(), password=None)

def sign_pss(private_key, text: str) -> str:
    sig = private_key.sign(
        text.encode("utf-8"),
        padding.PSS(mgf=padding.MGF1(hashes.SHA256()), salt_length=padding.PSS.DIGEST_LENGTH),
        hashes.SHA256(),
    )
    return base64.b64encode(sig).decode("utf-8")

def kalshi_headers(key_id, private_key, method, path):
    ts = str(int(datetime.datetime.now().timestamp() * 1000))
    path_no_qs = path.split("?")[0]
    sig = sign_pss(private_key, ts + method + path_no_qs)
    return {
        "KALSHI-ACCESS-KEY": key_id,
        "KALSHI-ACCESS-SIGNATURE": sig,
        "KALSHI-ACCESS-TIMESTAMP": ts,
    }

JavaScript Signing Example

const crypto = require("crypto");
const fs = require("fs");

function signPss(privateKeyPem, text) {
  const sign = crypto.createSign("RSA-SHA256");
  sign.update(text);
  sign.end();
  return sign.sign({
    key: privateKeyPem,
    padding: crypto.constants.RSA_PKCS1_PSS_PADDING,
    saltLength: crypto.constants.RSA_PSS_SALTLEN_DIGEST,
  }).toString("base64");
}

function kalshiHeaders(keyId, privateKeyPem, method, path) {
  const ts = Date.now().toString();
  const pathNoQs = path.split("?")[0];
  const sig = signPss(privateKeyPem, ts + method + pathNoQs);
  return {
    "KALSHI-ACCESS-KEY": keyId,
    "KALSHI-ACCESS-SIGNATURE": sig,
    "KALSHI-ACCESS-TIMESTAMP": ts,
  };
}

SDKs

Kalshi provides official SDKs. Prefer these for production integrations:

SDKInstallDocs
Python (sync)pip install kalshi_python_synchttps://docs.kalshi.com/sdks/python/quickstart.md
Python (async)pip install kalshi_python_asynchttps://docs.kalshi.com/sdks/python/quickstart.md
TypeScriptnpm install kalshi-typescripthttps://docs.kalshi.com/sdks/typescript/quickstart.md

The old kalshi-python package is deprecated. Migrate to kalshi_python_sync or kalshi_python_async.

SDK overview: https://docs.kalshi.com/sdks/overview.md

For production applications, consider generating your own client from the OpenAPI spec.


Rate Limits

TierReadWrite
Basic20/s10/s
Advanced30/s30/s
Premier100/s100/s
Prime400/s400/s

Write-limited endpoints: CreateOrder, CancelOrder, AmendOrder, DecreaseOrder, BatchCreateOrders, BatchCancelOrders. In batch APIs each item counts as 1 transaction (except BatchCancelOrders where each cancel = 0.2 transactions).

Full details: https://docs.kalshi.com/getting_started/rate_limits.md


Pagination

The API uses cursor-based pagination. Responses include a cursor field; pass it as ?cursor={value} on the next request. An empty/null cursor means no more pages. Default page size is 100 (max typically 1000).

Full guide: https://docs.kalshi.com/getting_started/pagination.md


REST API Endpoints Overview

Below is a summary organized by domain. For full request/response schemas, see the linked docs or browse https://docs.kalshi.com/llms.txt.

Markets

EndpointMethodAuthDescription
/marketsGETNoList markets with filters (status, series, timestamps). Docs: Get Markets
/markets/{ticker}GETNoGet a single market by ticker. Docs: Get Market
/markets/{ticker}/orderbookGETNoGet current orderbook (yes bids + no bids). Docs: Get Market Orderbook
/markets/{ticker}/candlesticksGETNoCandlestick data (1m, 1h, 1d). Docs: Get Market Candlesticks
/markets/candlesticksPOSTNoBatch candlesticks for up to 100 tickers. Docs: Batch Get Market Candlesticks
/markets/tradesGETNoAll public trades. Docs: Get Trades
/series/{ticker}GETNoGet a series. Docs: Get Series
/seriesGETNoList series. Docs: Get Series List

Events

EndpointMethodAuthDescription
/eventsGETNoList events (excludes multivariate). Docs: Get Events
/events/{ticker}GETNoGet a single event. Docs: Get Event
/events/{ticker}/metadataGETNoEvent metadata only. Docs: Get Event Metadata
/events/{ticker}/candlesticksGETNoAggregated event candlesticks. Docs: Get Event Candlesticks
/events/{ticker}/forecast/percentile_historyGETNoForecast percentile history. Docs: Get Event Forecast Percentile History
/events/multivariateGETNoList multivariate events. Docs: Get Multivariate Events

Orders (Authenticated)

EndpointMethodAuthDescription
/portfolio/ordersPOSTYesCreate an order. Docs: Create Order
/portfolio/ordersGETYesList your orders (resting/canceled/executed). Docs: Get Orders
/portfolio/orders/{order_id}GETYesGet a single order. Docs: Get Order
/portfolio/orders/{order_id}DELETEYesCancel an order. Docs: Cancel Order
/portfolio/orders/{order_id}/amendPOSTYesAmend price/count. Docs: Amend Order
/portfolio/orders/{order_id}/decreasePOSTYesDecrease contract count. Docs: Decrease Order
/portfolio/orders/{order_id}/queue_positionGETYesQueue position. Docs: Get Order Queue Position
/portfolio/orders/queue_positionsGETYesQueue positions for all resting orders. Docs: Get Queue Positions for Orders
/portfolio/orders/batchedPOSTYesBatch create (up to 20). Docs: Batch Create Orders
/portfolio/orders/batchedDELETEYesBatch cancel (up to 20). Docs: Batch Cancel Orders

Portfolio (Authenticated)

EndpointMethodAuthDescription
/portfolio/balanceGETYesAccount balance (cents). Docs: Get Balance
/portfolio/positionsGETYesMarket positions. Docs: Get Positions
/portfolio/fillsGETYesYour fills. Docs: Get Fills
/portfolio/settlementsGETYesSettlement history. Docs: Get Settlements
/portfolio/resting_order_valueGETYesTotal resting order value (FCM). Docs: Get Total Resting Order Value

Subaccounts (Authenticated)

EndpointMethodAuthDescription
/portfolio/subaccountsPOSTYesCreate subaccount (max 32). Docs: Create Subaccount
/portfolio/subaccounts/balancesGETYesAll subaccount balances. Docs: Get All Subaccount Balances
/portfolio/subaccounts/transfersGETYesSubaccount transfer history. Docs: Get Subaccount Transfers
/portfolio/subaccounts/transferPOSTYesTransfer between subaccounts. Docs: Transfer Between Subaccounts

Order Groups (Authenticated)

Order groups apply a rolling 15-second contracts limit; when hit, all orders in the group are auto-cancelled.

EndpointMethodAuthDescription
/portfolio/order_groupsPOSTYesCreate group. Docs: Create Order Group
/portfolio/order_groupsGETYesList groups. Docs: Get Order Groups
/portfolio/order_groups/{id}GETYesGet group. Docs: Get Order Group
/portfolio/order_groups/{id}DELETEYesDelete group. Docs: Delete Order Group
/portfolio/order_groups/{id}/resetPOSTYesReset counter. Docs: Reset Order Group
/portfolio/order_groups/{id}/triggerPOSTYesManually trigger. Docs: Trigger Order Group
/portfolio/order_groups/{id}/limitPUTYesUpdate limit. Docs: Update Order Group Limit

Communications / RFQ (Authenticated)

EndpointMethodAuthDescription
/communications/idGETYesGet your comms ID. Docs: Get Communications ID
/rfqsPOSTYesCreate RFQ (max 100 open). Docs: Create RFQ
/rfqsGETYesList RFQs. Docs: Get RFQs
/rfqs/{id}GETYesGet RFQ. Docs: Get RFQ
/rfqs/{id}DELETEYesDelete RFQ. Docs: Delete RFQ
/quotesPOSTYesCreate quote. Docs: Create Quote
/quotesGETYesList quotes. Docs: Get Quotes
/quotes/{id}GETYesGet quote. Docs: Get Quote
/quotes/{id}DELETEYesDelete quote. Docs: Delete Quote
/quotes/{id}/acceptPOSTYesAccept quote. Docs: Accept Quote
/quotes/{id}/confirmPOSTYesConfirm quote. Docs: Confirm Quote

Historical Data (Authenticated)

Historical data is for archived markets, orders, and fills that have moved past cutoff timestamps.

EndpointMethodAuthDescription
/historical/cutoff_timestampsGETYesCutoff boundaries. Docs: Get Historical Cutoff Timestamps
/historical/marketsGETYesArchived markets. Docs: Get Historical Markets
/historical/markets/{ticker}GETYesSingle archived market. Docs: Get Historical Market
/historical/markets/{ticker}/candlesticksGETYesArchived candlesticks. Docs: Get Historical Market Candlesticks
/historical/fillsGETYesArchived fills. Docs: Get Historical Fills
/historical/ordersGETYesArchived orders. Docs: Get Historical Orders

Historical data guide: https://docs.kalshi.com/getting_started/historical_data.md

Multivariate Collections

EndpointMethodAuthDescription
/multivariate/collectionsGETNoList collections. Docs: Get Multivariate Event Collections
/multivariate/collections/{ticker}GETNoGet collection. Docs: Get Multivariate Event Collection
/multivariate/collections/{ticker}/marketsPOSTYesCreate market in collection. Docs: Create Market In Multivariate Event Collection
/multivariate/collections/{ticker}/lookupGETNoLookup tickers. Docs: Lookup Tickers For Market In Multivariate Event Collection
/multivariate/collections/{ticker}/lookup_historyGETNoRecent lookups. Docs: Get Multivariate Event Collection Lookup History

Milestones & Structured Targets

EndpointMethodAuthDescription
/milestonesGETNoList milestones. Docs: Get Milestones
/milestones/{id}GETNoGet milestone. Docs: Get Milestone
/structured_targetsGETNoList structured targets. Docs: Get Structured Targets
/structured_targets/{id}GETNoGet structured target. Docs: Get Structured Target

Live Data

EndpointMethodAuthDescription
/live_data/{milestone_id}GETNoLive data for milestone. Docs: Get Live Data
/live_dataGETNoMultiple milestones. Docs: Get Multiple Live Data

Search & Discovery

EndpointMethodAuthDescription
/search/sports/filtersGETNoSport filters. Docs: Get Filters for Sports
/search/tagsGETNoTags by category. Docs: Get Tags for Series Categories

Exchange & Account

EndpointMethodAuthDescription
/exchange/statusGETNoExchange status. Docs: Get Exchange Status
/exchange/scheduleGETNoExchange schedule. Docs: Get Exchange Schedule
/exchange/announcementsGETNoAnnouncements. Docs: Get Exchange Announcements
/exchange/data_timestampGETYesData freshness timestamp. Docs: Get User Data Timestamp
/exchange/series_fee_changesGETNoFee changes. Docs: Get Series Fee Changes
/account/api_limitsGETYesYour rate limit tier. Docs: Get Account API Limits
/account/api_keysGETYesList API keys. Docs: Get API Keys
/account/api_keysPOSTYesCreate API key. Docs: Create API Key
/account/api_keys/generatePOSTYesGenerate key pair. Docs: Get API Keys
/account/api_keys/{id}DELETEYesDelete API key. Docs: Delete API Key

Incentive Programs

EndpointMethodAuthDescription
/incentivesGETNoList incentives. Docs: Get Incentives

WebSocket API

A single authenticated WebSocket connection provides real-time streaming. Subscribe to channels by sending JSON commands.

Connection

wss://api.elections.kalshi.com/trade-api/ws/v2      (production)
wss://demo-api.kalshi.co/trade-api/ws/v2            (demo)

Authentication headers (KALSHI-ACCESS-KEY, KALSHI-ACCESS-SIGNATURE, KALSHI-ACCESS-TIMESTAMP) must be included during the handshake. Sign the string {timestamp}GET/trade-api/ws/v2.

Available Channels

ChannelAuth RequiredDescriptionDocs
tickerNo*Market price/volume/OI updatesMarket Ticker
tradeNo*Public trade notificationsPublic Trades
market_lifecycle_v2No*Market/event state changesMarket & Event Lifecycle
multivariateNo*Multivariate lookup notificationsMultivariate Lookups
orderbook_deltaYesReal-time orderbook updatesOrderbook Updates
fillYesYour fill notificationsUser Fills
orderYesYour order updatesUser Orders
market_positionsYesYour position updatesMarket Positions
communicationsYesRFQ/quote notificationsCommunications
order_group_updatesYesOrder group lifecycleOrder Group Updates

*The connection itself always requires authentication, even for public channels.

Subscribe Command

{
  "id": 1,
  "cmd": "subscribe",
  "params": {
    "channels": ["ticker", "orderbook_delta"],
    "market_tickers": ["KXHIGHNY-24JAN01-T60"]
  }
}

Keep-Alive

Kalshi sends Ping frames every 10 seconds with body heartbeat. Clients must respond with Pong frames. Docs: Connection Keep-Alive

Full WebSocket guide: https://docs.kalshi.com/getting_started/quick_start_websockets.md


Orderbook Structure

Kalshi orderbooks return bids only (no asks). In binary markets:

  • A YES bid at X¢ = a NO ask at (100−X)¢
  • A NO bid at Y¢ = a YES ask at (100−Y)¢

Each entry is [price, quantity] sorted ascending. The best bid is the last element.

Spread calculation:

  • Best YES ask = 100 - best_no_bid
  • Spread = Best YES ask − Best YES bid

Full guide: https://docs.kalshi.com/getting_started/orderbook_responses.md


FIX Protocol

Kalshi also supports the Financial Information eXchange (FIX) protocol for low-latency trading:


Common Patterns

Fetch All Open Markets for a Series

curl -s "https://api.elections.kalshi.com/trade-api/v2/markets?series_ticker=KXHIGHNY&status=open" | jq '.markets[] | {ticker, title, yes_price, volume}'

Get Orderbook for a Market

curl -s "https://api.elections.kalshi.com/trade-api/v2/markets/KXHIGHNY-24JAN01-T60/orderbook" | jq '.orderbook'

Paginate Through All Results

# First page
curl -s "https://api.elections.kalshi.com/trade-api/v2/markets?limit=100" > page1.json
# Extract cursor for next page
CURSOR=$(jq -r '.cursor' page1.json)
# Next page
curl -s "https://api.elections.kalshi.com/trade-api/v2/markets?limit=100&cursor=$CURSOR" > page2.json

Usage Tips

  • Always check llms.txt first: https://docs.kalshi.com/llms.txt has every endpoint and guide.
  • Use the demo environment for testing — credentials are separate from production.
  • Never hardcode API keys — use environment variables or secure key storage.
  • Prices are in cents (1–99). Monetary values in WebSocket position channels are in centi-cents (divide by 10,000 for dollars).
  • Sign paths without query parameters. Strip everything after ? before signing.
  • Handle pagination — always check for a non-null cursor and loop until exhausted.
  • Respect rate limits — implement exponential backoff on 429 responses.
  • Combine REST + WebSocket for the most accurate state: use REST for initial snapshots and WebSocket for real-time deltas.
  • Orderbook is bids-only — derive asks via the 100−price complement.
  • Historical vs. Live data: Check cutoff timestamps to know whether to query live or historical endpoints.
  • For market status values, use: unopened, open, closed, settled.
  • Batch operations count against per-second write limits per item.

Error Handling

Standard HTTP error codes apply. The API returns JSON error bodies with descriptive messages. Implement retry with backoff for 429 (rate limited) and 5xx (server errors).

WebSocket Error Codes

CodeMeaning
1Unable to process message
2Params required
3Channels required
5Unknown command
8Unknown channel name
9Authentication required
14Market ticker required
16Market not found
17Internal error
18Command timeout

Full error code table: https://docs.kalshi.com/getting_started/quick_start_websockets.md


Example Project: Alph Bot

Alph Bot is an open-source automated trading bot that demonstrates a production-quality integration of the Kalshi API alongside Shipp for real-time sports data and Claude AI for probability estimation.

How Alph Bot Uses Kalshi

  1. Market discovery — Searches for Kalshi event contracts related to a live sports game (e.g., NBA point spreads, totals).
  2. Orderbook reading — Fetches orderbook data to determine current market-implied probabilities (prices in cents map directly to implied %).
  3. Edge detection — Compares Kalshi market prices against AI-estimated probabilities powered by Claude + Shipp real-time game data.
  4. Order execution — Places limit orders when sufficient edge is found, using Kelly Criterion for position sizing.
  5. Risk management — Enforces circuit breakers (max daily loss), position size limits, single-market exposure caps, and minimum account balance thresholds.

Alph Bot's Kalshi Configuration

From its .env.example:

ALPH_BOT_KALSHI_API_KEY_ID=abc123
ALPH_BOT_KALSHI_PRIVATE_KEY_PATH=./keys/kalshi-private.pem

# Strategy
ALPH_BOT_MIN_EDGE_PCT=5
ALPH_BOT_MIN_CONFIDENCE=medium
ALPH_BOT_KELLY_FRACTION=0.25

# Risk controls
ALPH_BOT_MAX_TOTAL_EXPOSURE_USD=10000
ALPH_BOT_MAX_POSITION_SIZE_USD=1000
ALPH_BOT_MAX_SINGLE_MARKET_PERCENT=20
ALPH_BOT_MAX_DAILY_LOSS_USD=500
ALPH_BOT_MAX_DAILY_TRADES=50
ALPH_BOT_MIN_ACCOUNT_BALANCE_USD=100

Try It

git clone https://gitlab.com/outsharp/shipp/alph-bot.git
cd alph-bot
cp .env.example .env
# Add your Kalshi, Shipp, and Anthropic API keys

yarn migrate

# Find a game to trade on
./index.ts available-games --sport NBA

# Run value betting in demo mode (uses Kalshi demo environment)
./index.ts value-bet -d --game <GAME_ID>

# Run in paper mode (no real orders executed)
./index.ts value-bet --paper --game <GAME_ID>

Warning: Trading on Kalshi involves real money when not in demo/paper mode. Always start with a demo account.

See the Alph Bot README for full setup instructions.


Versioning

The current API version is v2 under /trade-api/v2. Monitor the API Changelog for updates. SDK versions align with the OpenAPI spec and are generally published weekly.

Source Transparency

This detail page is rendered from real SKILL.md content. Trust labels are metadata-based hints, not a safety guarantee.

Related Skills

Related by shared tags or category signals.

General

google-news

No summary provided by upstream source.

Repository SourceNeeds Review
General

openfootball

No summary provided by upstream source.

Repository SourceNeeds Review
General

polymarket

No summary provided by upstream source.

Repository SourceNeeds Review
General

shipp

No summary provided by upstream source.

Repository SourceNeeds Review
kalshi | V50.AI