> ## Documentation Index
> Fetch the complete documentation index at: https://docs.0xmonaco.com/llms.txt
> Use this file to discover all available pages before exploring further.

# MarginAccountsService

> Parent margin account summaries, risk bucket collateral transfers, movements, and risk simulation

Package: `monaco.api.margin_accounts`

Source: `protos/api/margin_accounts.proto`

Use `MarginAccountsService` for parent margin account state, risk bucket collateral movement, and pre-trade risk checks.

```protobuf theme={null}
service MarginAccountsService {
  rpc GetMarginAccountSummary(GetMarginAccountSummaryRequest) returns (GetMarginAccountSummaryResponse);
  rpc GetParentMarginAccountSummary(GetParentMarginAccountSummaryRequest) returns (GetMarginAccountSummaryResponse);
  rpc ListMarginAccounts(ListMarginAccountsRequest) returns (ListMarginAccountsResponse);
  rpc GetAvailableCollateral(GetAvailableCollateralRequest) returns (GetAvailableCollateralResponse);
  rpc TransferCollateralToMarginAccount(TransferCollateralToMarginAccountRequest) returns (TransferCollateralToMarginAccountResponse);
  rpc TransferCollateralFromMarginAccount(TransferCollateralFromMarginAccountRequest) returns (TransferCollateralFromMarginAccountResponse);
  rpc TransferCollateralToParentMarginAccount(TransferCollateralToParentMarginAccountRequest) returns (TransferCollateralToMarginAccountResponse);
  rpc TransferCollateralFromParentMarginAccount(TransferCollateralFromParentMarginAccountRequest) returns (TransferCollateralFromMarginAccountResponse);
  rpc GetMarginAccountMovements(GetMarginAccountMovementsRequest) returns (GetMarginAccountMovementsResponse);
  rpc GetParentMarginAccountMovements(GetParentMarginAccountMovementsRequest) returns (GetMarginAccountMovementsResponse);
  rpc SimulateOrderRisk(SimulateOrderRiskRequest) returns (SimulateOrderRiskResponse);
  rpc SimulateParentMarginOrderRisk(SimulateParentMarginOrderRiskRequest) returns (SimulateOrderRiskResponse);
  rpc TransferCollateralToRiskBucket(TransferCollateralToRiskBucketRequest) returns (TransferCollateralToMarginAccountResponse);
  rpc SimulateRiskBucketOrderRisk(SimulateRiskBucketOrderRiskRequest) returns (SimulateOrderRiskResponse);
  rpc CreateSubAccount(CreateSubAccountRequest) returns (CreateSubAccountResponse);
  rpc CloseSubAccount(CloseSubAccountRequest) returns (CloseSubAccountResponse);
  rpc GetMarginAccountPnl(GetMarginAccountPnlRequest) returns (GetMarginAccountPnlResponse);
  rpc TransferCollateral(TransferCollateralRequest) returns (TransferCollateralResponse);
  rpc TransferCollateralToSubAccount(TransferCollateralToSubAccountRequest) returns (TransferCollateralResponse);
  rpc TransferCollateralFromSubAccount(TransferCollateralFromSubAccountRequest) returns (TransferCollateralResponse);
}
```

## Notes

