Skip to main content

Crate kalshi_fast

Crate kalshi_fast 

Source
Expand description

§kalshi-fast-rs

High-performance async Rust client for the Kalshi prediction markets API.

§Features

  • OpenAPI parity — full REST operation coverage for the current docs snapshot
  • AsyncAPI parity — WebSocket commands, responses, and user_orders
  • Pagination helpers — page-level (CursorPager) and item-level (stream_*) iteration
  • REST reliability controls — retry/backoff/jitter with 429 Retry-After support
  • Transport builder — timeout/connect-timeout/headers/user-agent/proxy/custom client
  • RSA-PSS authentication — secure signing for private endpoints

§Quick Start: REST (Builder + Retry)

use std::time::Duration;
use kalshi_fast::{
    KalshiEnvironment, KalshiRestClient, RateLimitConfig, RetryConfig,
};

let client = KalshiRestClient::builder(KalshiEnvironment::demo())
    .with_rate_limit_config(RateLimitConfig { read_rps: 30, write_rps: 15 })
    .with_retry_config(RetryConfig {
        max_retries: 4,
        base_delay: Duration::from_millis(200),
        max_delay: Duration::from_secs(2),
        jitter: 0.2,
        retry_non_idempotent: false,
    })
    .build()?;

let status = client.get_exchange_status().await?;
println!("exchange_active={}", status.exchange_active);

§Quick Start: WebSocket

use kalshi_fast::{
    KalshiAuth, KalshiEnvironment, KalshiWsClient, WsChannel,
    WsDataMessage, WsEvent, WsMessage, WsReconnectConfig, WsSubscriptionParams,
};

let auth = KalshiAuth::from_pem_file(
    std::env::var("KALSHI_KEY_ID").unwrap(),
    std::env::var("KALSHI_PRIVATE_KEY_PATH").unwrap(),
)?;

let mut ws = KalshiWsClient::connect_authenticated(
    KalshiEnvironment::demo(),
    auth,
    WsReconnectConfig::default(),
).await?;

ws.subscribe(WsSubscriptionParams {
    channels: vec![WsChannel::UserOrders],
    ..Default::default()
}).await?;

loop {
    match ws.next_event().await? {
        WsEvent::Message(WsMessage::Data(WsDataMessage::UserOrder { msg, .. })) => {
            println!("order={} status={:?}", msg.order_id, msg.status);
        }
        WsEvent::Reconnected { attempt } => println!("Reconnected (attempt {})", attempt),
        WsEvent::Disconnected { .. } => break,
        _ => {}
    }
}

§Authentication

Private endpoints (portfolio, orders, WebSocket fills) require RSA-PSS signing. Load your key with KalshiAuth::from_pem_file or KalshiAuth::from_pem_str:

// From a .key file on disk
let auth = KalshiAuth::from_pem_file("your-key-id", "/path/to/private.key")?;

// Or from PEM content directly (supports PKCS#8 and PKCS#1)
let pem = std::fs::read_to_string("/path/to/private.key").unwrap();
let auth = KalshiAuth::from_pem_str("your-key-id", &pem)?;

Environment variables used by the examples:

  • KALSHI_KEY_ID — your API key ID
  • KALSHI_PRIVATE_KEY_PATH — path to your RSA private key (PEM format)

§Pagination

Page-level with CursorPager:

let mut pager = client.markets_pager(GetMarketsParams::default());
while let Some(page) = pager.next_page().await? {
    for market in page {
        println!("{}", market.ticker);
    }
}

Item-level with streams:

use futures::stream::TryStreamExt;

let markets: Vec<Market> = client
    .stream_markets(GetMarketsParams::default(), Some(250))
    .try_collect()
    .await?;

§WebSocket Reconnection

KalshiWsClient handles reconnection automatically with exponential backoff and resubscribes to active channels. Configure via WsReconnectConfig:

FieldDefaultDescription
max_retriesNone (unlimited)Maximum reconnection attempts
base_delay250 msFirst backoff delay
max_delay30 sUpper bound on backoff
jitter0.2Random jitter factor
resubscribetrueResubscribe to active channels on reconnect

Connection lifecycle events are exposed through WsEvent:

Note: Sequence resync is not automatic; callers must handle any gaps.

§Performance

Optimized for low-latency algorithmic trading:

  • Deferred JSON parsing — uses serde_json::RawValue to skip parsing unused fields
  • Zero-copy message parsing — binary WebSocket frames parsed with from_slice
  • Split read/write streams — no lock contention on WebSocket operations

Re-exports§

pub use auth::KalshiAuth;
pub use auth::KalshiAuthHeaders;
pub use env::KalshiEnvironment;
pub use env::REST_PREFIX;
pub use env::WS_PATH;
pub use error::KalshiError;
pub use rest::CursorPager;
pub use rest::KalshiRestClient;
pub use rest::KalshiRestClientBuilder;
pub use rest::RateLimitConfig;
pub use rest::RateLimitTier;
pub use rest::RetryConfig;
pub use ws::KalshiWsClient;
pub use ws::KalshiWsLowLevelClient;
pub use ws::WsEvent;
pub use ws::WsEventReceiver;
pub use ws::WsReaderConfig;
pub use ws::WsReaderMode;
pub use ws::WsReconnectConfig;
pub use rest::types::*;
pub use types::*;
pub use ws::types::*;

Modules§

auth
env
error
rest
REST client for the Kalshi API.
types
ws
WebSocket client for the Kalshi real-time streaming API.