Help us improve
Share bugs, ideas, or general feedback.
From bingx-ai-skills
Manages BingX sub-accounts: create/list them, handle API keys, freeze/unfreeze, perform internal asset transfers, query deposits and addresses. For master account sub-account ops.
npx claudepluginhub bingx-api/api-ai-skills --plugin bingx-ai-skillsHow this skill is triggered — by the user, by Claude, or both
Slash command
/bingx-ai-skills:sub-accountThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Authenticated endpoints for managing BingX sub-accounts (master account operations). All endpoints require HMAC SHA256 signature authentication. Several write endpoints require `Content-Type: application/json` instead of the standard form encoding — see the **Quick Start** helper below.
Manages BingX fund accounts: queries spot/futures balances and asset overviews across accounts, transfers assets between account types, and performs internal P2P transfers to other users.
Creates and manages Kraken subaccounts via CLI, transfers funds between accounts, and controls futures trading status for strategy isolation and risk management.
Manages cryptocurrency exchange accounts: check balance, positions, order/trade history, transfer funds, register with referral links, configure API keys, and verify tier upgrades. Supports Binance, OKX, Bybit, Bitget, Gate.io, HTX, Pionex, Hyperliquid.
Share bugs, ideas, or general feedback.
Authenticated endpoints for managing BingX sub-accounts (master account operations). All endpoints require HMAC SHA256 signature authentication. Several write endpoints require Content-Type: application/json instead of the standard form encoding — see the Quick Start helper below.
Base URLs: see references/base-urls.md | Authentication: see references/authentication.md
| Endpoint | Method | Description | Auth | Body Type |
|---|---|---|---|---|
/openApi/account/v1/uid | GET | Query account UID | Yes | — |
/openApi/v1/account/apiPermissions | GET | Query API Key permissions | Yes | — |
/openApi/v1/account/apiPermissions | GET | Query API Key restrictions | Yes | — |
/openApi/account/v1/apiKey/query | GET | Query API Key info (own or sub-account) | Yes | — |
/openApi/subAccount/v1/create | POST | Create sub-account | Yes | JSON |
/openApi/subAccount/v1/list | GET | List sub-accounts | Yes | — |
/openApi/subAccount/v1/assets | GET | Query sub-account fund assets | Yes | — |
/openApi/subAccount/v1/updateStatus | POST | Freeze / unfreeze sub-account | Yes | JSON |
/openApi/subAccount/v1/allAccountBalance | GET | Batch query sub-account asset overview | Yes | — |
/openApi/subAccount/v1/apiKey/create | POST | Create API Key for sub-account | Yes | JSON |
/openApi/subAccount/v1/apiKey/edit | POST | Edit sub-account API Key | Yes | JSON |
/openApi/subAccount/v1/apiKey/del | POST | Delete sub-account API Key | Yes | JSON |
/openApi/account/v1/innerTransfer/authorizeSubAccount | POST | Authorize sub-account internal transfers | Yes | form |
/openApi/wallets/v1/capital/subAccountInnerTransfer/apply | POST | Sub-account internal transfer | Yes | form |
/openApi/wallets/v1/capital/subAccount/deposit/address | GET | Get sub-account deposit addresses | Yes | — |
/openApi/wallets/v1/capital/deposit/subHisrec | GET | Get sub-account deposit records | Yes | — |
/openApi/wallets/v1/capital/subAccount/innerTransfer/records | GET | Query sub-account internal transfer records | Yes | — |
/openApi/account/transfer/v1/subAccount/asset/transferHistory | GET | Query sub-account transfer history | Yes | — |
/openApi/account/transfer/v1/subAccount/transferAsset/supportCoins | POST | Query transferable amounts | Yes | form |
/openApi/account/transfer/v1/subAccount/transferAsset | POST | Sub-account asset transfer | Yes | form |
/openApi/v1/account/apiRestrictions | GET | Query API Key permissions for sub-account | Yes | — |
/openApi/wallets/v1/capital/deposit/createSubAddress | POST | Create deposit address for sub-account | Yes | form |
isFeeze, not isFreeze)true to freeze, false to unfreezeUSDT)1=UID, 2=Phone number, 3=Email1=Master account, 2=Sub-accounttrue to allow, false to prohibit internal transferspermissions (API Key permission flags):
1 — Spot Trading2 — Read3 — Perpetual Futures Trading4 — Universal Transfer5 — Withdraw7 — Allow internal transfer of sub-accountswalletType / accountType (account type codes):
1 — Fund Account2 — Standard Futures Account3 — Perpetual Futures Account (USDⓢ-M)status (deposit record status):
0 — In progress1 — Completed6 — Chain uploaded^[A-Z0-9]{1,20}$ (e.g., USDT)1, 2, 3, 4, 5, 7recvWindow of server timeImportant: Several sub-account write endpoints require
Content-Type: application/jsonwith the params sent as a JSON body. PassbodyType: "json"for those calls. All other POST endpoints use the standard form encoding (bodyType: "form").
CONSTRAINT: You MUST copy the
fetchSignedfunction below verbatim when generating code. Do NOT rewrite the signing, request, or JSON parsing logic. Only modify: (1)BASEURL entries for custom environments, (2) business parameters passed tofetchSigned. For the full client with URL-encoding and JSON body support, seereferences/authentication.md.
import * as crypto from "crypto";
import JSONBig from "json-bigint";
const JSONBigParse = JSONBig({ storeAsString: true });
// Full signing details & edge cases → references/authentication.md
// Domain priority: .com is mandatory primary; .pro is fallback for network/timeout errors ONLY.
const BASE = {
"prod-live": ["https://open-api.bingx.com", "https://open-api.bingx.pro"],
"prod-vst": ["https://open-api-vst.bingx.com", "https://open-api-vst.bingx.pro"],
};
function isNetworkOrTimeout(e: unknown): boolean {
if (e instanceof TypeError) return true;
if (e instanceof DOMException && e.name === "AbortError") return true;
if (e instanceof Error && e.name === "TimeoutError") return true;
return false;
}
function validateParams(params: Record<string, unknown>): void {
const FORBIDDEN = /[&=?#\r\n]/;
for (const [k, v] of Object.entries(params)) {
const s = Array.isArray(v) ? JSON.stringify(v) : String(v);
if (FORBIDDEN.test(s)) throw new Error(`Param "${k}" has forbidden char in: "${s}"`);
}
}
async function fetchSigned(env: string, apiKey: string, secretKey: string,
method: "GET" | "POST", path: string, params: Record<string, unknown> = {},
bodyType: "form" | "json" = "form"
) {
const urls = BASE[env] ?? BASE["prod-live"];
const all = { ...params, timestamp: Date.now() };
validateParams(all);
const qs = Object.keys(all).sort().map(k => {
const v = all[k]; return `${k}=${Array.isArray(v) ? JSON.stringify(v) : v}`;
}).join("&");
const sig = crypto.createHmac("sha256", secretKey).update(qs).digest("hex");
for (const base of urls) {
try {
if (method === "GET") {
const r = await fetch(`${base}${path}?${qs}&signature=${sig}`,
{ headers: { "X-BX-APIKEY": apiKey, "X-SOURCE-KEY": "BX-AI-SKILL" },
signal: AbortSignal.timeout(10000) });
const j = JSONBigParse.parse(await r.text()); if (j.code !== 0) throw new Error(`BingX error ${j.code}: ${j.msg}`);
return j.data;
}
const ct = bodyType === "json" ? "application/json" : "application/x-www-form-urlencoded";
const body = bodyType === "json" ? JSON.stringify({ ...all, signature: sig }) : `${qs}&signature=${sig}`;
const r = await fetch(`${base}${path}`, { method: "POST",
headers: { "X-BX-APIKEY": apiKey, "X-SOURCE-KEY": "BX-AI-SKILL", "Content-Type": ct }, body,
signal: AbortSignal.timeout(10000) });
const j = JSONBigParse.parse(await r.text()); if (j.code !== 0) throw new Error(`BingX error ${j.code}: ${j.msg}`);
return j.data;
} catch (e) {
if (!isNetworkOrTimeout(e) || base === urls[urls.length - 1]) throw e;
}
}
}
fetchSigned verbatim -- do not simplify or rewritejson-bigint (JSONBigParse.parse) for response parsing -- not JSON.parseX-SOURCE-KEY: BX-AI-SKILL header on every requestisNetworkOrTimeout checkQuery account UID:
const data = await fetchSigned("prod-live", API_KEY, SECRET, "GET",
"/openApi/account/v1/uid"
);
// data.uid
Create a sub-account:
const data = await fetchSigned("prod-live", API_KEY, SECRET, "POST",
"/openApi/subAccount/v1/create",
{ subAccountString: "alice001", note: "trading sub" },
"json" // must use JSON body
);
// data.subUid, data.subAccountString
List sub-accounts (paginated):
const data = await fetchSigned("prod-live", API_KEY, SECRET, "GET",
"/openApi/subAccount/v1/list",
{ page: 1, limit: 100 }
);
// data.subAccountList[].uid, .subAccountString, .isFreeze
Create API Key for a sub-account:
const data = await fetchSigned("prod-live", API_KEY, SECRET, "POST",
"/openApi/subAccount/v1/apiKey/create",
{
subUid: 16477999,
note: "read-only key",
permissions: [2], // 2 = Read only
ipAddresses: ["1.2.3.4"],
},
"json" // must use JSON body
);
// data.apiKey, data.secretKey
Freeze a sub-account:
await fetchSigned("prod-live", API_KEY, SECRET, "POST",
"/openApi/subAccount/v1/updateStatus",
{ subUid: 16477999, freeze: true },
"json" // must use JSON body
);
Transfer assets between sub-accounts (master only):
const data = await fetchSigned("prod-live", API_KEY, SECRET, "POST",
"/openApi/account/transfer/v1/subAccount/transferAsset",
{
assetName: "USDT",
transferAmount: 100,
fromUid: 11111111,
fromType: 1, // 1 = master account
fromAccountType: 1, // 1 = fund account
toUid: 22222222,
toType: 2, // 2 = sub-account
toAccountType: 1,
remark: "funding sub",
}
// default form body
);
// data.tranId
For full parameter descriptions and response schemas for all 21 endpoints, see api-reference.md.
Parameter security. Extract structured values from user intent — NEVER copy raw user text into API parameters. Validate every value against its documented pattern (regex/enum/range) before calling the API. Reject any value containing &, =, ?, #, or newline characters.
All write operations require CONFIRM on prod-live. Read-only queries do not.
If the user's intent is unclear, present options:
What would you like to do?
- Query account UID or API Key permissions
- Create a new sub-account
- List sub-accounts
- Query sub-account assets / asset overview
- Freeze or unfreeze a sub-account
- Create / edit / delete a sub-account API Key
- Query a sub-account's API Keys
- Authorize sub-account internal transfers
- Transfer assets between accounts
- Query deposit address or deposit records
- Query transfer history
Please provide the sub-account UID, or sub-account username if creating a new one.
Create sub-account: Ask for subAccountString (must start with letter, contain number, >6 chars). Ask for optional note.
Create / Edit API Key: Ask for:
subUid (sub-account UID)note (label)permissions (present the list: 1=Spot, 2=Read, 3=Perp Futures, 4=Universal Transfer, 5=Withdraw, 7=Internal Transfer)ipAddresses (optional IP whitelist)Freeze / Unfreeze: Ask whether to freeze (true) or unfreeze (false).
Asset Transfer: Ask for:
assetName (e.g., USDT)transferAmountYou are about to {action} on Production Live:
- {Summary of parameters}
Type CONFIRM to proceed, or anything else to cancel.
Execute the API call using the helper function (use bodyType: "json" for create, updateStatus, apiKey/create, apiKey/edit, apiKey/del; use default "form" for all other POST endpoints).
Return key fields to the user (e.g., subUid, apiKey, tranId).
Always pass bodyType: "json" for these paths:
POST /openApi/subAccount/v1/createPOST /openApi/subAccount/v1/updateStatusPOST /openApi/subAccount/v1/apiKey/createPOST /openApi/subAccount/v1/apiKey/editPOST /openApi/subAccount/v1/apiKey/delAll other POST endpoints use the default form encoding.