Monaco Protocol SDK v1.1.1
This release derives a cross risk bucket’sselectedTradingPairIds from its open positions, makes the builder-fee change limit a Monaco setting (10 changes in a rolling 24 hours by default), lets a browser read the edge’s own 451 and 429 refusals, and keeps order, take-profit, stop-loss and TWAP deadlines running through a maintenance window. No request or response shape changed. Action item: if you read selectedTradingPairIds as the markets a cross risk bucket may trade, read it as the markets where it holds an open position.
Changed
A cross risk bucket’s scope is its open positions
selectedTradingPairIds on a cross risk bucket is now the markets where that risk bucket has an open position, sorted by trading pair id. That covers MarginAccountSummary.selectedTradingPairIds from sdk.marginAccounts.listMarginAccounts (GET /api/v1/margin/accounts; gRPC MarginAccountsService.ListMarginAccounts), GET /api/v1/margin/accounts/{marginAccountId} and GET /api/v1/margin/parent-margin-account (gRPC GetMarginAccountSummary, GetParentMarginAccountSummary), the selectedTradingPairIds a cross transferCollateralToRiskBucket returns, and the selectedTradingPairIds of every cross simulateRiskBucketOrderRisk preview, which is that scope plus the previewed pair. A market joins once a fill’s position is persisted and leaves once its last position’s close is persisted, so a position still being liquidated counts. Resting orders alone do not count, and pairs declared before scope was derived drop off once they hold no open position. Raw REST and gRPC requests may still carry the deprecated selectedTradingPairIds request fields, which the server ignores. The TypeScript SDK rejects them with a ValidationError before sending, so omit them. See Margin Accounts.
The builder-fee change limit is a Monaco setting
The number ofBUILDER fee changes an enrolled frontend can make in a rolling 24 hours is now set by Monaco instead of fixed at two: 10 by default, never below 1 or above 100. One setBuilderFee call is still one change, whichever sides it sets, and administrator changes still never count. changesRemaining on sdk.buildercodes.getConfig() (GET /api/v1/buildercodes/config; gRPC BuildercodeRewardsService.GetBuildercodesConfig) and on setBuilderFee (PUT /api/v1/buildercodes/builder-fee; gRPC SetBuilderFee) can now be up to 100, and the change-limit refusal names the limit in force. See BuilderCodes.
Fixed
A browser can read the edge’s own refusals
The production region gate’s451 REGION_RESTRICTED (details.reason edge_geo_block) and the edge rate limits’ 429 RATE_LIMIT_EXCEEDED (details.reason edge_request_flood / edge_429_flood) now carry the same CORS headers the API sends. In a browser, a write from a restricted region now fails with an APIError whose statusCode is 451, instead of Network request failed for <endpoint>, so a frontend can show the region message. The region gate never refuses a preflight, so this always holds. An edge rate limit is readable only when the request needs no preflight or the browser has cached one: while a client is blocked, the edge refuses its preflights too, and the call still fails as a network error. Treat that as transient and retry with backoff. Node and other non-browser callers are unaffected. See Region Status and Rate Limits.
Deadlines keep running through maintenance
During a maintenance window, aGTC order past its expirationDate and a take-profit or stop-loss past its expiresAt now expire, a conditional TWAP order past its conditionalExpiry expires instead of waiting, and a TWAP order past its endTime ends and releases its hold. Before, all of them stayed live until maintenance lifted. New orders are still refused during maintenance, as before.

