> ## Documentation Index
> Fetch the complete documentation index at: https://docs.bison.markets/llms.txt
> Use this file to discover all available pages before exploring further.

# Events & Markets

> Querying market data and metadata

## Overview

The SDK provides methods to query market information, event metadata, and system configuration.

<Info>
  To avoid ambiguity, we denote the smallest possible multiple of USDC (0.000001 USDC) as one `uusdc`,
  which stands for µUSDC (micro-USDC), and denote the smallest possible multiple of a contract (0.01 contract)
  as one `ccontract` (centicontract).

  User-facing USDC balances are specified as fixed-point strings (e.g. `"1.2625"` for USDC). Contract quantities
  in the API and SDK are specified as integer `ccontracts` strings (e.g. `"1050"` for 10.50 contracts at precision 2).
</Info>

## List & Search Events

Search and filter events from the Bison event cache. Events are synced from Kalshi hourly.

### `getEvents`

```typescript theme={null}
async getEvents(params?: {
  series_ticker?: string;
  limit?: string;
  query?: string;
}): Promise<GetEventsResponse>
```

#### Parameters

All parameters are optional. Omit all parameters to retrieve all events.

<ParamField path="series_ticker" type="string">
  Filter by Kalshi series ticker (e.g., `"KXBTC"`)
</ParamField>

<ParamField path="limit" type="string">
  Maximum number of events to return (max 200)
</ParamField>

<ParamField path="query" type="string">
  Search events by title, subtitle, or ticker. Results are sorted by match relevance (title matches first, then subtitle, ticker).
</ParamField>

#### Returns

List of events matching the filter criteria, including title, subtitle, and category.

#### Examples

**Get all events:**

```typescript theme={null}
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:**

```typescript theme={null}
// 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:**

```typescript theme={null}
// 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`

```typescript theme={null}
async getEvent(eventTicker: string): Promise<GetEventResponse>
```

#### Parameters

<ParamField path="eventTicker" type="string" required>
  Kalshi event ticker (e.g., `"KXFEDDECISION-26JAN"`)
</ParamField>

#### Returns

Event information including all associated markets, their metadata, and current state.

#### Example

```typescript theme={null}
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`

```typescript theme={null}
async getEventMetadata(eventTicker: string): Promise<GetEventMetadataResponse>
```

#### Parameters

<ParamField path="eventTicker" type="string" required>
  Kalshi event ticker (e.g., `"KXFEDDECISION-26JAN"`)
</ParamField>

#### Returns

Event metadata including title, description, category, and important dates.

#### Example

```typescript theme={null}
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`

```typescript theme={null}
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.

<ParamField path="series_ticker" type="string">
  Filter by Kalshi series ticker (e.g., `"KXPREZ"`)
</ParamField>

<ParamField path="event_ticker" type="string">
  Filter by Kalshi event ticker (e.g., `"KXFEDDECISION-26JAN"`)
</ParamField>

<ParamField path="status" type="string">
  Filter by market status: `"active"`, `"closed"`, or `"settled"`
</ParamField>

<ParamField path="limit" type="string">
  Maximum number of markets to return (max 200)
</ParamField>

#### Returns

List of markets matching the filter criteria, including bid/ask prices, volume, and metadata.

#### Examples

**Get all active markets:**

```typescript theme={null}
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:**

```typescript theme={null}
// 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:**

```typescript theme={null}
// 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:**

```typescript theme={null}
// 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`

```typescript theme={null}
async getMarketHistory(
  marketTicker: string,
  params?: {
    start_ts?: number;
    end_ts?: number;
    period_interval?: number;
  }
): Promise<GetMarketHistoryResponse>
```

#### Parameters

<ParamField path="marketTicker" type="string" required>
  Market ticker (e.g., `"KXBTC-25JAN03-B101"`)
</ParamField>

<ParamField path="start_ts" type="number">
  Start timestamp in Unix seconds. Defaults to 30 days ago.
</ParamField>

<ParamField path="end_ts" type="number">
  End timestamp in Unix seconds. Defaults to now.
</ParamField>

<ParamField path="period_interval" type="number">
  Candle interval in minutes (e.g., `60` for 1 hour, `1440` for 1 day). Defaults to `60`.
</ParamField>

#### 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):**

```typescript theme={null}
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:**

```typescript theme={null}
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:**

```typescript theme={null}
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`

```typescript theme={null}
async getInfo(): Promise<GetInfoResponse>
```

#### Returns

System information including vault addresses, USDC addresses, and supported chains.

#### Example

```typescript theme={null}
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:

```typescript theme={null}
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:

```typescript theme={null}
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
