Skip to main content
This walks the full path: find an event, pick an outcome, submit an order, and read it back. Resource methods return the typed payload directly and raise a RequestError on any non-2xx response.
time_in_force defaults to {"type": "GTC"} for a Kalshi order in Python, so the snippet leaves it out. Pass it when you want something else.

Value casing

Enumerated values are uppercase everywhere they appear, on discovery listings, REST requests and stream frames alike: venue (POLYMARKET, KALSHI), order side and status, stream channels (BOOK, TRADE), book level side (BID, ASK) and market status (LIVE, RESYNCING). A venue read from one surface can be passed straight to another, and both clients pass it through unchanged, but a Kalshi listing’s side (YES, NO) is not an order side (BID, ASK). Frame type names are uppercase too (WELCOME, SNAPSHOT, PONG, ERROR).
You never pass a venue to the REST order methods, because the namespace carries it: client.polymarket and client.kalshi address their own venue.

Idempotency

submitOrder and submit_order attach a fresh idempotency key to every call, which protects you from the API replaying one request twice. It does not make your retry safe: a second call without a key of your own carries a new one, and the API treats it as a new order. To make a retry safe, generate the key yourself, keep it for as long as you might retry, and send the same one every time:
Re-sending a key with the same body returns the original order and creates no duplicate. Re-sending it with a different body is rejected. Some submits can instead report ORDER_RECONCILIATION_REQUIRED with the order’s orderId when the outcome is unknown: the Polymarket single submit and the Polymarket, Kalshi and ProphetX batch submits. Read that order back rather than submitting again. The Kalshi single submit above does not return it.

Venue namespaces

Orders, positions and balances are venue-scoped, because the venues address markets differently: Kalshi by ticker with a BID/ASK side and decimal count and price, Polymarket by tokenId with BUY/SELL and decimal prices.
Both namespaces carry seven core methods: submitOrder, listOrders, getOrder, cancelOrder, getOrderFills, listPositions and getBalance, in the naming of your language. cancelOrders also cancels every resting Polymarket order, or narrows to one outcome or market, in a single request:
Kalshi supports the same cancellation pattern, optionally narrowed to one ticker:
Read notCancelled on every response. When nextPageToken is present, pass it back with the same ticker to continue through the remaining orders. It returns cancelled and notCancelled, and a partial outcome is a success rather than an error. Read notCancelled for the orders that are still live and the code saying why. In Python a Polymarket order is one of two models, PolymarketMarketOrder or PolymarketLimitOrder, and the API discriminates on type. A limit order takes size and price instead of amount.

Identity and clock

whoami returns the trader and pod your key acts for, plus its capabilities, which is useful for confirming a key is wired to the pod you expect. The time route returns the server clock; see Authentication on why that matters.