Skip to main content

Overview

Kalshi’s WebSocket API provides real-time updates for:
  • Order book changes
  • Trade executions
  • Market status updates
  • Fill notifications

Connection URL

Connect to the WebSocket endpoint at:
For the demo environment, use:
The existing shared WebSocket hosts, wss://api.elections.kalshi.com/trade-api/ws/v2 for production and wss://demo-api.kalshi.co/trade-api/ws/v2 for demo, remain supported. For the full endpoint list, see API Environments and Endpoints.

Authentication

WebSocket connections require authentication during the connection handshake. Once connected, channels fall into two groups:
  • Private channels (user-specific data): orderbook_delta, fill, market_positions, communications, order_group_updates
  • Public market-data channels (no additional channel-level auth): ticker, trade, market_lifecycle_v2, multivariate_market_lifecycle, multivariate
In other words, even channels that carry public market data still use the authenticated WebSocket session, but they do not impose additional per-channel authorization checks.
For detailed information about API key generation and request signing, see our API Keys documentation.

Required Headers

When establishing the WebSocket connection, include these headers:

Signing the WebSocket Request

The signature for WebSocket connections follows the same pattern as REST API requests:
  1. Create the message to sign:
  2. Generate the signature using your private key (see API Keys documentation)
  3. Include the headers when opening the WebSocket connection

Establishing a Connection

To connect to the WebSocket API, you need to:
  1. Generate authentication headers (same as REST API)
  2. Create a WebSocket connection with those headers
  3. Handle the connection lifecycle
Here’s how to establish an authenticated connection:

Subscribing to Data

Once connected, subscribe to channels by sending a subscription command:

Processing Messages

Handle incoming messages based on their type:

Connection Keep-Alive

The Python websockets library automatically handles WebSocket ping/pong frames to keep connections alive. No manual heartbeat handling is required. Learn more about automatic keepalive in the websockets documentation.Other WebSocket libraries may require manual ping/pong implementation.

Subscribing to Channels

Once connected, subscribe to specific data channels:

Subscribe to Ticker Updates

To receive real-time ticker updates for all markets:

Subscribe to Specific Markets

To subscribe to orderbook or trade updates for specific markets:

Connection Lifecycle

  1. Initial Connection: Establish WebSocket with authentication headers
  2. Subscribe: Send subscription commands for desired channels
  3. Receive Updates: Process incoming messages based on their type
  4. Handle Disconnects: Implement reconnection logic with exponential backoff

Error Handling

The server sends error messages in this format:

WebSocket Error Codes

Best Practices

Connection Management

  • Implement automatic reconnection with exponential backoff
  • Handle network interruptions gracefully
  • Use the websockets library’s built-in keepalive

Data Handling

  • Process messages asynchronously to avoid blocking
  • Implement proper error handling for malformed messages
  • Cache initial orderbook state before applying updates

Security

  • Never expose your private key in client-side code
  • Rotate API keys regularly
  • Use secure key storage practices

Performance

  • Subscribe only to markets you need
  • Implement message buffering for high-frequency updates
  • Consider using connection pooling for multiple subscriptions

Complete Example

Here’s a complete, runnable example that connects to the WebSocket API and subscribes to orderbook updates:
This example:
  • Establishes an authenticated WebSocket connection
  • Subscribes to orderbook updates for the specified market
  • Processes both the initial snapshot and incremental updates
  • Displays orderbook changes in real-time
To run this example:
  1. Replace KEY_ID with your API key ID
  2. Replace PRIVATE_KEY_PATH with the path to your private key file
  3. Replace MARKET_TICKER with any open market ticker
  4. Run with Python 3.7+

Next Steps