* Margin account RPCs are authenticated.
* Parent margin account RPCs operate on the authenticated user's parent account.
* Risk bucket RPCs resolve the target isolated bucket from request context such as trading pair and optional strategy key.
* `SimulateRiskBucketOrderRiskRequest.selected_trading_pair_ids` is **deprecated and ignored** in CROSS mode, the contract `TransferCollateralToRiskBucketRequest` already adopted for its own field. Cross scope is derived from trading — a pair joins the cross risk bucket when a cross order on it succeeds and, once its positions close, stays listed until a later successful cross order on another pair reconciles the bucket — and the preview never priced anything from the list, so requiring it only produced `INVALID_ARGUMENT`s. A CROSS preview with an empty list, one omitting `trading_pair_id`, and one omitting a pair with an open cross position now all succeed, with unchanged figures. The field stays on the wire so pre-deprecation clients keep working; sending a value logs a server-side deprecation warning and has no other effect, and it is still rejected for ISOLATED (`selectedTradingPairIds is not supported for ISOLATED risk buckets`). `SimulateOrderRiskResponse.selected_trading_pair_ids` now reports the DERIVED scope the preview ran against — the active cross bucket's recorded pairs, every pair with an open position in it, and the previewed pair — never the caller's list. The generated gRPC struct carries `#[deprecated]`, so build the request with `..Default::default()` rather than naming the field, which trips rustc's `deprecated` lint under `-D warnings`.
* `TransferCollateralFromMarginAccountRequest` accepts an optional `margin_mode` (`ISOLATED` or `CROSS`); set `CROSS` to release the account's cross risk bucket, which has no trading pair and cannot be named by `trading_pair_id`. It is mutually exclusive with `trading_pair_id`, and released collateral returns to the parent margin account.
* `MarginAccountSummary` carries `subaccount_key` (`default` for the default margin account) and `margin_account_state` (`ACTIVE` or `CLOSED`) on every row, and `risk_bucket_state` (`NORMAL`, `PENDING_LIQUIDATION`, `LIQUIDATING`, `BAD_DEBT`, `CLOSED`) on risk-bucket rows only. `ListMarginAccountsRequest.state` filters on `risk_bucket_state`, so any filter excludes margin account rows, which have no state.
* `CreateSubAccount` opens a margin sub-account keyed by `subaccount_key`: up to 64 letters, digits, `_`, `-`, `.` or `:`; keys starting with `copy:` are reserved and `default` names the default margin account. The default margin account must already exist. Re-creating an open key is idempotent; re-creating a closed key re-opens the same account. Open sub-accounts are capped per owner by weighted 14-day volume tier (10 at the first tier, rising with the fee-tier floors to 50) or an admin override; copy-trading sub-accounts do not count. Returns `INVALID_ARGUMENT` for a malformed, reserved or `default` key, a missing default margin account, or a create past the cap; `PERMISSION_DENIED` for delegated-agent sessions; `RESOURCE_EXHAUSTED` (with `RetryInfo`) past the per-user movement budget; `UNAVAILABLE` when no matching engine connection is configured or the new account has not been projected yet; and `INTERNAL` when the call to the matching engine fails in transit.
* `CloseSubAccount` closes a flat sub-account (no position, resting order, conditional order or TWAP) in one call: its flat, solvent risk buckets close and all of its remaining collateral moves to the default margin account. `CloseSubAccountResponse` names `margin_account_id`, `default_margin_account_id` and the `amount` moved. Returns `INVALID_ARGUMENT` for the default margin account, a copy-trading sub-account (closed by stopping its follow), an already-closed sub-account, a sub-account that is not flat, or one with a risk bucket in liquidation, in bad debt, or insolvent — nothing moves; `NOT_FOUND` for an account that is not the caller's; `PERMISSION_DENIED` for delegated-agent sessions; `RESOURCE_EXHAUSTED` past the movement budget; `UNAVAILABLE` when no matching engine connection is configured; `INTERNAL` when the call to the matching engine fails in transit.
* `GetMarginAccountPnl` returns one of the caller's margin accounts' own `realized_pnl` (settled on the account plus still held in its open risk buckets) and `unrealized_pnl` (open positions at the latest risk marks); the caller's accounts sum to the owner-wide figure. Returns `INVALID_ARGUMENT` for a malformed id, `NOT_FOUND` for an account that is not the caller's, and `RESOURCE_EXHAUSTED` past the read budget.
* `TransferCollateral` moves collateral between `from` and `to` `CollateralTransferEndpoint`s, each naming exactly one of `wallet` and `margin_account_id`. Served moves: wallet to the default margin account and back, and margin account to margin account. An endpoint carrying `risk_bucket_id` is refused with `INVALID_ARGUMENT` — fund risk buckets with `TransferCollateralToRiskBucket`. Also `INVALID_ARGUMENT` for wallet to wallet, a wallet transfer naming a sub-account, the same account on both sides, or a closed account; `NOT_FOUND` for an account that is not the caller's; `PERMISSION_DENIED` for delegated-agent sessions; `RESOURCE_EXHAUSTED` past the movement budget.
* `TransferCollateralToSubAccount` moves `amount` from the caller's default margin account to the sub-account `margin_account_id`; `TransferCollateralFromSubAccount` moves it back. Each is the same one-step account-to-account move as `TransferCollateral`. Returns `INVALID_ARGUMENT` when `margin_account_id` is the default margin account (use the parent-margin-account RPCs), the sub-account is closed, or the amount exceeds the source's free collateral; `NOT_FOUND` for an account that is not the caller's; `PERMISSION_DENIED` for delegated-agent sessions; `RESOURCE_EXHAUSTED` past the movement budget.
* `TransferCollateralToRiskBucketRequest.margin_account_id` and `SimulateRiskBucketOrderRiskRequest.margin_account_id` select the margin account: omit it for the default margin account, or name one of the caller's open sub-accounts to fund or preview that sub-account's own risk buckets. A closed sub-account or a copy-trading sub-account is `INVALID_ARGUMENT`; another user's account is `NOT_FOUND`.
* `ListMarginAccounts`, `GetMarginAccountMovements` and `GetParentMarginAccountMovements` are cursor-paginated: send an empty `page_token` to start, then each response's `next_page_token` until it comes back empty; `page_size` is 1 to 1000. There is no `page` field: a stub generated from an older proto that still sets it is not rejected (protobuf discards the unknown field) and reads the first page on every call, so regenerate stubs and walk the token.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.