0) and may use numbered subaccounts 1–63.
Subaccounts are currently an API-only feature — they are not yet supported in the
Kalshi web or mobile app. Numbered-subaccount balances and positions are managed through
the trade API.
Requirements
Creating a numbered subaccount with Create Subaccount requires the Advanced API tier or above. On the Basic tier the request returns403 with code
subaccount_creation_requires_advanced_api_usage_level.
Intra Account Transfer
returns the same error when a Basic-tier account names a numbered subaccount.
The demo environment does not enforce the tier requirement, so a client that
works in demo can still receive this 403 in production.
Creating a subaccount needs an API key with the write scope, and
transferring between subaccounts needs write::transfer. See
Scopes.
Numbering
Transfers
You can move cash between your own subaccounts withPOST /portfolio/subaccounts/transfer (amounts in cents). Transfers net to
zero at the account level — nothing leaves your account.
Transfers are idempotent on a client-supplied client_transfer_id: retrying
with the same value returns 409 instead of applying the transfer twice.
Listing transfers
GET /portfolio/subaccounts/transfers returns your subaccount transfers,
paginated.
Restricted API keys
When generating an API key you can restrict it to a single subaccount. A restricted key can read and trade on that subaccount: order placement and management, portfolio reads (balance, positions, fills, settlements), order groups, and the full REST RFQ lifecycle — creating combo markets in multivariate event collections, creating and cancelling RFQs, posting, confirming, and cancelling quotes, and accepting quotes. Requests that omitsubaccount act on the key’s locked subaccount, and naming any other
subaccount is rejected.
GET /portfolio/subaccounts/balances also accepts restricted keys. It returns
only the key’s locked subaccount, with separate balances per exchange index.
To move funds between exchange indices, call
POST /portfolio/intra_exchange_instance_transfer with source_subaccount and
destination_subaccount both set to the key’s subaccount. Transfers to or from
margin are not allowed.
On perps, a restricted key can place, amend, decrease, and cancel orders
(including cancel-all), manage order groups, and manage cross-margin exit
triggers on its locked subaccount. It can also list that subaccount’s orders
(GET /margin/orders; naming any other subaccount is rejected), read them
individually (GET /margin/orders/{order_id} returns 404 for orders in any
other subaccount), and read that subaccount’s positions, fills, and funding
payments (GET /margin/positions, GET /margin/fills, and
GET /margin/funding_history, on the same terms as the order list).
GET /margin/balance returns only the locked subaccount’s balance and omits
the account-wide settled_funds total. Other authenticated perps endpoints,
including risk (GET /margin/risk), are not yet available to restricted keys.
Self-trade prevention applies across all subaccounts of an account. When an
order from a restricted key would trade against an order resting in another
subaccount, its self_trade_prevention_type decides the outcome:
taker_at_cross cancels the restricted key’s order, and maker cancels the
resting order in the other subaccount.
A restricted key cannot transfer funds between subaccounts, manage subaccounts or API keys, or
act on RFQs and quotes belonging to a different subaccount of the same
account. Subaccount-scoped requests match rows created through the API with
an explicit subaccount identity; RFQs created in the web app are not
addressable per subaccount. Endpoints outside its allowed set return
403 this API key is restricted to a single sub-account and cannot access this endpoint. On FIX, restricted keys support order entry and the maker
quote lifecycle only — RFQ creation (35=R) and quote acceptance (35=UA) are
not available to restricted FIX sessions.