Skip to content

Commit 3868dcf

Browse files
committed
feat: add missing API fields and endpoints from v3.8.0 audit
Audit against the latest Kalshi Python SDK (v3.8.0) revealed two gaps: - Add yes_bid_size_fp and yes_ask_size_fp to REST Market struct (already present in WebSocket ticker messages, added to API Feb 24, 2026) - Add subaccount netting endpoints: GET and PUT /portfolio/subaccounts/netting (added to API Feb 23, 2026) - Update API README: total endpoint count 84 -> 86, add netting to subaccounts section
1 parent b51f0dc commit 3868dcf

File tree

6 files changed

+110
-9
lines changed

6 files changed

+110
-9
lines changed

src/api/README.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ Complete reference for all Kalshi REST API endpoints supported by this library.
2424
| Order Groups | 7 | 100% |
2525
| Account | 1 | 100% |
2626
| Portfolio | 5 | 100% |
27-
| Subaccounts | 5 | 100% |
27+
| Subaccounts | 7 | 100% |
2828
| Markets | 6 | 100% |
2929
| Events | 6 | 100% |
3030
| Series | 2 | 100% |
@@ -38,7 +38,7 @@ Complete reference for all Kalshi REST API endpoints supported by this library.
3838
| Incentive Programs | 1 | 100% |
3939
| FCM | 2 | 100% |
4040
| Historical | 6 | 100% |
41-
| **Total** | **84** | **100%** |
41+
| **Total** | **86** | **100%** |
4242

4343
---
4444

@@ -123,6 +123,8 @@ Complete reference for all Kalshi REST API endpoints supported by this library.
123123
| 🔲 | POST | `/portfolio/subaccounts/transfer` | `transfer_between_subaccounts()` | |
124124
| 🔲 | GET | `/portfolio/subaccounts/balances` | `get_subaccount_balances()` | |
125125
| 🔲 | GET | `/portfolio/subaccounts/transfers` | `get_subaccount_transfers()` | |
126+
| 🔲 | GET | `/portfolio/subaccounts/netting` | `get_subaccount_netting()` | Netting config for all subaccounts |
127+
| 🔲 | PUT | `/portfolio/subaccounts/netting` | `update_subaccount_netting()` | Enable/disable netting per subaccount |
126128
| 🔲 | GET | `/portfolio/summary/total_resting_order_value` | `get_resting_order_value()` | FCM members only |
127129

128130
**Source**: `src/api/subaccounts.rs`

src/api/subaccounts.rs

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ use crate::{
88
error::Result,
99
models::{
1010
CreateSubaccountRequest, CreateSubaccountResponse, GetSubaccountTransfersParams,
11-
RestingOrderValueResponse, SubaccountBalancesResponse, SubaccountTransfersResponse,
12-
TransferBetweenSubaccountsRequest, TransferResponse,
11+
RestingOrderValueResponse, SubaccountBalancesResponse, SubaccountNettingResponse,
12+
SubaccountTransfersResponse, TransferBetweenSubaccountsRequest, TransferResponse,
13+
UpdateSubaccountNettingRequest,
1314
},
1415
};
1516

@@ -46,6 +47,20 @@ pub async fn get_subaccount_transfers(
4647
http.get(&path).await
4748
}
4849

50+
/// Returns netting configuration for all subaccounts.
51+
pub async fn get_subaccount_netting(http: &HttpClient) -> Result<SubaccountNettingResponse> {
52+
http.get("/portfolio/subaccounts/netting").await
53+
}
54+
55+
/// Updates the netting configuration for a specific subaccount.
56+
pub async fn update_subaccount_netting(
57+
http: &HttpClient,
58+
request: UpdateSubaccountNettingRequest,
59+
) -> Result<()> {
60+
http.put_no_response("/portfolio/subaccounts/netting", &request)
61+
.await
62+
}
63+
4964
/// Returns the total value in cents of all resting orders (primarily for FCM members).
5065
pub async fn get_resting_order_value(http: &HttpClient) -> Result<RestingOrderValueResponse> {
5166
http.get("/portfolio/summary/total_resting_order_value")

src/client.rs

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -44,9 +44,9 @@ use crate::{
4444
PositionsResponse, QueuePositionsResponse, QuoteResponse, RestingOrderValueResponse,
4545
RfqResponse, SeriesListResponse, SeriesResponse, SettlementsResponse,
4646
StructuredTargetResponse, StructuredTargetsResponse, SubaccountBalancesResponse,
47-
SubaccountTransfersResponse, TagsByCategoriesResponse, TradesResponse,
48-
TransferBetweenSubaccountsRequest, TransferResponse, UpdateOrderGroupLimitRequest,
49-
UserDataTimestampResponse,
47+
SubaccountNettingResponse, SubaccountTransfersResponse, TagsByCategoriesResponse,
48+
TradesResponse, TransferBetweenSubaccountsRequest, TransferResponse,
49+
UpdateOrderGroupLimitRequest, UpdateSubaccountNettingRequest, UserDataTimestampResponse,
5050
},
5151
};
5252

@@ -1888,6 +1888,47 @@ impl KalshiClient {
18881888
subaccounts::get_resting_order_value(&self.http).await
18891889
}
18901890

