KalshiSharp 1.2.0
There is a newer version of this package available.
See the version list below for details.
See the version list below for details.
dotnet add package KalshiSharp --version 1.2.0
NuGet\Install-Package KalshiSharp -Version 1.2.0
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="KalshiSharp" Version="1.2.0" />
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="KalshiSharp" Version="1.2.0" />
<PackageReference Include="KalshiSharp" />
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add KalshiSharp --version 1.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
#r "nuget: KalshiSharp, 1.2.0"
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package KalshiSharp@1.2.0
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=KalshiSharp&version=1.2.0
#tool nuget:?package=KalshiSharp&version=1.2.0
The NuGet Team does not provide support for this client. Please contact its maintainers for support.
KalshiSharp
A production-grade .NET 8 SDK for the Kalshi prediction market API.
Features
- Core API Coverage: REST clients for exchange, markets, events, orders, portfolio, users, and historical data
- Real-time WebSocket: Order book, ticker, trade, fill, position, and user-order subscriptions with auto-reconnect
- Async-First: All operations are async/await with proper cancellation support
- Thread-Safe: Safe for concurrent use from multiple threads
- Strongly Typed: Complete type coverage with nullable reference types enabled
- Automatic Signing: RSA-PSS request signing handled transparently
- Resilience: Built-in retry with exponential backoff, rate limiting, and circuit breaker
- Observability: OpenTelemetry tracing and metrics integration
- Dependency Injection: First-class support for
IServiceCollection
Installation
dotnet add package KalshiSharp
Quick Start
Basic Usage
using KalshiSharp.Configuration;
using KalshiSharp.Rest;
// Create a client with your API credentials
using var client = new KalshiClient(new KalshiClientOptions
{
ApiKey = "your-api-key",
ApiSecret = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----", // RSA private key in PEM format
Environment = KalshiEnvironment.Demo // or Production
});
var status = await client.Exchange.GetStatusAsync();
Console.WriteLine($"Trading Active: {status.TradingActive}");
With Dependency Injection (ASP.NET Core)
For applications using dependency injection:
using KalshiSharp.Configuration;
using KalshiSharp.DependencyInjection;
// In Program.cs or Startup.cs
services.AddKalshiClient(options =>
{
options.ApiKey = configuration["Kalshi:ApiKey"]!;
options.ApiSecret = configuration["Kalshi:ApiSecret"]!;
options.Environment = KalshiEnvironment.Production;
});
// Inject IKalshiClient directly
public class MyService(IKalshiClient client)
{
public async Task DoSomethingAsync()
{
var markets = await client.Markets.ListMarketsAsync();
}
}
Get Exchange Schedule
var schedule = await client.Exchange.GetScheduleAsync();
Console.WriteLine($"Standard hours entries: {schedule.Schedule.StandardHours.Count}");
Console.WriteLine($"Maintenance windows: {schedule.Schedule.MaintenanceWindows.Count}");
List Markets with Pagination
using KalshiSharp.Models.Enums;
using KalshiSharp.Models.Requests;
var query = new MarketQuery
{
Limit = 10,
Status = MarketStatus.Active
};
var page1 = await client.Markets.ListMarketsAsync(query);
foreach (var market in page1.Items)
{
Console.WriteLine($"{market.Ticker}: {market.Title}");
Console.WriteLine($" Yes: ${market.YesBidDollars} / ${market.YesAskDollars}");
}
// Fetch next page
if (page1.HasMore)
{
var page2 = await client.Markets.ListMarketsAsync(query with { Cursor = page1.Cursor });
}
Get Order Book
var orderBook = await client.Markets.GetOrderBookAsync("TICKER-ABC");
Console.WriteLine($"Yes levels: {orderBook.OrderbookFp.YesDollars.Count}");
Console.WriteLine($"No levels: {orderBook.OrderbookFp.NoDollars.Count}");
// Each level is [fixed-point dollar price, fixed-point quantity]
foreach (var level in orderBook.OrderbookFp.YesDollars)
{
Console.WriteLine($" ${level[0]}: {level[1]} contracts");
}
Place and Cancel Orders
using KalshiSharp.Models.Requests;
// Create an order through the current V2 event-order API
var request = new CreateOrderRequestV2
{
Ticker = "TICKER-ABC",
Side = OrderBookSide.Bid,
Count = "10.00",
Price = "0.4500",
TimeInForce = EventOrderTimeInForce.GoodTillCanceled,
SelfTradePreventionType = SelfTradePreventionType.TakerAtCross,
ClientOrderId = Guid.NewGuid().ToString("N"),
ExchangeIndex = -1 // auto-route by ticker
};
var ordersV2 = client.OrdersV2
?? throw new NotSupportedException("This client does not provide the V2 order capability.");
var order = await ordersV2.CreateOrderAsync(request);
Console.WriteLine($"Order ID: {order.OrderId}, remaining: {order.RemainingCount}");
// Cancel the order
var cancelled = await ordersV2.CancelOrderAsync(order.OrderId, new CancelOrderQueryV2
{
ExchangeIndex = -1,
MarketTicker = request.Ticker
});
Portfolio Information
// Get balance
var balance = await client.Portfolio.GetBalanceAsync();
Console.WriteLine($"Balance: ${balance.BalanceDollars}");
// List positions
var positions = await client.Portfolio.ListPositionsAsync();
foreach (var position in positions.Items)
{
Console.WriteLine($"{position.Ticker}: {position.PositionFp} contracts");
}
// List fills
var fills = await client.Portfolio.ListFillsAsync();
Historical Data
Historical access is explicit. Existing live methods are never rerouted automatically.
var historical = client.Historical
?? throw new NotSupportedException("This client does not provide historical data access.");
var cutoff = await historical.GetCutoffAsync();
Console.WriteLine($"Markets before {cutoff.MarketSettledTs:u} are historical");
var archived = await historical.ListMarketsAsync(new HistoricalMarketQuery
{
SeriesTicker = "KXHIGHNY",
Limit = 100
});
WebSocket Real-Time Updates
using KalshiSharp.Configuration;
using KalshiSharp.WebSockets;
using KalshiSharp.WebSockets.Subscriptions;
using KalshiSharp.Models.WebSocket;
// Create WebSocket client
await using var wsClient = new KalshiWebSocketClient(new KalshiClientOptions
{
ApiKey = "your-api-key",
ApiSecret = "-----BEGIN PRIVATE KEY-----\n...\n-----END PRIVATE KEY-----",
Environment = KalshiEnvironment.Production
});
// Connect and subscribe
await wsClient.ConnectAsync();
await wsClient.SubscribeAsync(OrderBookSubscription.ForMarkets("TICKER-ABC"));
await wsClient.SubscribeAsync(TradeSubscription.ForMarkets("TICKER-ABC"));
// Process messages
await foreach (var message in wsClient.Messages)
{
switch (message)
{
case OrderBookSnapshot snapshot:
Console.WriteLine($"Snapshot: {snapshot.Message.MarketTicker}");
break;
case OrderBookUpdate update:
Console.WriteLine($"Delta: ${update.Message.PriceDollars}, {update.Message.DeltaFp}");
break;
case TradeUpdate trade:
Console.WriteLine($"Trade: {trade.Message.CountFp} @ ${trade.Message.YesPriceDollars}");
break;
}
}
Error Handling
The SDK provides strongly-typed exceptions for different error scenarios:
using KalshiSharp.Errors;
try
{
var market = await client.Markets.GetMarketAsync("INVALID");
}
catch (KalshiNotFoundException)
{
Console.WriteLine("Market not found");
}
catch (KalshiAuthException)
{
Console.WriteLine("Invalid credentials");
}
catch (KalshiRateLimitException ex)
{
Console.WriteLine($"Rate limited, retry after: {ex.RetryAfter}");
}
catch (KalshiValidationException ex)
{
foreach (var error in ex.ValidationErrors ?? new())
{
Console.WriteLine($"{error.Key}: {string.Join(", ", error.Value)}");
}
}
catch (KalshiException ex)
{
Console.WriteLine($"API error: {ex.StatusCode} - {ex.Message}");
}
Configuration Options
| Option | Default | Description |
|---|---|---|
ApiKey |
Required | Your Kalshi API key ID |
ApiSecret |
Required | Your RSA private key in PEM format |
Environment |
Production |
Production or Demo |
BaseUri |
Auto | Override base URI |
Timeout |
30s | HTTP request timeout |
ClockSkewTolerance |
30s | Tolerance for timestamp validation |
EnableRateLimiting |
true | Enable client-side rate limiting |
RateLimits |
Basic tier: read burst 200, write burst 100 | Separate read, unscoped-write, and shard-write token budgets; override after checking account limits |
Project Structure
KalshiSharp/
├── KalshiSharp/ # Main SDK library
│ ├── Auth/ # RSA-PSS request signing
│ ├── Configuration/ # Client options
│ ├── DependencyInjection/ # IServiceCollection extensions
│ ├── Errors/ # Exception types
│ ├── Http/ # HTTP client pipeline
│ ├── Models/ # DTOs and enums
│ │ ├── Enums/
│ │ ├── Requests/
│ │ ├── Responses/
│ │ └── WebSocket/
│ ├── RateLimiting/ # Token bucket limiter
│ ├── Rest/ # REST API clients
│ │ ├── Exchange/
│ │ ├── Historical/
│ │ ├── Markets/
│ │ ├── Events/
│ │ ├── Orders/
│ │ ├── Portfolio/
│ │ └── Users/
│ ├── Serialization/ # JSON converters
│ └── WebSockets/ # WebSocket client
│ ├── Connections/
│ ├── ReconnectPolicy/
│ └── Subscriptions/
├── KalshiSharp.Tests/ # Unit and integration tests
└── KalshiSharp.Examples/ # Example console app
Running Examples
# Set credentials via user-secrets (recommended)
cd KalshiSharp.Examples
dotnet user-secrets set "Kalshi:ApiKey" "your-api-key-id"
dotnet user-secrets set "Kalshi:ApiSecret" "-----BEGIN PRIVATE KEY-----
...your PEM key...
-----END PRIVATE KEY-----"
# Or via environment variables (double underscore for nesting)
export KALSHI__APIKEY="your-api-key-id"
export KALSHI__APISECRET="-----BEGIN PRIVATE KEY-----..."
# Run specific example
dotnet run --project KalshiSharp.Examples -- exchange
dotnet run --project KalshiSharp.Examples -- markets
dotnet run --project KalshiSharp.Examples -- order
dotnet run --project KalshiSharp.Examples -- websocket
# Run all examples
dotnet run --project KalshiSharp.Examples -- all
Requirements
- .NET 8.0 or later
- Valid Kalshi API credentials (obtain from Kalshi API Settings)
License
MIT
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net8.0 is compatible. net8.0-android was computed. net8.0-browser was computed. net8.0-ios was computed. net8.0-maccatalyst was computed. net8.0-macos was computed. net8.0-tvos was computed. net8.0-windows was computed. net9.0 was computed. net9.0-android was computed. net9.0-browser was computed. net9.0-ios was computed. net9.0-maccatalyst was computed. net9.0-macos was computed. net9.0-tvos was computed. net9.0-windows was computed. net10.0 was computed. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.
-
net8.0
- Microsoft.Extensions.Http (>= 8.0.1)
- Microsoft.Extensions.Http.Resilience (>= 8.10.0)
- Microsoft.Extensions.Logging.Abstractions (>= 8.0.2)
- Microsoft.Extensions.Options (>= 8.0.2)
- Polly.Core (>= 8.5.0)
- System.Threading.RateLimiting (>= 8.0.0)
NuGet packages
This package is not used by any NuGet packages.
GitHub repositories
This package is not used by any popular GitHub repositories.