Skip to main content

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.
series_ticker
string
Filter by Kalshi series ticker (e.g., "KXBTC")
limit
string
Maximum number of events to return (max 200)
query
string
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`);

Get Event Information

Retrieve detailed information about a Kalshi event and its markets.

getEvent

async getEvent(eventTicker: string): Promise<GetEventResponse>

Parameters

eventTicker
string
required
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}`);
});

Get Event Metadata

Retrieve metadata for a Kalshi event, including human-readable information and timestamps.

getEventMetadata

async getEventMetadata(eventTicker: string): Promise<GetEventMetadataResponse>

Parameters

eventTicker
string
required
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.
series_ticker
string
Filter by Kalshi series ticker (e.g., "KXPREZ")
event_ticker
string
Filter by Kalshi event ticker (e.g., "KXFEDDECISION-26JAN")
status
string
Filter by market status: "active", "closed", or "settled"
limit
string
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

marketTicker
string
required
Market ticker (e.g., "KXBTC-25JAN03-B101")
start_ts
number
Start timestamp in Unix seconds. Defaults to 30 days ago.
end_ts
number
End timestamp in Unix seconds. Defaults to now.
period_interval
number
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');

Get System Information

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