1891+
/// Get netting configuration for all subaccounts.
1892+
///
1893+
/// Returns the netting enabled/disabled setting for each subaccount.
1894+
///
1895+
/// # Example
1896+
///
1897+
/// ```ignore
1898+
/// let netting = client.get_subaccount_netting().await?;
1899+
/// for config in &netting.netting_configs {
1900+
/// println!("Subaccount {}: netting {}",
1901+
/// config.subaccount_number,
1902+
/// if config.enabled { "enabled" } else { "disabled" }
1903+
/// );
1904+
/// }
1905+
/// ```
1906+
pub async fn get_subaccount_netting(&self) -> Result<SubaccountNettingResponse> {
1907+
subaccounts::get_subaccount_netting(&self.http).await
1908+
}
1909+
1910+
/// Update the netting configuration for a specific subaccount.
1911+
///
1912+
/// # Arguments
1913+
///
1914+
/// * `request` - The netting update request specifying subaccount and enabled state
1915+
///
1916+
/// # Example
1917+
///
1918+
/// ```ignore
1919+
/// use kalshi_trade_rs::models::UpdateSubaccountNettingRequest;
1920+
///
1921+
/// // Enable netting for the primary account
1922+
/// let request = UpdateSubaccountNettingRequest::new(0, true);
1923+
/// client.update_subaccount_netting(request).await?;
1924+
/// ```
1925+
pub async fn update_subaccount_netting(
1926+
&self,
1927+
request: UpdateSubaccountNettingRequest,
1928+
) -> Result<()> {
1929+
subaccounts::update_subaccount_netting(&self.http, request).await
1930+
}
1931+
18911932
// =========================================================================
18921933
// Live Data API
18931934
// =========================================================================

src/models.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ pub use structured_target::{
110110
pub use subaccount::{
111111
CreateSubaccountRequest, CreateSubaccountResponse, GetSubaccountTransfersParams,
112112
RestingOrderValueResponse, Subaccount, SubaccountBalance, SubaccountBalancesResponse,
113-
SubaccountTransfer, SubaccountTransfersResponse, TransferBetweenSubaccountsRequest,
114-
TransferResponse,
113+
SubaccountNettingConfig, SubaccountNettingResponse, SubaccountTransfer,
114+
SubaccountTransfersResponse, TransferBetweenSubaccountsRequest, TransferResponse,
115+
UpdateSubaccountNettingRequest,
115116
};

src/models/market.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -189,10 +189,16 @@ pub struct Market {
189189
pub yes_bid: i64,
190190
/// Best YES bid price in dollars.
191191
pub yes_bid_dollars: String,
192+
/// Size at best YES bid (fixed-point decimal string).
193+
#[serde(default)]
194+
pub yes_bid_size_fp: Option<String>,
192195
/// Best YES ask price in cents.
193196
pub yes_ask: i64,
194197
/// Best YES ask price in dollars.
195198
pub yes_ask_dollars: String,
199+
/// Size at best YES ask (fixed-point decimal string).
200+
#[serde(default)]
201+
pub yes_ask_size_fp: Option<String>,
196202
/// Best NO bid price in cents.
197203
pub no_bid: i64,
198204
/// Best NO bid price in dollars.

src/models/subaccount.rs

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -257,6 +257,42 @@ pub struct SubaccountTransfersResponse {
257257
pub cursor: Option<String>,
258258
}
259259

260+
/// Netting configuration for a single subaccount.
261+
#[derive(Debug, Clone, Serialize, Deserialize)]
262+
pub struct SubaccountNettingConfig {
263+
/// Subaccount number (0 for primary, 1-32 for subaccounts).
264+
pub subaccount_number: i32,
265+
/// Whether netting is enabled for this subaccount.
266+
pub enabled: bool,
267+
}
268+
269+
/// Response from GET /portfolio/subaccounts/netting.
270+
#[derive(Debug, Clone, Serialize, Deserialize)]
271+
pub struct SubaccountNettingResponse {
272+
/// Netting configurations for all subaccounts.
273+
pub netting_configs: Vec<SubaccountNettingConfig>,
274+
}
275+
276+
/// Request body for PUT /portfolio/subaccounts/netting.
277+
#[derive(Debug, Clone, Serialize, Deserialize)]
278+
pub struct UpdateSubaccountNettingRequest {
279+
/// Subaccount number (0 for primary, 1-32 for subaccounts).
280+
pub subaccount_number: i32,
281+
/// Whether to enable netting for the subaccount.
282+
pub enabled: bool,
283+
}
284+
285+
impl UpdateSubaccountNettingRequest {
286+
/// Create a new netting update request.
287+
#[must_use]
288+
pub fn new(subaccount_number: i32, enabled: bool) -> Self {
289+
Self {
290+
subaccount_number,
291+
enabled,
292+
}
293+
}
294+
}
295+
260296
/// Response from GET /portfolio/summary/total_resting_order_value.
261297
#[derive(Debug, Clone, Serialize, Deserialize)]
262298
pub struct RestingOrderValueResponse {

0 commit comments

Comments
 (0)