OKX · Money path
OKX Funds Transfer: Where Deposits Land, How Money Moves Between Accounts, and Why API Keys Shouldn't Withdraw
The money is on OKX, but your script reads a balance of zero. Or you want to take some profit out and find a grid bot is holding it. Quant money on OKX passes several doors: which account a deposit lands in, how it gets to the trading account where orders are placed, how it's split out to sub-accounts, where the part held by bots shows up, and only then withdrawal.
Which account does an OKX deposit land in?
You choose. The help center's How do I make a deposit? (web) has you pick the crypto and the network, and then: "In the Deposit account section, you can select whether to deposit funds into your Funding or Trading account." In the API docs, the to field returned by Get deposit address is the same choice: 6 is the funding account, 18 the trading account, with a note that users under some entities (Brazil is the example given) can only deposit to the trading account.
Arrival waits on chain confirmations. The same help page says: "The deposit will typically show as successful once all block confirmations for that crypto have been completed."
How do transfers work between funding, trading and sub-accounts?
Manual transfers are done on the website or in the app. A script uses the Funds transfer endpoint: POST /api/v5/asset/transfer, rate-limited to 2 requests per second. Per the docs it covers a master account moving funds from its funding account to its trading account, and from the master account to the funding and trading accounts of sub-accounts. Four parameters are required: ccy (currency), amt (amount), from and to, and the last two take only 6 (funding account) or 18 (trading account). Across master and sub-accounts you add type and subAcct (the sub-account name):
| What you're doing | type | Whose key the docs allow | subAcct |
|---|---|---|---|
| Transfer within one account (funding ↔ trading) | 0 (default) | Not restricted | Not needed |
| Master account to sub-account | 1 | Master account API key | Required |
| Sub-account to master account | 2 | Master account API key | Required |
| Sub-account to master account | 3 | Sub-account API key | Not needed |
| Sub-account to another sub-account under the same master | 4 | Sub-account API key, and the master must first grant transfer-out permission | Required |
The first example in the docs is a master account moving 1.5 USDT from its funding account to its trading account:
POST /api/v5/asset/transfer
{
"ccy": "USDT",
"amt": "1.5",
"from": "6",
"to": "18"
}
Two things are easy to miss. First, the docs warn under this endpoint that the success or failure of the request doesn't necessarily reflect the actual transfer result, and recommend confirming with Get funds transfer state (GET /api/v5/asset/transfer-state, which covers the last two weeks). Second, error code 58111 means funding fees are being collected on perpetual contracts and transfers are temporarily unavailable; have the script retry on that code.
When a master account wants to move money directly between two sub-accounts, that's a different endpoint, Master accounts manage the transfers between sub-accounts, which the docs mark as master account only. What the funding account, trading account and sub-accounts each are is covered in OKX Funding Account vs Trading Account.
How do I see the funds a trading bot is holding?
Once a grid-type bot is created, the money put into it no longer counts toward the trading account's available balance. OKX's Introduction to Trading bot Mode says: "The fund invested in the grid will be isolated from your Trading account and used independently for the Trading bot." It adds: "You can view and manage your bots on the Bots page." Recurring buy is the opposite; per the same page, "the fund is not reserved and isolated upfront for each cycle from the trading account." What happens when the balance runs short is covered in OKX Recurring Buy.
Over the API there are two places to look:
- Get balance (
GET /api/v5/account/balance): each currency carriesstgyEq, described as "Total equity allocated to trading bots for the currency", next toavailBal(available balance) andfrozenBal(frozen balance). - Get grid algo order list: each running grid carries
investment(accumulated investment amount) andtotalPnl(total P&L).
To move money a grid is holding, it first has to come back to the trading account. The Spot Grid help page describes the routes: when the bot is stopped and its holdings sold, "Funds from the sale will be returned to your trading account"; withdrawn grid profit goes to the trading account too. After that, transfer it as in the previous section. How much you can move is what availBal shows.
What permission does the transfer endpoint need?
Trade. When you create a key there are only three permissions to tick, Read, Trade and Withdraw, and the docs describe Trade as "Can place and cancel orders, funding transfer, make settings which need write permission". So a key with just Read and Trade can already move money between the funding and trading accounts; if it's a master account key, it can also push money out to sub-accounts and pull it back.
A read-only key can't move money, which makes it the right key for monitoring and reconciliation. A strategy key carries Trade, so store it as a key that can use every transfer route the account has. If you want a strategy to reach only part of your money, give it its own sub-account and use that sub-account's own key; the reasoning is in What Happens When an API Key Leaks.
Why shouldn't an API key have Withdraw permission?
The docs describe the Withdrawal endpoint (POST /api/v5/asset/withdrawal) this way: withdrawal is supported for funding-account assets, ordinary sub-accounts can't withdraw, and the API can only withdraw to verified addresses, which are set up on the website or app.
There are three reasons not to tick Withdraw on a strategy key:
- The strategy doesn't need it. Placing and cancelling orders, reading balances and transferring are all covered by Read and Trade.
- It sidesteps the checks on a manual withdrawal. The help center's How do I make a withdrawal? (web) has you "Complete the 2FA verification" before confirming; an API call needs nothing but the key's signature.
- If Read or Trade is abused, the money is still somewhere among your own accounts. If Withdraw is abused, it leaves OKX, and once it's on-chain it can't be pulled back.
The API key security section of the docs has two related rules: bind the key to IP addresses (up to 20 per key), and a key that has Trade or Withdraw permission but no bound IP is deleted automatically after 14 days of inactivity. Keep withdrawals as a manual step on the website or app.
FAQ
Should I deposit to the funding account or the trading account?
If a script or bot will trade with the money right away, pick the trading account and save yourself a transfer. If it will sit for a while or be withdrawn later, pick the funding account, since withdrawals only cover funding-account assets. Either way the choice isn't final: you can still transfer between the two afterwards.
The transfer endpoint returned success. Why hasn't the money arrived?
The docs warn under the funds transfer endpoint that the success or failure of the request doesn't necessarily reflect the actual transfer result, and recommend confirming with Get funds transfer state (GET /api/v5/asset/transfer-state), which covers the last two weeks. Separately, error code 58111 means funding fees are being collected on perpetual contracts and transfers are temporarily unavailable; retry a little later.
Can a key with only Trade permission send money to a sub-account?
Yes, provided the key belongs to the master account. The docs put funding transfer under the Trade permission; in the funds transfer endpoint, type 1 is master account to sub-account, marked as master account API key only, and the sub-account name goes in subAcct.
Can I transfer the money a grid bot is using straight back to the funding account?
Not directly. That money was isolated from the trading account when the grid was created. Per OKX's Spot Grid help page, when the bot is stopped and its holdings are sold, the funds from the sale are returned to your trading account; only then can you transfer them.
What does withdrawing through the API require?
The key needs Withdraw permission, and the docs state the API can only withdraw to verified addresses, which have to be set up on the website or app first; ordinary sub-accounts can't withdraw. A strategy key has no use for this permission, so leave it off and withdraw by hand.