Overview
The SDK provides methods to query market information, event metadata, and system configuration.
To avoid ambiguity, we denote the smallest possible multiple of USDC (0.000001 USDC) as one uusdc,
which stands for µUSDC (micro-USDC).
List & Search Events
Search and filter events from the Bison event cache. Events are synced from Kalshi hourly.
getEvents
async getEvents(params?: {
series_ticker?: string;
limit?: string;
query?: string;
}): Promise<GetEventsResponse>
Parameters
All parameters are optional. Omit all parameters to retrieve all events.
Filter by Kalshi series ticker (e.g., "KXBTC")
Maximum number of events to return (max 200)
Search events by title, subtitle, or ticker. Results are sorted by match relevance (title matches first, then subtitle, ticker).
Returns
List of events matching the filter criteria, including title, subtitle, and category.
Examples
Get all events:
import { createBisonClient } from '@bison-markets/sdk-ts';
const client = createBisonClient({
baseUrl: 'https://api.bison.markets'
});
const response = await client.getEvents({ limit: '20' });
console.log(`Found ${response.events.length} events`);
response.events.forEach(event => {
console.log(`${event.event_ticker}: ${event.title}`);
if (event.sub_title) {
console.log(` ${event.sub_title}`);
}
});
Search by keyword:
// Search for events mentioning "Bitcoin" in title, subtitle, or ticker
const response = await client.getEvents({
query: 'Bitcoin',
limit: '5'
});
console.log(`Found ${response.events.length} events matching "Bitcoin"`);
// Results are sorted by relevance (title matches first)
response.events.forEach(event => {
console.log(`${event.event_ticker}: ${event.title}`);
});
Filter by series:
// Get all events in the Bitcoin series
const response = await client.getEvents({
series_ticker: 'KXBTC'
});
console.log(`Found ${response.events.length} Bitcoin events`);
Retrieve detailed information about a Kalshi event and its markets.
getEvent
async getEvent(eventTicker: string): Promise<GetEventResponse>
Parameters
Kalshi event ticker (e.g., "KXFEDDECISION-26JAN")
Returns
Event information including all associated markets, their metadata, and current state.
Example
import { createBisonClient } from '@bison-markets/sdk-ts';
const client = createBisonClient({
baseUrl: 'https://api.bison.markets'
});
const event = await client.getEvent('KXFEDDECISION-26JAN');
console.log('Event:', event.event_ticker);
console.log('Title:', event.title);
console.log('Category:', event.category);
console.log('Status:', event.status);
// List all markets in the event
event.markets.forEach(market => {
console.log(`Market: ${market.ticker}`);
console.log(` Subtitle: ${market.yes_sub_title}`);
console.log(` Floor: ${market.floor_strike}`);
console.log(` Cap: ${market.cap_strike}`);
console.log(` Status: ${market.status}`);
});
Retrieve metadata for a Kalshi event, including human-readable information and timestamps.
async getEventMetadata(eventTicker: string): Promise<GetEventMetadataResponse>
Parameters
Kalshi event ticker (e.g., "KXFEDDECISION-26JAN")
Returns
Event metadata including title, description, category, and important dates.
Example
const data = await client.getEventMetadata('KXFEDDECISION-26JAN');
console.log('Title:', data.event.title);
console.log('Subtitle:', data.event.sub_title);
console.log('Category:', data.event.category);
console.log('Image URL:', data.event.image_url);
// Check event timing
console.log('Expected expiration:', new Date(data.event.expected_expiration_time));
List Markets
Filter Kalshi markets by event, series, or status.
getMarkets
async getMarkets(params?: {
series_ticker?: string;
event_ticker?: string;
status?: 'active' | 'closed' | 'settled';
limit?: string;
}): Promise<GetMarketsResponse>
Parameters
All parameters are optional. Omit all parameters to retrieve all markets.
Filter by Kalshi series ticker (e.g., "KXPREZ")
Filter by Kalshi event ticker (e.g., "KXFEDDECISION-26JAN")
Filter by market status: "active", "closed", or "settled"
Maximum number of markets to return (max 200)
Returns
List of markets matching the filter criteria, including bid/ask prices, volume, and metadata.
Examples
Get all active markets:
import { createBisonClient } from '@bison-markets/sdk-ts';
const client = createBisonClient({
baseUrl: 'https://api.bison.markets'
});
const response = await client.getMarkets({ status: 'active' });
console.log(`Found ${response.markets.length} active markets`);
response.markets.forEach(market => {
console.log(`${market.ticker}: ${market.title}`);
console.log(` YES: ${market.yes_bid} / ${market.yes_ask}`);
console.log(` NO: ${market.no_bid} / ${market.no_ask}`);
console.log(` Volume: ${market.volume}`);
});
Filter by event ticker:
// Get all markets for a specific event
const response = await client.getMarkets({
event_ticker: 'KXFEDDECISION-26JAN',
status: 'active'
});
console.log(`Event has ${response.markets.length} active markets`);
// Find markets with high volume
const popularMarkets = response.markets
.filter(m => m.volume && m.volume > 1000)
.sort((a, b) => (b.volume || 0) - (a.volume || 0));
console.log('Most popular markets:');
popularMarkets.slice(0, 5).forEach(m => {
console.log(` ${m.ticker}: ${m.volume} volume`);
});
Filter by series:
// Get all presidential election markets
const response = await client.getMarkets({
series_ticker: 'KXPREZ',
limit: '50'
});
console.log(`Found ${response.markets.length} presidential markets`);
// Group by status
const byStatus = response.markets.reduce((acc, market) => {
acc[market.status || 'unknown'] = (acc[market.status || 'unknown'] || 0) + 1;
return acc;
}, {} as Record<string, number>);
console.log('Markets by status:', byStatus);
Find trading opportunities:
// Find markets with tight spreads
const response = await client.getMarkets({ status: 'active' });
const tightSpreads = response.markets
.filter(m => {
if (!m.yes_bid || !m.yes_ask) return false;
const spread = m.yes_ask - m.yes_bid;
return spread <= 0.02; // 2 cent spread or less
})
.map(m => ({
ticker: m.ticker,
title: m.title,
spread: m.yes_ask! - m.yes_bid!,
volume: m.volume || 0
}))
.sort((a, b) => a.spread - b.spread);
console.log('Markets with tight spreads:');
tightSpreads.slice(0, 10).forEach(m => {
console.log(` ${m.ticker}: ${(m.spread * 100).toFixed(1)}¢ spread, ${m.volume} volume`);
});
Get Market Price History
Retrieve historical YES probability for a market. Returns mean (VWAP) price per candlestick period, matching Kalshi’s official price charts.
getMarketHistory
async getMarketHistory(
marketTicker: string,
params?: {
start_ts?: number;
end_ts?: number;
period_interval?: number;
}
): Promise<GetMarketHistoryResponse>
Parameters
Market ticker (e.g., "KXBTC-25JAN03-B101")
Start timestamp in Unix seconds. Defaults to 30 days ago.
End timestamp in Unix seconds. Defaults to now.
Candle interval in minutes (e.g., 60 for 1 hour, 1440 for 1 day). Defaults to 60.
Returns
Array of price points, each containing:
timestamp - Unix timestamp (seconds) at end of period
yes_price - Mean YES price for the period (0-1 probability, VWAP)
Examples
Get last 24 hours (default):
import { createBisonClient } from '@bison-markets/sdk-ts';
const client = createBisonClient({
baseUrl: 'https://api.bison.markets'
});
const { history } = await client.getMarketHistory('KXBTC-25JAN03-B101');
console.log(`${history.length} data points`);
history.forEach(point => {
const date = new Date(point.timestamp * 1000);
console.log(`${date.toISOString()}: ${(point.yes_price * 100).toFixed(1)}%`);
});
Get last 7 days with daily intervals:
const now = Math.floor(Date.now() / 1000);
const weekAgo = now - 7 * 24 * 60 * 60;
const { history } = await client.getMarketHistory('KXBTC-25JAN03-B101', {
start_ts: weekAgo,
end_ts: now,
period_interval: 1440, // 1 day in minutes
});
console.log('Daily prices for the last week:');
history.forEach(point => {
const date = new Date(point.timestamp * 1000).toLocaleDateString();
console.log(`${date}: ${(point.yes_price * 100).toFixed(1)}%`);
});
Build a simple chart data structure:
const { history } = await client.getMarketHistory('KXBTC-25JAN03-B101', {
period_interval: 60, // 1 hour in minutes
});
const chartData = history.map(point => ({
x: new Date(point.timestamp * 1000),
y: point.yes_price * 100, // Convert to percentage
}));
// Use with your charting library (Chart.js, Recharts, etc.)
console.log('Chart data ready:', chartData.length, 'points');
Retrieve system configuration and contract addresses.
getInfo
async getInfo(): Promise<GetInfoResponse>
Returns
System information including vault addresses, USDC addresses, and supported chains.
Example
const info = await client.getInfo();
console.log('Bison API Version:', info.version);
console.log('Supported chains:', info.chains);
// Contract addresses are available if needed
const baseConfig = info.chains.base;
console.log('Base configuration:');
console.log(' Chain ID:', baseConfig.chainId);
console.log(' RPC URL:', baseConfig.rpcUrl);
// Note: The SDK automatically resolves vault and USDC addresses
// for all trading/deposit functions, so you typically don't need to access them directly
Complete Market Workflow Example
Here’s a complete example showing how to discover and monitor a market:
import { createBisonClient } from '@bison-markets/sdk-ts';
const client = createBisonClient({
baseUrl: 'https://api.bison.markets'
});
// 1. Get event information
const event = await client.getEvent('KXFEDDECISION-26JAN');
console.log(`Found ${event.markets.length} markets in event`);
// 3. Find a specific market
const market = event.markets.find(m =>
m.floor_strike === 425 && m.cap_strike === 450
);
if (!market) {
throw new Error('Market not found');
}
console.log('Trading market:', market.ticker);
console.log('Range:', market.floor_strike, '-', market.cap_strike);
// 4. Subscribe to real-time ticker updates
const disconnect = client.listenToKalshiEvent(
event.event_ticker,
(update) => {
// Filter for our specific market
if (update.market_ticker === market.ticker) {
console.log(`${market.ticker} update:`);
if (update.yes_bid_uusdc && update.yes_ask_uusdc) {
console.log(` YES: $${update.yes_bid_uusdc / 1_000_000} / $${update.yes_ask_uusdc / 1_000_000}`);
}
if (update.volume !== undefined) {
console.log(` Volume: ${update.volume}`);
}
}
}
);
// Clean up when done
// disconnect();
Error Handling
All methods throw errors when the API request fails:
try {
const event = await client.getEvent('INVALID-TICKER');
} catch (error) {
if (error instanceof Error) {
console.error('Failed to get event:', error.message);
// Handle specific error cases
if (error.message.includes('not found')) {
console.log('Event does not exist');
} else if (error.message.includes('network')) {
console.log('Network error, retrying...');
}
}
}
Important Notes
- Market status can be:
unopened, open, closed, or settled
- All dates are returned as ISO 8601 strings
- The
getInfo response is cached and safe to call frequently