# Kalshi Prediction Markets — Orthogonal API

> Pay-per-use API on Orthogonal. Each call is billed to your Orthogonal balance.
> Base API: `https://api.orthogonal.com/v1/run` · [llms.txt](https://orthogonal.com/llms.txt) · [browse all APIs](https://orthogonal.com/discover)

Real-time and historical prediction market data from Kalshi, a CFTC-regulated exchange. Access events, markets, order books, trades, candlesticks, series, milestones, and live data feeds (sports play-by-play, crypto and commodity prices, weather indices). All endpoints are free, public market data reads; no trading or account access.

**Verified:** no

## Access

**Run API:** `POST https://api.orthogonal.com/v1/run`
**Auth:** `Authorization: Bearer $ORTHOGONAL_API_KEY`
Get an API key at https://orthogonal.com/dashboard/settings/api-keys

Every call goes through the unified Run API: send the API `slug`, the endpoint `path`, and the `query`/`body` parameters. The response is `{ "success": true, "price": "<usd>", "data": { ... } }`.

## Endpoints

### Get Event Candlesticks

Get aggregated candlestick data across all markets in an event.

`GET /series/{series_ticker}/events/{ticker}/candlesticks`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `series_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `start_ts` | integer | Yes | Start timestamp (Unix seconds). |
| `end_ts` | integer | Yes | End timestamp (Unix seconds). |
| `period_interval` | integer | Yes | Candlestick period in minutes: 1, 60, or 1440. |

```bash
# Replace {series_ticker}, {ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/series/{series_ticker}/events/{ticker}/candlesticks","method":"GET","query":{"start_ts":"<integer>","end_ts":"<integer>","period_interval":"<integer>"}}'
```

### Get Exchange Status

Get current Kalshi exchange status: whether the exchange and trading are active, whether intra-exchange transfers are allowed, estimated resume time during maintenance, and per-index statuses.

`GET /exchange/status`

**Cost:** Free

_No parameters required._

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/exchange/status","method":"GET"}'
```

### Get Series Fee Changes

Get series-level fee change history, including scheduled and (optionally) historical fee changes.

`GET /series/fee_changes`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `series_ticker` | string | No | Filter by series ticker. |
| `show_historical` | boolean | No | Include historical fee changes. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/series/fee_changes","method":"GET","query":{"series_ticker":"<string>","show_historical":"<boolean>"}}'
```

### Get Filters for Sports

Get available filter options for sports markets.

`GET /search/filters_by_sport`

**Cost:** Free

_No parameters required._

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/search/filters_by_sport","method":"GET"}'
```

### Get Tags for Categories

Get available tags organized by series categories for browsing and filtering.

`GET /search/tags_by_categories`

**Cost:** Free

_No parameters required._

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/search/tags_by_categories","method":"GET"}'
```

### Get Exchange Schedule

Get the exchange operating schedule including maintenance windows and trading hours.

`GET /exchange/schedule`

**Cost:** Free

_No parameters required._

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/exchange/schedule","method":"GET"}'
```

### Get Historical Market

Get detailed data about a specific historical market by its ticker.

`GET /historical/markets/{ticker}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/historical/markets/{ticker}","method":"GET"}'
```

### Get Historical Cutoff

Get the archive cutoff timestamps. Markets settled before market_settled_ts (and their candlesticks) and trades before the trades cutoff must be fetched from the /historical endpoints instead of the live ones.

`GET /historical/cutoff`

**Cost:** Free

_No parameters required._

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/historical/cutoff","method":"GET"}'
```

### Get Event Live Data

Get event-keyed live data: crypto price candlesticks (e.g. BTC, ETH), commodity and index price time series (e.g. WTI, gold, S&P 500), and minute-level temperature observations for hourly temperature events. The response's type field names the schema of the details object. Not every event has a live feed; events without one (e.g. daily high-temperature or rainfall events) return 404.

`GET /live_data/events/{event_ticker}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `event_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `range` | string | No | Chart range hint: 15min, 1h, 1d, etc. |

```bash
# Replace {event_ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/live_data/events/{event_ticker}","method":"GET","query":{"range":"<string>"}}'
```

### Get Milestone Live Data

Get live data for a specific milestone (game, event, data release).

`GET /live_data/milestone/{milestone_id}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `milestone_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `include_player_stats` | boolean | No | Include player-level statistics. |

```bash
# Replace {milestone_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/live_data/milestone/{milestone_id}","method":"GET","query":{"include_player_stats":"<boolean>"}}'
```

### Get Game Stats

Get play-by-play game statistics for a sports milestone. Supports pro and college football, pro and college basketball (men's and women's), WNBA, soccer, pro hockey, and pro baseball. Returns null for unsupported milestones.

`GET /live_data/milestone/{milestone_id}/game_stats`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `milestone_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {milestone_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/live_data/milestone/{milestone_id}/game_stats","method":"GET"}'
```

### Get Event

Get detailed data about a specific event by its ticker, including category, settlement sources, and related markets.

`GET /events/{event_ticker}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `event_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `with_nested_markets` | boolean | No | Include markets within the event object. |

```bash
# Replace {event_ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/events/{event_ticker}","method":"GET","query":{"with_nested_markets":"<boolean>"}}'
```

### Get Event Metadata

Get metadata for a specific event by its ticker.

`GET /events/{event_ticker}/metadata`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `event_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {event_ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/events/{event_ticker}/metadata","method":"GET"}'
```

### Get Market

Get detailed data about a specific market by its ticker including current prices, volume, open interest, and settlement info.

`GET /markets/{ticker}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/markets/{ticker}","method":"GET"}'
```

### Get Multivariate Events

List multivariate (combo) events dynamically created from multivariate event collections. Filter by series_ticker or collection_ticker.

`GET /events/multivariate`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `limit` | integer | No | Results per page. Defaults to 100, max 200. |
| `cursor` | string | No | Pagination cursor. |
| `series_ticker` | string | No | Filter by series ticker |
| `collection_ticker` | string | No | Filter by collection ticker. |
| `with_nested_markets` | boolean | No | Include nested markets. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/events/multivariate","method":"GET","query":{"limit":"<integer>","cursor":"<string>","series_ticker":"<string>","collection_ticker":"<string>","with_nested_markets":"<boolean>"}}'
```

### Get Event Fee Changes

Get event-level fee overrides layered on top of the parent series' fee structure. Null fee_type_override and fee_multiplier_override mean the override was cleared. Paginated with limit and cursor.

`GET /events/fee_changes`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `event_ticker` | string | No | Filter by specific event ticker. |
| `limit` | integer | No | Number of results per page. Defaults to 100. |
| `cursor` | string | No | Pagination cursor. Use the cursor value returned from the previous response to get the next page of results. Leave empty for the first page. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/events/fee_changes","method":"GET","query":{"event_ticker":"<string>","limit":"<integer>","cursor":"<string>"}}'
```

### Get Structured Targets

List structured targets (teams, players, and other entities referenced by market settlement rules). Filter by type or competition; paginated, page_size up to 2000. To fetch a specific target, use /structured_targets/{structured_target_id}.

`GET /structured_targets`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | No | Filter by target type. |
| `competition` | string | No | Filter by competition. |
| `page_size` | integer | No | Items per page (1-2000, default 100). |
| `cursor` | string | No | Pagination cursor. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/structured_targets","method":"GET","query":{"type":"<string>","competition":"<string>","page_size":"<integer>","cursor":"<string>"}}'
```

### Get Multivariate Event Collections

Get collections of multivariate events (combo markets).

`GET /multivariate_event_collections`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `status` | string | No | Filter: unopened, open, closed. |
| `associated_event_ticker` | string | No | Filter by associated event ticker. |
| `series_ticker` | string | No | Filter by series ticker. |
| `limit` | integer | No | Max results. |
| `cursor` | string | No | Pagination cursor. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/multivariate_event_collections","method":"GET","query":{"status":"<string>","associated_event_ticker":"<string>","series_ticker":"<string>","limit":"<integer>","cursor":"<string>"}}'
```

### Get Milestone

Get detailed data about a specific milestone by its ID.

`GET /milestones/{milestone_id}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `milestone_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {milestone_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/milestones/{milestone_id}","method":"GET"}'
```

### Get Multivariate Event Collection

Get a specific multivariate event collection by its ticker.

`GET /multivariate_event_collections/{collection_ticker}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `collection_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {collection_ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/multivariate_event_collections/{collection_ticker}","method":"GET"}'
```

### Get Structured Target

Get a specific structured target by its ID.

`GET /structured_targets/{structured_target_id}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `structured_target_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {structured_target_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/structured_targets/{structured_target_id}","method":"GET"}'
```

### Get Historical Markets

List markets archived to the historical database (settled before the historical cutoff). Filters are mutually exclusive. Useful for backtesting and research.

`GET /historical/markets`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `limit` | integer | No | Results per page. Defaults to 100, max 1000. |
| `cursor` | string | No | Pagination cursor. |
| `tickers` | string | No | Comma-separated market tickers. |
| `event_ticker` | string | No | Filter by event ticker. |
| `series_ticker` | string | No | Filter by series ticker. |
| `mve_filter` | string | No | Filter multivariate events. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/historical/markets","method":"GET","query":{"limit":"<integer>","cursor":"<string>","tickers":"<string>","event_ticker":"<string>","series_ticker":"<string>","mve_filter":"<string>"}}'
```

### Get Trades

Get completed trades across all markets with ticker, price, quantity, and timestamp. Block trades are included by default; filter with is_block_trade. Trades before the historical cutoff are in /historical/trades.

`GET /markets/trades`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `limit` | integer | No | Results per page. Defaults to 100, max 1000. |
| `cursor` | string | No | Pagination cursor. |
| `ticker` | string | No | Filter by market ticker. |
| `min_ts` | integer | No | Filter trades after this Unix timestamp. |
| `max_ts` | integer | No | Filter trades before this Unix timestamp. |
| `is_block_trade` | boolean | No | Filter by block trade status. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/markets/trades","method":"GET","query":{"limit":"<integer>","cursor":"<string>","ticker":"<string>","min_ts":"<integer>","max_ts":"<integer>","is_block_trade":"<boolean>"}}'
```

### Get Events

List prediction events with optional filters (status, series_ticker, specific tickers, close/update time). Events are real-world occurrences like elections, economic releases, or games, each containing one or more markets. Excludes multivariate (combo) events; use /events/multivariate for those.

`GET /events`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `limit` | integer | No | Results per page. Defaults to 200, max 200. |
| `cursor` | string | No | Pagination cursor from previous response. |
| `with_nested_markets` | boolean | No | Include nested markets in response. |
| `with_milestones` | boolean | No | Include related milestones. |
| `status` | string | No | Filter by status: unopened, open, closed, settled. |
| `series_ticker` | string | No | Filter by series ticker |
| `tickers` | string | No | Filter by specific event tickers. Comma-separated list of event tickers to retrieve. |
| `min_close_ts` | integer | No | Min close timestamp (Unix seconds). |
| `min_updated_ts` | integer | No | Filter events updated after this Unix timestamp. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/events","method":"GET","query":{"limit":"<integer>","cursor":"<string>","with_nested_markets":"<boolean>","with_milestones":"<boolean>","status":"<string>","series_ticker":"<string>","tickers":"<string>","min_close_ts":"<integer>","min_updated_ts":"<integer>"}}'
```

### Get Market Candlesticks

Get OHLC candlestick data for a market within a series. period_interval is in minutes: 1, 60, or 1440. Markets settled before the historical cutoff must use /historical/markets/{ticker}/candlesticks.

`GET /series/{series_ticker}/markets/{ticker}/candlesticks`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `series_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `start_ts` | integer | Yes | Start timestamp (Unix seconds). |
| `end_ts` | integer | Yes | End timestamp (Unix seconds). |
| `period_interval` | integer | Yes | Candlestick period in minutes: 1, 60, or 1440. |
| `include_latest_before_start` | boolean | No | Prepend the latest candlestick before start_ts. |

```bash
# Replace {series_ticker}, {ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/series/{series_ticker}/markets/{ticker}/candlesticks","method":"GET","query":{"start_ts":"<integer>","end_ts":"<integer>","period_interval":"<integer>","include_latest_before_start":"<boolean>"}}'
```

### Batch Get Market Candlesticks

Batch get candlestick data for up to 100 market tickers in one request (max 10,000 candlesticks total), grouped by market. period_interval is in minutes: 1, 60, or 1440.

`GET /markets/candlesticks`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `market_tickers` | string | Yes | Comma-separated market tickers (max 100). |
| `start_ts` | integer | Yes | Start timestamp (Unix seconds). |
| `end_ts` | integer | Yes | End timestamp (Unix seconds). |
| `period_interval` | integer | Yes | Candlestick period in minutes: 1, 60, or 1440. |
| `include_latest_before_start` | boolean | No | Prepend the latest candlestick before start_ts. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/markets/candlesticks","method":"GET","query":{"market_tickers":"<string>","start_ts":"<integer>","end_ts":"<integer>","period_interval":"<integer>","include_latest_before_start":"<boolean>"}}'
```

### Get Markets

Get all markets with optional filters. Markets represent specific binary outcomes with yes/no positions, prices, volume, and settlement rules.

`GET /markets`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `limit` | integer | No | Results per page. Defaults to 100, max 1000. |
| `cursor` | string | No | Pagination cursor. |
| `event_ticker` | string | No | Filter by event ticker. |
| `series_ticker` | string | No | Filter by series ticker. |
| `min_created_ts` | integer | No | Filter markets created after this timestamp. |
| `max_created_ts` | integer | No | Filter markets created before this timestamp. |
| `min_updated_ts` | integer | No | Markets updated after this Unix timestamp. |
| `max_updated_ts` | integer | No | Markets updated before this Unix timestamp. |
| `max_close_ts` | integer | No | Filter markets closing before this Unix timestamp. |
| `min_close_ts` | integer | No | Filter markets closing after this Unix timestamp. |
| `min_settled_ts` | integer | No | Markets settled after this Unix timestamp. |
| `max_settled_ts` | integer | No | Markets settled before this Unix timestamp. |
| `status` | string | No | Filter by status: unopened, open, closed, settled. |
| `tickers` | string | No | Comma-separated list of market tickers. |
| `mve_filter` | string | No | Multivariate filter: only, exclude, or include all. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/markets","method":"GET","query":{"limit":"<integer>","cursor":"<string>","event_ticker":"<string>","series_ticker":"<string>","min_created_ts":"<integer>","max_created_ts":"<integer>","min_updated_ts":"<integer>","max_updated_ts":"<integer>","max_close_ts":"<integer>","min_close_ts":"<integer>","min_settled_ts":"<integer>","max_settled_ts":"<integer>","status":"<string>","tickers":"<string>","mve_filter":"<string>"}}'
```

### Get Weather Index

Get the Kalshi-computed city temperature index: the minute-resolution series (Fahrenheit, 0.01 precision) that settles hourly temperature markets. Gaps where the index quorum failed are real gaps.

`GET /live_data/weather/{city}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `city` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `from` | integer | No | Window start, unix milliseconds. Defaults to 24h before to. |
| `to` | integer | No | Window end, unix milliseconds. Defaults to now. |
| `last_sec` | integer | No | Trailing window in seconds (alternative to from/to). |
| `detailed` | boolean | No | Include per-station audit readings. |

```bash
# Replace {city} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/live_data/weather/{city}","method":"GET","query":{"from":"<integer>","to":"<integer>","last_sec":"<integer>","detailed":"<boolean>"}}'
```

### Get Historical Trades

Get trades filled before the historical cutoff across all markets. Block trades are included by default; filter with is_block_trade.

`GET /historical/trades`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `ticker` | string | No | Filter by market ticker. |
| `min_ts` | integer | No | Filter after this Unix timestamp. |
| `max_ts` | integer | No | Filter before this Unix timestamp. |
| `limit` | integer | No | Results per page. Defaults to 100, max 1000. |
| `cursor` | string | No | Pagination cursor. |
| `is_block_trade` | boolean | No | Filter by block trade status. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/historical/trades","method":"GET","query":{"ticker":"<string>","min_ts":"<integer>","max_ts":"<integer>","limit":"<integer>","cursor":"<string>","is_block_trade":"<boolean>"}}'
```

### Get Incentive Programs

List Kalshi incentive programs (liquidity and volume rewards tied to specific markets) with optional filters.

`GET /incentive_programs`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `status` | string | No | Status: all, active, upcoming, closed, or paid_out. |
| `type` | string | No | Type: all, liquidity, volume, etc. |
| `incentive_description` | string | No | Filter by exact description. |
| `limit` | integer | No | Results per page. Defaults to 100, max 10000. |
| `cursor` | string | No | Pagination cursor. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/incentive_programs","method":"GET","query":{"status":"<string>","type":"<string>","incentive_description":"<string>","limit":"<integer>","cursor":"<string>"}}'
```

### Get Weather Index Calibrations

Get a city's weather-index configuration timeline: launch config plus every weekly offset calibration and methodology update, with station weights, offsets, and city reference needed to reproduce index values.

`GET /live_data/weather/{city}/calibrations`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `city` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |

```bash
# Replace {city} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/live_data/weather/{city}/calibrations","method":"GET"}'
```

### Get Live Data by Type

Legacy version of milestone live data that requires a type path parameter. Prefer /live_data/milestone/{milestone_id}.

`GET /live_data/{type}/milestone/{milestone_id}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `milestone_id` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `include_player_stats` | boolean | No | Include player-level statistics. |

```bash
# Replace {type}, {milestone_id} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/live_data/{type}/milestone/{milestone_id}","method":"GET","query":{"include_player_stats":"<boolean>"}}'
```

### Get Series

Get detailed data about a specific series by its ticker.

`GET /series/{series_ticker}`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `series_ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `include_volume` | boolean | No | Include total volume traded. |

```bash
# Replace {series_ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/series/{series_ticker}","method":"GET","query":{"include_volume":"<boolean>"}}'
```

### Get Milestones

List milestones: scheduled real-world occurrences (games, data releases) linked to prediction markets. Filter by start date, category, competition, type, or related event ticker.

`GET /milestones`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `limit` | integer | Yes | Number per page. |
| `minimum_start_date` | string | No | Min start date (RFC3339). |
| `category` | string | No | Filter: Sports, Elections, Crypto, etc. |
| `competition` | string | No | Filter: Pro Football, Pro Basketball, etc. |
| `source_id` | string | No | Filter by source ID. |
| `type` | string | No | Filter: football_game, basketball_game, etc. |
| `related_event_ticker` | string | No | Filter by related event ticker. |
| `cursor` | string | No | Pagination cursor. |
| `min_updated_ts` | integer | No | Milestones updated after this timestamp. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/milestones","method":"GET","query":{"limit":"<integer>","minimum_start_date":"<string>","category":"<string>","competition":"<string>","source_id":"<string>","type":"<string>","related_event_ticker":"<string>","cursor":"<string>","min_updated_ts":"<integer>"}}'
```

### Get Series List

Get data about multiple series. A series is a template for recurring events (e.g. Monthly Jobs Report).

`GET /series`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `category` | string | No | Filter by category. |
| `tags` | string | No | Filter by tags. |
| `include_product_metadata` | boolean | No | Include product metadata. |
| `include_volume` | boolean | No | Include total volume across events. |
| `min_updated_ts` | integer | No | Series updated after this Unix timestamp. |

```bash
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/series","method":"GET","query":{"category":"<string>","tags":"<string>","include_product_metadata":"<boolean>","include_volume":"<boolean>","min_updated_ts":"<integer>"}}'
```

### Get Historical Market Candlesticks

Get OHLC candlestick data for an archived market that settled before the historical cutoff. period_interval is in minutes: 1, 60, or 1440.

`GET /historical/markets/{ticker}/candlesticks`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `start_ts` | integer | Yes | Start timestamp (Unix seconds). |
| `end_ts` | integer | Yes | End timestamp (Unix seconds). |
| `period_interval` | integer | Yes | Candlestick period in minutes: 1, 60, or 1440. |

```bash
# Replace {ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/historical/markets/{ticker}/candlesticks","method":"GET","query":{"start_ts":"<integer>","end_ts":"<integer>","period_interval":"<integer>"}}'
```

### Get Market Orderbook

Get the current order book for a market. Returns yes_dollars and no_dollars bid levels as [price_in_dollars, contract_count] pairs, sorted by price ascending (best bid is last). Asks are implied: a yes bid at $X equals a no ask at $(1-X). Use depth to return only the top N levels per side.

`GET /markets/{ticker}/orderbook`

**Cost:** Free

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `ticker` | string | Yes | Path parameter — substitute directly into the endpoint `path`. |
| `depth` | integer | No | Number of price levels per side to return (1-100). 0 or omitted returns all levels. |

```bash
# Replace {ticker} in "path" with real values before sending
curl -X POST 'https://api.orthogonal.com/v1/run' \
  -H 'Authorization: Bearer $ORTHOGONAL_API_KEY' \
  -H 'Content-Type: application/json' \
  -d '{"api":"kalshi","path":"/markets/{ticker}/orderbook","method":"GET","query":{"depth":"<integer>"}}'
```

---

Full details and an interactive quickstart: https://orthogonal.com/discover/kalshi
