Notes
Notes on what the prediction-market APIs get wrong
Six things Polymarket's and Kalshi's APIs do that will quietly cost you money, each found live and each reproducible without keys.
- Polymarket's order book arrives worst-firstbids[0] is the worst bid, not the best. Why the raw CLOB book is ordered the way it is, what it costs you, and how to normalise and walk it.
- Kalshi has no ask side: two bid ladders, and a NO bid is a YES askKalshi's order book publishes YES bids and NO bids, both ascending, as dollar strings. Getting the translation backwards silently takes the opposite position.
- A geoblocked machine reads fine and fails only at the orderPolymarket and Kalshi enforce jurisdiction at order placement, not at connection. Every public read answers normally, so a restricted server looks perfectly healthy until the first trade.
- A rejected order is a return value, not an exceptionThe exchange models a rejected order as an ok:false response. Reported carelessly, a rejection reads to an agent as a resting order.
- The call that sounds like your trades returns everyone'slist_account_trades returns the market's public tape, not your fills. Read your own activity by wallet instead.
- A price gap across two venues is not an edgeIdentical wording on Polymarket and Kalshi does not mean identical settlement. Most cross-venue gaps are a settlement difference, not free money.
Found by driving the venues live, then encoded so an agent never rediscovers it. Reproduce every one of these with no keys: pip install oddsrail && python examples/footguns.py (source).