Overview
The SDK provides methods to query market information, event metadata, and system configuration.
List Markets
Search and filter Kalshi markets based on various criteria.
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-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`);
});
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-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.subtitle}`);
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 metadata = await client.getEventMetadata('KXFEDDECISION-26JAN');
console.log('Title:', metadata.title);
console.log('Category:', metadata.category);
console.log('Series ticker:', metadata.series_ticker);
console.log('Mutually exclusive:', metadata.mutually_exclusive);
// Check event timing
console.log('Settlement date:', new Date(metadata.settlement_date));
console.log('Close date:', new Date(metadata.close_date));
console.log('Open date:', new Date(metadata.open_date));
Get Created Tokens
Retrieve information about position tokens that have been created on-chain.
getCreatedTokens
async getCreatedTokens(chain?: 'base'): Promise<GetCreatedTokensResponse>
Parameters
Optional chain identifier. Currently only "base" is supported.
Returns
List of created position tokens with their contract addresses and market information.
Example
const tokens = await client.getCreatedTokens('base');
console.log('Created tokens:');
tokens.forEach(token => {
console.log(`Market: ${token.marketId}`);
console.log(` YES token: ${token.yesTokenAddress}`);
console.log(` NO token: ${token.noTokenAddress}`);
console.log(` Created at: ${new Date(token.createdAt)}`);
});
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-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...');
}
}
}
Position Token Utilities
The SDK provides utility methods for working with position tokens on-chain.
getPositionTokenAddress
Get the on-chain token address for a specific market position.
async getPositionTokenAddress(params: {
publicClient: PublicClient;
chain: 'base';
marketId: string;
side: 'yes' | 'no';
}): Promise<`0x${string}` | null>
Parameters
Viem public client for reading from the blockchain
Chain identifier (currently only "base" is supported)
Position side: "yes" or "no"
Returns
Token address if the position has been minted, null otherwise.
Example
import { createPublicClient, http } from 'viem';
import { base } from 'viem/chains';
const publicClient = createPublicClient({
chain: base,
transport: http(),
});
const tokenAddress = await client.getPositionTokenAddress({
publicClient,
chain: 'base',
marketId: 'KXBTC-100K-DEC31',
side: 'yes',
});
if (tokenAddress) {
console.log('YES token address:', tokenAddress);
} else {
console.log('Position tokens not yet minted');
}
getTokenBalance
Get the balance of an ERC20 token for a specific address.
async getTokenBalance(params: {
publicClient: PublicClient;
tokenAddress: `0x${string}`;
userAddress: `0x${string}`;
}): Promise<bigint>
Parameters
Viem public client for reading from the blockchain
ERC20 token contract address
Wallet address to check balance for
Returns
Token balance as a bigint. Position tokens have 0 decimals.
Example
const tokenAddress = await client.getPositionTokenAddress({
publicClient,
chain: 'base',
marketId: 'KXBTC-100K-DEC31',
side: 'yes',
});
if (tokenAddress) {
const balance = await client.getTokenBalance({
publicClient,
tokenAddress,
userAddress: '0xf39Fd6e51aad88F6F4ce6aB8827279cffFb92266',
});
console.log(`Balance: ${balance} YES tokens`);
}
addTokenToWallet
Add a position token to the user’s wallet (e.g., MetaMask).
async addTokenToWallet(params: {
tokenAddress: `0x${string}`;
marketId: string;
side: 'yes' | 'no';
}): Promise<boolean>
Parameters
Position token contract address
Market ticker (used for token symbol)
Position side: "yes" or "no"
Returns
true if the user accepted the request, false otherwise.
Example
const tokenAddress = await client.getPositionTokenAddress({
publicClient,
chain: 'base',
marketId: 'KXBTC-100K-DEC31',
side: 'yes',
});
if (tokenAddress) {
try {
const added = await client.addTokenToWallet({
tokenAddress,
marketId: 'KXBTC-100K-DEC31',
side: 'yes',
});
if (added) {
console.log('Token added to wallet successfully');
} else {
console.log('User declined to add token');
}
} catch (error) {
console.error('Failed to add token:', error);
}
}
This method requires a browser environment with an injected Web3 wallet (like MetaMask). It will throw an error if called in a non-browser environment or if no wallet is detected.
Important Notes
- Market status can be:
unopened, open, closed, or settled
- All dates are returned as ISO 8601 strings
- Token addresses are only available after positions have been minted on-chain
- The
getInfo response is cached and safe to call frequently
- Position tokens have 0 decimals - quantities represent whole tokens
- Token symbols are automatically generated from the market ID (first 7 chars) and side