skills/kalshi/SKILL.md
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.
npx skillsauth add outsharp/shipp-skills kalshiInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
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.
| Term | Definition | |---|---| | Market | A single binary outcome contract (Yes / No) with prices in cents (1–99¢). | | Event | A collection of related markets representing a real-world occurrence (e.g., an election, a weather reading). | | Series | A template for recurring events that share the same structure and rules (e.g., "Daily Highest Temp in NYC"). | | Orderbook | Bids only — in binary markets a YES bid at X¢ is equivalent to a NO ask at (100−X)¢. | | Fill | A matched trade on one of your orders. | | Settlement | The final resolution of a market (Yes or No) after determination. | | Multivariate Event | A combo event created dynamically from a multivariate event collection. |
Full glossary: https://docs.kalshi.com/getting_started/terms.md
| Environment | REST API | WebSocket |
|---|---|---|
| Production | https://api.elections.kalshi.com/trade-api/v2 | wss://api.elections.kalshi.com/trade-api/ws/v2 |
| Demo | https://demo-api.kalshi.co/trade-api/v2 | wss://demo-api.kalshi.co/trade-api/ws/v2 |
Note: Despite the
electionssubdomain, the production URL serves ALL Kalshi markets — economics, weather, tech, entertainment, etc.
Demo environment info: https://docs.kalshi.com/getting_started/demo_env.md
All detailed examples, request/response schemas, and walkthroughs live in the official docs. Always consult these before building:
| Resource | URL | |---|---| | Full documentation index (llms.txt) | https://docs.kalshi.com/llms.txt | | Introduction | https://docs.kalshi.com/welcome/index.md | | Making your first request | https://docs.kalshi.com/getting_started/making_your_first_request.md | | Quick Start: Market Data | https://docs.kalshi.com/getting_started/quick_start_market_data.md | | Quick Start: Authenticated Requests | https://docs.kalshi.com/getting_started/quick_start_authenticated_requests.md | | Quick Start: Create Your First Order | https://docs.kalshi.com/getting_started/quick_start_create_order.md | | Quick Start: WebSockets | https://docs.kalshi.com/getting_started/quick_start_websockets.md | | API Keys guide | https://docs.kalshi.com/getting_started/api_keys.md | | Rate Limits & Tiers | https://docs.kalshi.com/getting_started/rate_limits.md | | Pagination | https://docs.kalshi.com/getting_started/pagination.md | | Orderbook Responses | https://docs.kalshi.com/getting_started/orderbook_responses.md | | Historical Data | https://docs.kalshi.com/getting_started/historical_data.md | | Subpenny Pricing | https://docs.kalshi.com/getting_started/subpenny_pricing.md | | Fixed-Point Contracts | https://docs.kalshi.com/getting_started/fixed_point_contracts.md | | OpenAPI Spec (YAML) | https://docs.kalshi.com/openapi.yaml | | API Changelog | https://docs.kalshi.com/changelog/index.md | | Kalshi Platform | https://kalshi.com | | Demo Platform | https://demo.kalshi.co |
Kalshi uses RSA-PSS signed requests (not Bearer tokens). Every authenticated request requires three headers:
| Header | Value |
|---|---|
| KALSHI-ACCESS-KEY | Your API Key ID |
| KALSHI-ACCESS-TIMESTAMP | Current Unix timestamp in milliseconds |
| KALSHI-ACCESS-SIGNATURE | Base64-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.
Full guide: https://docs.kalshi.com/getting_started/api_keys.md
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,
}
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,
};
}
Kalshi provides official SDKs. Prefer these for production integrations:
| SDK | Install | Docs |
|---|---|---|
| Python (sync) | pip install kalshi_python_sync | https://docs.kalshi.com/sdks/python/quickstart.md |
| Python (async) | pip install kalshi_python_async | https://docs.kalshi.com/sdks/python/quickstart.md |
| TypeScript | npm install kalshi-typescript | https://docs.kalshi.com/sdks/typescript/quickstart.md |
The old
kalshi-pythonpackage is deprecated. Migrate tokalshi_python_syncorkalshi_python_async.
SDK overview: https://docs.kalshi.com/sdks/overview.md
For production applications, consider generating your own client from the OpenAPI spec.
| Tier | Read | Write | |---|---|---| | Basic | 20/s | 10/s | | Advanced | 30/s | 30/s | | Premier | 100/s | 100/s | | Prime | 400/s | 400/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
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
Below is a summary organized by domain. For full request/response schemas, see the linked docs or browse https://docs.kalshi.com/llms.txt.
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /markets | GET | No | List markets with filters (status, series, timestamps). Docs: Get Markets |
| /markets/{ticker} | GET | No | Get a single market by ticker. Docs: Get Market |
| /markets/{ticker}/orderbook | GET | No | Get current orderbook (yes bids + no bids). Docs: Get Market Orderbook |
| /markets/{ticker}/candlesticks | GET | No | Candlestick data (1m, 1h, 1d). Docs: Get Market Candlesticks |
| /markets/candlesticks | POST | No | Batch candlesticks for up to 100 tickers. Docs: Batch Get Market Candlesticks |
| /markets/trades | GET | No | All public trades. Docs: Get Trades |
| /series/{ticker} | GET | No | Get a series. Docs: Get Series |
| /series | GET | No | List series. Docs: Get Series List |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /events | GET | No | List events (excludes multivariate). Docs: Get Events |
| /events/{ticker} | GET | No | Get a single event. Docs: Get Event |
| /events/{ticker}/metadata | GET | No | Event metadata only. Docs: Get Event Metadata |
| /events/{ticker}/candlesticks | GET | No | Aggregated event candlesticks. Docs: Get Event Candlesticks |
| /events/{ticker}/forecast/percentile_history | GET | No | Forecast percentile history. Docs: Get Event Forecast Percentile History |
| /events/multivariate | GET | No | List multivariate events. Docs: Get Multivariate Events |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /portfolio/orders | POST | Yes | Create an order. Docs: Create Order |
| /portfolio/orders | GET | Yes | List your orders (resting/canceled/executed). Docs: Get Orders |
| /portfolio/orders/{order_id} | GET | Yes | Get a single order. Docs: Get Order |
| /portfolio/orders/{order_id} | DELETE | Yes | Cancel an order. Docs: Cancel Order |
| /portfolio/orders/{order_id}/amend | POST | Yes | Amend price/count. Docs: Amend Order |
| /portfolio/orders/{order_id}/decrease | POST | Yes | Decrease contract count. Docs: Decrease Order |
| /portfolio/orders/{order_id}/queue_position | GET | Yes | Queue position. Docs: Get Order Queue Position |
| /portfolio/orders/queue_positions | GET | Yes | Queue positions for all resting orders. Docs: Get Queue Positions for Orders |
| /portfolio/orders/batched | POST | Yes | Batch create (up to 20). Docs: Batch Create Orders |
| /portfolio/orders/batched | DELETE | Yes | Batch cancel (up to 20). Docs: Batch Cancel Orders |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /portfolio/balance | GET | Yes | Account balance (cents). Docs: Get Balance |
| /portfolio/positions | GET | Yes | Market positions. Docs: Get Positions |
| /portfolio/fills | GET | Yes | Your fills. Docs: Get Fills |
| /portfolio/settlements | GET | Yes | Settlement history. Docs: Get Settlements |
| /portfolio/resting_order_value | GET | Yes | Total resting order value (FCM). Docs: Get Total Resting Order Value |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /portfolio/subaccounts | POST | Yes | Create subaccount (max 32). Docs: Create Subaccount |
| /portfolio/subaccounts/balances | GET | Yes | All subaccount balances. Docs: Get All Subaccount Balances |
| /portfolio/subaccounts/transfers | GET | Yes | Subaccount transfer history. Docs: Get Subaccount Transfers |
| /portfolio/subaccounts/transfer | POST | Yes | Transfer between subaccounts. Docs: Transfer Between Subaccounts |
Order groups apply a rolling 15-second contracts limit; when hit, all orders in the group are auto-cancelled.
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /portfolio/order_groups | POST | Yes | Create group. Docs: Create Order Group |
| /portfolio/order_groups | GET | Yes | List groups. Docs: Get Order Groups |
| /portfolio/order_groups/{id} | GET | Yes | Get group. Docs: Get Order Group |
| /portfolio/order_groups/{id} | DELETE | Yes | Delete group. Docs: Delete Order Group |
| /portfolio/order_groups/{id}/reset | POST | Yes | Reset counter. Docs: Reset Order Group |
| /portfolio/order_groups/{id}/trigger | POST | Yes | Manually trigger. Docs: Trigger Order Group |
| /portfolio/order_groups/{id}/limit | PUT | Yes | Update limit. Docs: Update Order Group Limit |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /communications/id | GET | Yes | Get your comms ID. Docs: Get Communications ID |
| /rfqs | POST | Yes | Create RFQ (max 100 open). Docs: Create RFQ |
| /rfqs | GET | Yes | List RFQs. Docs: Get RFQs |
| /rfqs/{id} | GET | Yes | Get RFQ. Docs: Get RFQ |
| /rfqs/{id} | DELETE | Yes | Delete RFQ. Docs: Delete RFQ |
| /quotes | POST | Yes | Create quote. Docs: Create Quote |
| /quotes | GET | Yes | List quotes. Docs: Get Quotes |
| /quotes/{id} | GET | Yes | Get quote. Docs: Get Quote |
| /quotes/{id} | DELETE | Yes | Delete quote. Docs: Delete Quote |
| /quotes/{id}/accept | POST | Yes | Accept quote. Docs: Accept Quote |
| /quotes/{id}/confirm | POST | Yes | Confirm quote. Docs: Confirm Quote |
Historical data is for archived markets, orders, and fills that have moved past cutoff timestamps.
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /historical/cutoff_timestamps | GET | Yes | Cutoff boundaries. Docs: Get Historical Cutoff Timestamps |
| /historical/markets | GET | Yes | Archived markets. Docs: Get Historical Markets |
| /historical/markets/{ticker} | GET | Yes | Single archived market. Docs: Get Historical Market |
| /historical/markets/{ticker}/candlesticks | GET | Yes | Archived candlesticks. Docs: Get Historical Market Candlesticks |
| /historical/fills | GET | Yes | Archived fills. Docs: Get Historical Fills |
| /historical/orders | GET | Yes | Archived orders. Docs: Get Historical Orders |
Historical data guide: https://docs.kalshi.com/getting_started/historical_data.md
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /multivariate/collections | GET | No | List collections. Docs: Get Multivariate Event Collections |
| /multivariate/collections/{ticker} | GET | No | Get collection. Docs: Get Multivariate Event Collection |
| /multivariate/collections/{ticker}/markets | POST | Yes | Create market in collection. Docs: Create Market In Multivariate Event Collection |
| /multivariate/collections/{ticker}/lookup | GET | No | Lookup tickers. Docs: Lookup Tickers For Market In Multivariate Event Collection |
| /multivariate/collections/{ticker}/lookup_history | GET | No | Recent lookups. Docs: Get Multivariate Event Collection Lookup History |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /milestones | GET | No | List milestones. Docs: Get Milestones |
| /milestones/{id} | GET | No | Get milestone. Docs: Get Milestone |
| /structured_targets | GET | No | List structured targets. Docs: Get Structured Targets |
| /structured_targets/{id} | GET | No | Get structured target. Docs: Get Structured Target |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /live_data/{milestone_id} | GET | No | Live data for milestone. Docs: Get Live Data |
| /live_data | GET | No | Multiple milestones. Docs: Get Multiple Live Data |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /search/sports/filters | GET | No | Sport filters. Docs: Get Filters for Sports |
| /search/tags | GET | No | Tags by category. Docs: Get Tags for Series Categories |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /exchange/status | GET | No | Exchange status. Docs: Get Exchange Status |
| /exchange/schedule | GET | No | Exchange schedule. Docs: Get Exchange Schedule |
| /exchange/announcements | GET | No | Announcements. Docs: Get Exchange Announcements |
| /exchange/data_timestamp | GET | Yes | Data freshness timestamp. Docs: Get User Data Timestamp |
| /exchange/series_fee_changes | GET | No | Fee changes. Docs: Get Series Fee Changes |
| /account/api_limits | GET | Yes | Your rate limit tier. Docs: Get Account API Limits |
| /account/api_keys | GET | Yes | List API keys. Docs: Get API Keys |
| /account/api_keys | POST | Yes | Create API key. Docs: Create API Key |
| /account/api_keys/generate | POST | Yes | Generate key pair. Docs: Get API Keys |
| /account/api_keys/{id} | DELETE | Yes | Delete API key. Docs: Delete API Key |
| Endpoint | Method | Auth | Description |
|---|---|---|---|
| /incentives | GET | No | List incentives. Docs: Get Incentives |
A single authenticated WebSocket connection provides real-time streaming. Subscribe to channels by sending JSON commands.
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.
| Channel | Auth Required | Description | Docs |
|---|---|---|---|
| ticker | No* | Market price/volume/OI updates | Market Ticker |
| trade | No* | Public trade notifications | Public Trades |
| market_lifecycle_v2 | No* | Market/event state changes | Market & Event Lifecycle |
| multivariate | No* | Multivariate lookup notifications | Multivariate Lookups |
| orderbook_delta | Yes | Real-time orderbook updates | Orderbook Updates |
| fill | Yes | Your fill notifications | User Fills |
| order | Yes | Your order updates | User Orders |
| market_positions | Yes | Your position updates | Market Positions |
| communications | Yes | RFQ/quote notifications | Communications |
| order_group_updates | Yes | Order group lifecycle | Order Group Updates |
*The connection itself always requires authentication, even for public channels.
{
"id": 1,
"cmd": "subscribe",
"params": {
"channels": ["ticker", "orderbook_delta"],
"market_tickers": ["KXHIGHNY-24JAN01-T60"]
}
}
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
Kalshi orderbooks return bids only (no asks). In binary markets:
Each entry is [price, quantity] sorted ascending. The best bid is the last element.
Spread calculation:
100 - best_no_bidFull guide: https://docs.kalshi.com/getting_started/orderbook_responses.md
Kalshi also supports the Financial Information eXchange (FIX) protocol for low-latency trading:
| Topic | Docs | |---|---| | Overview | https://docs.kalshi.com/fix/index.md | | Connectivity | https://docs.kalshi.com/fix/connectivity.md | | Session Management | https://docs.kalshi.com/fix/session-management.md | | Order Entry | https://docs.kalshi.com/fix/order-entry.md | | Order Groups | https://docs.kalshi.com/fix/order-groups.md | | Drop Copy | https://docs.kalshi.com/fix/drop-copy.md | | Market Settlement | https://docs.kalshi.com/fix/market-settlement.md | | RFQ Messages | https://docs.kalshi.com/fix/rfq-messages.md | | Error Handling | https://docs.kalshi.com/fix/error-handling.md | | Subpenny Pricing | https://docs.kalshi.com/fix/subpenny-pricing.md |
curl -s "https://api.elections.kalshi.com/trade-api/v2/markets?series_ticker=KXHIGHNY&status=open" | jq '.markets[] | {ticker, title, yes_price, volume}'
curl -s "https://api.elections.kalshi.com/trade-api/v2/markets/KXHIGHNY-24JAN01-T60/orderbook" | jq '.orderbook'
# 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
llms.txt first: https://docs.kalshi.com/llms.txt has every endpoint and guide.? before signing.cursor and loop until exhausted.unopened, open, closed, settled.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).
| Code | Meaning | |---|---| | 1 | Unable to process message | | 2 | Params required | | 3 | Channels required | | 5 | Unknown command | | 8 | Unknown channel name | | 9 | Authentication required | | 14 | Market ticker required | | 16 | Market not found | | 17 | Internal error | | 18 | Command timeout |
Full error code table: https://docs.kalshi.com/getting_started/quick_start_websockets.md
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.
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
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.
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.
development
Shipp is a real-time data connector. Use it to fetch authoritative, changing external data (e.g., sports schedules, live events) via the Shipp API.
development
Polymarket is a decentralized prediction market platform built on Polygon. Use this skill to interact with the Polymarket APIs for market discovery, price data, order placement, portfolio management, WebSocket streaming, and bridging/withdrawals.
development
openfootball (football.json) is a free, open, public domain collection of football (soccer) match data in JSON format. It covers major leagues worldwide including the English Premier League, Bundesliga, La Liga, Serie A, Ligue 1, World Cup, Euro, and Champions League. Use this skill to fetch historical and current season fixtures, results, and scores. No API key or authentication is required.
development
The NOAA Weather.gov API provides access to National Weather Service forecasts, alerts, observations, radar data, and more for the United States. Use this skill to fetch weather forecasts, active alerts, station observations, and zone data. No API key is required — just a User-Agent header.