V1 (/v1) and V2 (/v2) run side by side, so you can migrate at your own pace. The envelope model is identical — ClientMessage / ServerMessage with a oneof payload. The changes below are what actually differ.
Regenerate your code from the t4/v2 proto set (package t4proto.v2.*). Do not point a V1-generated parser at a /v2 stream — several field numbers were reassigned (see order routing and market data).
wss:…/v1. Same hostnames.
→ wss:…/v2
V1 had two subscribe messages (MarketDepthSubscribe + MarketByOrderSubscribe) and request-time DepthBuffer / DepthLevels parameters. V2 replaces all of that with a single MarketSubscribe:
quotes (Quotes enum) picks the feed in one field: NONE (unsubscribe), TOP_OF_BOOK, FULL_ORDER_BOOK, MARKET_BY_ORDER.ticker (bool) turns the trade feed on.
Message changes (ServerMessage):
| V1 | V2 |
|---|---|
MarketDepthSubscribeReject (100) + MarketByOrderSubscribeReject (101) | MarketSubscribeReject (100) — one reject |
MarketDepthTrade (104) | MarketTrade (104) — one trade message for all feeds |
MarketByOrderTrade (111) | *(removed — MBO trades arrive as MarketTrade with sequence + participating orders)* |
MarketDepth (103), MarketSnapshot (108), MarketByOrderSnapshot (109) and MarketByOrderUpdate (110) are unchanged. See Market Data.
V1 spread order lifecycle events across six server messages. V2 collapses them into a single OrderUpdate plus a dedicated OrderTrade.
| V1 (ServerMessage) | V2 |
|---|---|
OrderUpdate (300) | OrderUpdate (300), discriminated by update_type |
OrderUpdateMulti (301) | *(removed — snapshots arrive as OrderUpdate with update_type=SNAPSHOT)* |
OrderUpdateFailed (302) | OrderUpdate with update_type=FAILED |
OrderUpdateStatus (303) | OrderUpdate with update_type=STATUS |
OrderUpdateTrade (304) | OrderUpdate with update_type=TRADE + OrderTrade (301) |
OrderUpdateTradeLeg (305) | OrderUpdate with update_type=TRADE_LEG |
Field-number reassignment (order routing responses): V2 field 301 is now OrderTrade (was OrderUpdateMulti) and 302 is now MarginInquiryResponse (was OrderUpdateFailed). Switch on ServerMessage.payload from the V2 proto — do not assume V1 numbering.
Every order-routing volume — volume, max_show, max_volume, current_volume, new_volume, total_fill_volume, working_volume, trade volume — changed from int32 to the Decimal string type. This supports fractional exchange quantities (e.g. Kalshi “1.50”). See Prices & Data Types.
Market-data volumes are unchanged (still int32).
margin_inquiry on a submitted Order to receive a MarginInquiryResponse (margins and impact) without placing the order.ClOrdId on OrderSubmit / OrderRevise / OrderPull; echoed back as tag_cl_ord_id. You can also address revise/pull by ClOrdId.OrderBatchAcknowledge / OrderBatchReject echo ClOrdId alongside the assigned unique_id.
The account feed (ServerMessage fields 200–207) keeps the same message names and field numbers as V1 — only the proto package changed.
Message fields are documented in the .proto files — see the Message Catalog.