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:Authentication
WebSocket connections support both authenticated and unauthenticated usage:- Private channels (auth required):
orderbook_delta,fill,market_positions,communications,order_group_updates - Public channels (no auth required):
ticker,ticker_v2,trade,market_lifecycle_v2,multivariate
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:-
Create the message to sign:
- Generate the signature using your private key (see API Keys documentation)
- Include the headers when opening the WebSocket connection
Establishing a Connection
To connect to the WebSocket API, you need to:- Generate authentication headers (same as REST API)
- Create a WebSocket connection with those headers
- Handle the connection lifecycle
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
- Initial Connection: Establish WebSocket with authentication headers
- Subscribe: Send subscription commands for desired channels
- Receive Updates: Process incoming messages based on their type
- Handle Disconnects: Implement reconnection logic with exponential backoff
Error Handling
The server sends error messages in this format:WebSocket Error Codes
| Code | Error | Description |
|---|---|---|
| 1 | Unable to process message | General processing error |
| 2 | Params required | Missing params object in command |
| 3 | Channels required | Missing channels array in subscribe |
| 4 | Subscription IDs required | Missing sids in unsubscribe |
| 5 | Unknown command | Invalid command name |
| 6 | Already subscribed | Duplicate subscription attempt |
| 7 | Unknown subscription ID | Subscription ID not found |
| 8 | Unknown channel name | Invalid channel in subscribe |
| 9 | Authentication required | Private channel without auth |
| 10 | Channel error | Channel-specific error |
| 11 | Invalid parameter | Malformed parameter value |
| 12 | Exactly one subscription ID is required | For update_subscription |
| 13 | Unsupported action | Invalid action for update_subscription |
| 14 | Market Ticker required | Missing market specification (market_ticker or market_id) |
| 15 | Action required | Missing action in update_subscription |
| 16 | Market not found | Invalid market_ticker or market_id |
| 17 | Internal error | Server-side processing error |
| 18 | Command timeout | Server timed out while processing command |
| 19 | shard_factor must be > 0 | Invalid shard_factor |
| 20 | shard_factor is required when shard_key is set | Missing shard_factor when shard_key is set |
| 21 | shard_key must be >= 0 and < shard_factor | Invalid shard_key |
| 22 | shard_factor must be <= 100 | shard_factor too large |
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:- 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
- Replace
KEY_IDwith your API key ID - Replace
PRIVATE_KEY_PATHwith the path to your private key file - Replace
MARKET_TICKERwith any open market ticker - Run with Python 3.7+
Next Steps
- Review the WebSocket API Reference for detailed message specifications
- Explore Market Data Quick Start for REST API integration
- Check out our Demo Environment for testing