Live API

The same live feed as the Live Bets page, for your own programs. Read it, then place the opposite bet through Kalshi's own API from your computer. It is open to everyone while accounts are being set up, and will be part of Full Suite.

1. Read the feed

One address streams every bet the moment it happens: https://www.fliptradex.com/api/live. It stays open and sends plain text events. The first event, init, holds every trader and bet on the board. After that, bets comes at most once a second with a list of every bet that is new or changed since the last one, trader is a new or updated trader, and drop is a trader who left the list. By default the feed carries only the bets worth taking (single markets where their side cost 10 to 75 cents, $10 or more). Add ?all=1 for every bet.

curl -N https://www.fliptradex.com/api/live
Field of a betWhat it holds
srckalshi, poly (Polymarket) or hl (Hyperliquid)
whotheir made-up nickname
groupthe market or game the bet is in
tickerthe Kalshi market ticker, for placing the opposite bet (empty for parlays and for the other two sites)
pickthe side they took: YES, NO, an outcome, Long or Short
pricethe price they paid per contract, in dollars (0.65 is 65 cents)
sizetheir bet size as a range, like $100 to $500
timewhen, in milliseconds, to the minute
worthtrue when the bet is in the range where taking the other side paid in our test
copytrue when the side to take is their own side, because their record wins; false when it is the other side
fadeonce settled: what $100 on the side to take made, bought 2 cents worse than their price, after fees
ifWinstill open: what $100 on the side to take pays if it wins
nowstill open: what $100 on the side to take is worth at the best price you could sell for now

In Node 18 or newer, save this as fades.mjs and run node fades.mjs:

// fades.mjs: prints every new bet on the FlipTradeX live feed and the opposite bet. Run: node fades.mjs
const res = await fetch('https://www.fliptradex.com/api/live')
let buf = ''
for await (const chunk of res.body) {
  buf += Buffer.from(chunk).toString()
  for (let i; (i = buf.indexOf('\n\n')) >= 0; buf = buf.slice(i + 2)) {
    const block = buf.slice(0, i), type = block.match(/^event: (.+)$/m)?.[1], data = block.match(/^data: (.+)$/m)?.[1]
    if (type === 'bets') for (const b of JSON.parse(data)) console.log(b.src, '|', b.group, '|', b.ticker, '| they took', b.pick, 'at', b.price)
  }
}

In Python, save this as fades.py and run python3 fades.py:

# fades.py: prints every new bet on the FlipTradeX live feed. Run: pip install requests, then python3 fades.py
import json, requests
event = None
with requests.get("https://www.fliptradex.com/api/live", stream=True) as r:
    for line in r.iter_lines(decode_unicode=True):
        if line.startswith("event: "):
            event = line[7:]
        elif line.startswith("data: ") and event == "bets":
            for b in json.loads(line[6:]):
                print(b["src"], "|", b["group"], "|", b["ticker"], "| they took", b["pick"], "at", b["price"])

2. Place the opposite bet on Kalshi

You trade from your own Kalshi account, with your own keys, on your own computer. FlipTradeX never sees your keys and never places a bet for you. Start in Kalshi's demo, which uses play money: https://external-api.demo.kalshi.co/trade-api/v2. Real money uses https://external-api.kalshi.com/trade-api/v2.

Get keys. In Kalshi, open Account and security, then API Keys, then Create Key. Save the private key file and the key ID. Kalshi will not show the private key again.

Sign each request. Every request carries three headers: KALSHI-ACCESS-KEY (your key ID), KALSHI-ACCESS-TIMESTAMP (the time in milliseconds) and KALSHI-ACCESS-SIGNATURE. The signature is the timestamp, the method and the path joined together (like 1703123456789GET/trade-api/v2/portfolio/balance), signed with your private key using RSA-PSS and SHA-256, then turned into base64. Sign the path without anything after a question mark. Kalshi's full working code: Authenticated Requests.

Place the order. With the post() helper from Kalshi's Create your first order guide:

# fade.py: takes the other side of one Kalshi bet from the feed. Needs post(), private_key and API_KEY_ID
# from Kalshi's guide: https://docs.kalshi.com/getting_started/quick_start_create_order
import uuid
b = {"ticker": "KXNFLGAME-26NOV01ARIDAL-DAL", "pick": "YES"}  # one bet from the feed
pay = 0.35  # the most you will pay for one contract of your side, in dollars
# Kalshi V2 orders: "bid" means you hold YES, "ask" means you hold NO, and the price is always the YES price.
# So their YES becomes your "ask", and paying up to 35 cents for NO means a YES price of 0.65.
side = "ask" if b["pick"] == "YES" else "bid"
order = {"ticker": b["ticker"], "side": side, "count": "1", "price": f"{1 - pay if side == 'ask' else pay:.4f}",
         "time_in_force": "good_till_canceled", "self_trade_prevention_type": "taker_at_cross", "client_order_id": str(uuid.uuid4())}
response = post(private_key, API_KEY_ID, "/portfolio/events/orders", order)
print(response.status_code, response.text)

Watch the price live. Kalshi's websocket is wss://external-api-ws.kalshi.com/trade-api/ws/v2 (demo: wss://external-api-ws.demo.kalshi.co/trade-api/ws/v2). Open it with the same three headers, signed over GET and /trade-api/ws/v2, then send this to get every price change in one market:

{"id": 1, "cmd": "subscribe", "params": {"channels": ["ticker"], "market_tickers": ["KXNFLGAME-26NOV01ARIDAL-DAL"]}}

Each message has a type. A ticker message carries yes_bid_dollars and yes_ask_dollars. The trade channel sends every trade in the market, and fill sends your own fills. Kalshi's guide: WebSockets.

Fees. Kalshi's fee schedule charges an order that fills right away 7% times contracts times price times (1 minus price), rounded up. FlipTradeX rounds it up to the whole cent, so its numbers never come out better than yours. Check the fee on your first Kalshi fill before you bet more.