A Go client library for the Kalshi prediction markets trading API.
go get github.com/trencetech/kalshigopackage main
import (
"context"
"fmt"
"log"
"github.com/trencetech/kalshigo"
)
func main() {
// Create a client with API credentials
client := kalshigo.NewClient(kalshigo.ClientConfig{
APIKeyID: "your-api-key-id",
PrivateKey: "-----BEGIN RSA PRIVATE KEY-----\n...\n-----END RSA PRIVATE KEY-----",
})
ctx := context.Background()
// Get your portfolio balance
balance, err := client.GetBalance(ctx)
if err != nil {
log.Fatal(err)
}
fmt.Printf("Balance: %s\n", balance.Balance)
// Fetch available markets
markets, err := client.GetMarkets(ctx, kalshigo.GetMarketsParams{
Status: kalshigo.MarketStatusOpen,
Limit: 10,
})
if err != nil {
log.Fatal(err)
}
for _, market := range markets.Markets {
fmt.Printf("Market: %s - %s\n", market.Ticker, market.Title)
}
}- Complete coverage of the Kalshi Trade API v2
- RSA-based request signing for authentication
- Support for both production and demo environments
- Context-aware requests with cancellation support
- Structured logging with zap
- Fixed-point dollar representation for financial precision
client := kalshigo.NewClient(kalshigo.ClientConfig{
BaseURL: kalshigo.DefaultBaseURL, // optional, defaults to production API
APIKeyID: "your-api-key-id",
PrivateKey: "your-pem-encoded-private-key",
HTTPClient: &http.Client{Timeout: 30 * time.Second},
Logger: *zap.NewProduction(),
UserAgent: "my-trading-bot/1.0",
})The BaseURL is configurable and defaults to the production API if not specified:
// Production (default) - no need to specify BaseURL
client := kalshigo.NewClient(kalshigo.ClientConfig{
APIKeyID: "your-api-key-id",
PrivateKey: "your-pem-encoded-private-key",
})
// Demo environment
client := kalshigo.NewClient(kalshigo.ClientConfig{
BaseURL: kalshigo.DemoBaseURL,
APIKeyID: "your-api-key-id",
PrivateKey: "your-pem-encoded-private-key",
})
// Custom API URL
client := kalshigo.NewClient(kalshigo.ClientConfig{
BaseURL: "https://custom-api.example.com/trade-api/v2",
APIKeyID: "your-api-key-id",
PrivateKey: "your-pem-encoded-private-key",
})| Constant | Environment | URL |
|---|---|---|
DefaultBaseURL |
Production | https://api.elections.kalshi.com/trade-api/v2 |
DemoBaseURL |
Demo | https://demo-api.kalshi.co/trade-api/v2 |
GetBalance(ctx)
GetPositions(ctx, params)
GetSettlements(ctx, params)
GetFills(ctx, params)
GetPortfolioRestingOrderTotalValue(ctx)GetOrders(ctx, params)
GetOrder(ctx, orderID)
CreateOrder(ctx, request)
CancelOrder(ctx, orderID)
AmendOrder(ctx, orderID, request)
DecreaseOrder(ctx, orderID, request)
BatchCreateOrders(ctx, request)
BatchCancelOrders(ctx, request)
GetOrderQueuePositions(ctx, ticker)GetMarkets(ctx, params)
GetMarket(ctx, ticker)
GetMarketOrderbook(ctx, ticker, depth)
GetMarketCandlesticks(ctx, seriesTicker, ticker, params)
BatchGetMarketCandlesticks(ctx, seriesTicker, params)
GetTrades(ctx, params)GetEvents(ctx, params)
GetEvent(ctx, eventTicker)
GetEventMetadata(ctx, eventTicker)
GetEventCandlesticks(ctx, seriesTicker, eventTicker, params)
GetEventForecastPercentilesHistory(ctx, seriesTicker, eventTicker, params)
GetMultivariateEvents(ctx, params)GetExchangeStatus(ctx)
GetExchangeAnnouncements(ctx)
GetExchangeSchedule(ctx)
GetSeriesFeeChanges(ctx, params)CreateRFQ(ctx, request)
GetRFQs(ctx, params)
GetRFQ(ctx, rfqID)
DeleteRFQ(ctx, rfqID)
CreateQuote(ctx, request)
GetQuotes(ctx, params)
GetQuote(ctx, quoteID)
DeleteQuote(ctx, quoteID)
AcceptQuote(ctx, quoteID)
ConfirmQuote(ctx, quoteID, request)GetMultivariateEventCollections(ctx, params)
GetMultivariateEventCollection(ctx, mveCollectionTicker)
CreateMarketInMultivariateEventCollection(ctx, ticker, request)
LookupTickersInMultivariateEventCollection(ctx, ticker, request)
GetMultivariateEventCollectionLookupHistory(ctx, ticker, params)GetApiKeys(ctx)
CreateApiKey(ctx, request)
GenerateApiKey(ctx, request)
DeleteApiKey(ctx, keyID)// Create a limit order
order, err := client.CreateOrder(ctx, kalshigo.CreateOrderRequest{
Ticker: "INXD-25MAR21-B4300",
Action: kalshigo.OrderActionBuy,
Side: kalshigo.OrderSideYes,
Type: kalshigo.OrderTypeLimit,
Count: 10,
YesPrice: 50, // Price in cents
Expiration: time.Now().Add(24 * time.Hour),
})
// Create a market order
order, err := client.CreateOrder(ctx, kalshigo.CreateOrderRequest{
Ticker: "INXD-25MAR21-B4300",
Action: kalshigo.OrderActionBuy,
Side: kalshigo.OrderSideYes,
Type: kalshigo.OrderTypeMarket,
Count: 5,
})Kalshi uses RSA-based request signing. You need:
- An API Key ID from your Kalshi account settings
- An RSA private key (PEM format) associated with that API key
The client automatically signs all authenticated requests with:
KALSHI-ACCESS-KEY: Your API key IDKALSHI-ACCESS-SIGNATURE: RSA-PSS signature of the requestKALSHI-ACCESS-TIMESTAMP: Current timestamp in milliseconds
The library provides typed constants for common values:
// Order status
kalshigo.OrderStatusResting
kalshigo.OrderStatusCanceled
kalshigo.OrderStatusExecuted
// Order sides
kalshigo.OrderSideYes
kalshigo.OrderSideNo
// Order actions
kalshigo.OrderActionBuy
kalshigo.OrderActionSell
// Order types
kalshigo.OrderTypeLimit
kalshigo.OrderTypeMarket
// Market status
kalshigo.MarketStatusOpen
kalshigo.MarketStatusClosed
kalshigo.MarketStatusSettled
// Market types
kalshigo.MarketTypeBinary
kalshigo.MarketTypeScalarAPI errors are returned as *kalshigo.ErrorResponse:
order, err := client.CreateOrder(ctx, request)
if err != nil {
if apiErr, ok := err.(*kalshigo.ErrorResponse); ok {
fmt.Printf("API Error: %s (code: %s)\n", apiErr.Message, apiErr.Code)
} else {
fmt.Printf("Error: %v\n", err)
}
}- go.uber.org/zap - Structured logging
- Go 1.21 or later
See LICENSE for details.