Skip to main content

Pionex API: Complete Guide

Explains the Pionex API: REST base api.pionex.com, WebSocket wss://ws.pionex.com/wsPub, HMAC-SHA256 signing via PIONEX-KEY/PIONEX-SIGNATURE headers, 10 req/sec rate limit, free to use, Spot/Bot/Futures/Earn endpoints

1. What is the Pionex API?

The Pionex API is a programmatic interface that lets you control your Pionex account from your own code, scripts, or third-party tools — without ever clicking inside the Pionex web app. Anything you can do in the user interface (check your balance, place a spot order, start a Grid Bot, open a futures position, subscribe to a Dual Investment product) you can also do through the API.

The API speaks two related "dialects":

  • REST — classic HTTP requests. You ask a question (GET) or push a change (POST, DELETE) and get a JSON answer back. Best for actions: place this order, cancel that bot, show my balances.

  • WebSocket — a long-lived streaming connection. The server pushes updates to you in real time. Best for data that changes constantly: live prices, order book updates, fills as they happen.

Most integrations use both: REST for "do something now," WebSocket for "tell me when something changes."

To access your API key creation, refer to Step 4.1

Who is the API for?

Audience

Typical use case

Beginner traders

Read-only scripts that fetch your portfolio into a spreadsheet, log fills to a file, or send a Telegram alert when a bot closes.

Quant / algo traders

Custom strategies, backtests, market-making bots, statistical arbitrage.

Developers and fintech teams

Embed Pionex trading inside another product, build a tax-reporting tool, or sync balances into a portfolio dashboard.

Power users

Operate dozens of grid bots in parallel, batch-cancel orders, run scheduled DCA jobs.

You do not need to be a senior engineer. If you can run a Python or JavaScript script, you can use the Pionex API. The hardest concept — request signing — is explained in plain language below, with copy-paste examples.

At-a-glance reference

Property

Value

REST base URL (Spot / Bot / Earn)

REST base URL (Futures)

WebSocket public stream

Authentication

HMAC-SHA256 signature on every private request

Required headers

PIONEX-KEY, PIONEX-SIGNATURE

Response format

JSON envelope: { result, code, message, data }

Rate limits

10 requests/second per IP and per account (weight-based); HTTP 429 when exceeded

Cost to use

Free — you only pay normal trading fees


2. What you can build

The API is grouped into four families of endpoints. Pick the family that matches what you want to build; you can mix freely.

2.1 Trade API — Spot trading

The bread-and-butter. Buy and sell crypto with funds you already hold.

  • Get all your balances

  • List trading pairs and their rules (minimum order size, fee rate, decimal precision)

  • Place limit and market orders

  • Cancel orders, list open orders, fetch order history

  • Get your recent fills (executed trades)

2.2 Bot API — Automated strategies

Bot API is available to all accounts — no application needed. Enable the Bot Reading / Bot Trading permissions on your API key.

Pionex's signature feature. Spin up trading bots — and tune them — programmatically.

  • Spot Grid bots — buy low, sell high inside a price range, repeatedly

  • Futures Grid bots — same idea, with leverage

  • AI Strategy — let Pionex suggest grid parameters for you

  • Adjust profit rate or price range on a live bot

  • Reduce position by a percentage, or cancel the bot entirely

2.3 Futures API — Futures Trading

Perpetual contracts with leverage (the maximum depends on the symbol).

Direct futures trading via API is not available. This capability is still in internal development and has not been released to any account — there is no application, waitlist, or early-access process.

  • Open and close long and short positions

  • Set leverage and margin mode (isolated or cross)

  • Switch between one-way and hedge position mode

  • View unrealized PnL, mark price, liquidation price

  • Pull funding fee history

2.4 Earn API — Passive yield (beta)

Lower-effort products for users who want yield rather than active trading.

  • Browse Dual Investment products

  • View current strike prices, UP APY, DOWN APY

  • Subscribe to a product, list active investments, view history

Note: Earn endpoints are in beta and may not be available in every region.


3. Before you start

What you need

  1. A Pionex account in good standing, fully verified if your jurisdiction requires it.

  2. Two-factor authentication enabled — required to create an API key.

  3. A development environment — anything that can make HTTPS requests. Python 3.9+ or Node.js 18+ are the friendliest choices because almost every example online is written in one of them.

  4. Basic familiarity with:

    • JSON (you've seen { "key": "value" } before)

    • Environment variables, or some way to keep secrets out of your code

    • Running a script from the terminal

What you do not need

  • A server. You can run from your laptop.

  • A paid plan. The API is free.

  • A degree in cryptography. The signing logic is around ten lines of code.

Mental model: how a request works

Every authenticated call follows the same five-step pattern:

  1. You build a request URL, for example GET /api/v1/account/balances?timestamp=...

  2. You assemble a "canonical message" string from the method, path, sorted query parameters, and body.

  3. You hash that string with HMAC-SHA256 using your API secret. This produces a signature.

  4. You send the request with two extra headers: PIONEX-KEY and PIONEX-SIGNATURE.

  5. Pionex re-runs the exact same hash on its side and compares. If they match, you're authenticated.

Key idea: the signature proves you know the secret without ever sending the secret over the wire.


4. Create your first API key

Step 1 — Open the API management page

  • Web: Log in, click your profile avatar, and choose API Management — or open https://www.pionex.com/en/my-account/api directly.

  • Mobile app: The app has no built-in API menu. Open API Management via the web page — open pionex.com in a mobile browser, or tap Click Here to open that page inside the app (in-app webview).

From API Management you can also edit an existing key's permissions, label, and IP whitelist, or delete (revoke) a key. The Secret cannot be regenerated or reset — if you lose it, delete the key and create a new one.

Step 2 — Create a new API key

Click Create API Key. You'll be asked for:

  • Label — name it something specific like grid-bot-laptop or read-only-portfolio. You'll thank yourself later when you have multiple keys.

  • Permissions — see the next section.

  • IP whitelist (optional but strongly recommended) — restrict the key so it only works from specific IP addresses. You can enter multiple IPs separated by commas.

Step 3 — Choose permissions carefully

Permission

What it allows

Recommendation

Read

View balances, orders, positions, fills

Always enable. Required for anything useful.

Trade (Write)

Place and cancel orders, create / adjust / close bots

Enable only if your script truly needs to trade.

Bot API permissions

Bot API keys have two separate toggles:

  • Bot Reading (view bot orders, validate parameters),

  • Bot Trading (create/adjust/cancel bots).

No separate access request — enable the toggles you need on the key

Step 4 — Save the secret immediately

When you click Confirm, Pionex shows you two strings:

  • API Key (sometimes called apiKey or PIONEX-KEY) — public-ish, like a username

  • Secret — shown once, never again. Treat it like a password. If you lose it, you must delete the key and create a new one.

Copy both into a safe place. The recommended workflow is to set them as environment variables in your shell profile, for example:

export PIONEX_KEY="paste_your_api_key_here"
export PIONEX_SECRET="paste_your_secret_here"

Warning: never paste keys into source code that touches a public or shared repository.

Step 5 — Test connectivity (no auth required)

Before you sign anything, prove the network works:

curl "https://api.pionex.com/api/v1/common/symbols?symbol=BTC_USDT"

You should get a JSON envelope listing the trading rules for BTC_USDT. If this fails, fix your network or firewall before going further. Auth bugs are infinitely harder to debug if the basics aren't working.


5. Core concepts

5.1 Base URLs

Purpose

URL

Spot, Bot, Earn (REST)

Futures (REST)

Public WebSocket

Watch out: the futures path prefix is /uapi/v1, not /api/v1. Mixing them up is a common first-day mistake.

5.2 The response envelope

Every Pionex JSON response has this outer shape:

Success: { "result": true, "data": { ... }, "timestamp": 1783990000000 }
Error: { "result": false, "code": "APIKEY_LOST", "message": "Apikey lost", "timestamp": ... }

code and message appear only on errors, and codes are usually strings (e.g. APIKEY_LOST, BOT_INVALID_ARGUMENT). Note that errors — including authentication failures — usually come back as HTTP 200 with result: false, so always check result, not just the HTTP status.

Some account-level rejections use a different shape: a numeric code, a reason string, and no result field. For example:

{ "code": 40300951, "reason": "P_TRADING_BOT_OPERATION_IS_FORBIDDEN", "message": "Operation is forbidden, banned for account frozen", "data": null }

Treat a response as failed if result is false, or if result is missing and code is present.

Tip: always check result before reading data. Even HTTP 200 responses can have result: false for business-logic errors such as "insufficient balance."

5.3 Symbol naming

Market

Format

Example

Spot

BASE_QUOTE

BTC_USDT, ETH_USDT, SOL_BTC

Perpetual futures

BASE_QUOTE_PERP

BTC_USDT_PERP, ETH_USDT_PERP

Always use the underscore separator and uppercase letters.

5.4 Timestamps

  • Always milliseconds since epoch — not seconds. This is a frequent mistake from people coming from Unix tools.

  • Goes in the query string, never in the body, even on POST requests.

  • Pionex tolerates ±20 seconds of clock skew but not much. If your machine's clock is wrong, signing will fail with "timestamp out of recv window." Sync your system clock if you see this.

5.5 Status codes

Code

Meaning

What to do

200

Success (still check result)

Proceed

400

Bad parameter

Check spelling, types, and required fields

401

Unauthorized

API key or signature is wrong

403

Forbidden

Re-check key permissions. Direct futures trading is not available to any account — there is no futures access to request.

429

Rate-limited

Back off. See the Rate Limits section.

500

Server error

Retry with exponential backoff


6. Authentication: how request signing works

This is the section that intimidates newcomers. It shouldn't. Once you see one working example, the rest is mechanical.

6.1 The canonical message

For every authenticated request, you build a single string:

{METHOD}{PATH}?{SORTED_QUERY}{BODY}

Rules:

  1. METHOD is uppercase: GET, POST, DELETE.

  2. PATH is the URL path including the leading slash, for example /api/v1/account/balances.

  3. SORTED_QUERY is the query string with parameters sorted alphabetically by key and URL-encoded.

  4. BODY is the JSON request body for POST requests, with no whitespace. In Python: json.dumps(separators=(',',':')). In JavaScript, JSON.stringify(obj) produces the same.

  5. Drop any None or undefined parameters entirely. Never send key=None.

  6. Even on POST, the timestamp parameter goes in the query, not the body.

6.2 Worked example: signing a balance check

Request:

GET /api/v1/account/balances?timestamp=1701234567890

The canonical message you sign:

GET/api/v1/account/balances?timestamp=1701234567890

Feed that string and your secret into HMAC-SHA256, take the hex digest, and place it in the PIONEX-SIGNATURE header.

6.3 Python reference implementation

import hmac import hashlib import time import os from urllib.parse import urlencode import requests  API_KEY = os.environ["PIONEX_KEY"] API_SECRET = os.environ["PIONEX_SECRET"] BASE_URL = "https://api.pionex.com"  def sign_get(path, params=None):     params = dict(params or {})     params["timestamp"] = int(time.time() * 1000)     query = urlencode(sorted(params.items()))     message = f"GET{path}?{query}"     signature = hmac.new(         API_SECRET.encode(),         message.encode(),         hashlib.sha256,     ).hexdigest()     headers = {         "PIONEX-KEY": API_KEY,         "PIONEX-SIGNATURE": signature,     }     return f"{BASE_URL}{path}?{query}", headers  url, headers = sign_get("/api/v1/account/balances") response = requests.get(url, headers=headers).json() print(response)

6.4 JavaScript / Node.js reference implementation

import crypto from "node:crypto";  const API_KEY = process.env.PIONEX_KEY; const API_SECRET = process.env.PIONEX_SECRET; const BASE_URL = "https://api.pionex.com";  function signGet(path, params = {}) {   const allParams = { ...params, timestamp: Date.now() };   const query = new URLSearchParams(     Object.entries(allParams).sort(([a], [b]) => a.localeCompare(b))   ).toString();   const message = `GET${path}?${query}`;   const signature = crypto     .createHmac("sha256", API_SECRET)     .update(message)     .digest("hex");   return {     url: `${BASE_URL}${path}?${query}`,     headers: {       "PIONEX-KEY": API_KEY,       "PIONEX-SIGNATURE": signature,     },   }; }  const { url, headers } = signGet("/api/v1/account/balances"); const r = await fetch(url, { headers }); console.log(await r.json());

6.5 Signing a POST request

The body is part of the canonical message. Construct it once, sign it, then send the same exact bytes as the request body.

import json  def sign_post(path, body):     timestamp = int(time.time() * 1000)     query = urlencode([("timestamp", timestamp)])     body_str = json.dumps(body, separators=(",", ":"))  # no spaces     message = f"POST{path}?{query}{body_str}"     signature = hmac.new(         API_SECRET.encode(),         message.encode(),         hashlib.sha256,     ).hexdigest()     return (         f"{BASE_URL}{path}?{query}",         {             "PIONEX-KEY": API_KEY,             "PIONEX-SIGNATURE": signature,             "Content-Type": "application/json",         },         body_str,     )  url, headers, body_str = sign_post(     "/api/v1/trade/order",     {         "symbol": "BTC_USDT",         "side": "BUY",         "type": "LIMIT",         "quantity": "0.001",         "price": "30000.00",     }, ) requests.post(url, headers=headers, data=body_str).json()

Pitfall: if you let your HTTP library re-serialize the body (for example requests.post(json=...)), it may add whitespace and your signature will mismatch. Always send the same bytes you signed (data=body_str).


7. Beginner walkthrough: read your account

Goal: print your balances and the rules for BTC_USDT. About 15 minutes. No risk — read-only key.

Step 1 — Get all symbols (no auth)

import requests r = requests.get(     "https://api.pionex.com/api/v1/common/symbols",     params={"symbol": "BTC_USDT"}, ) print(r.json()["data"]["symbols"][0])

You'll learn minQuantity, minAmount, baseScale, and makerFeeRate — values you'll need before placing real orders.

Step 2 — Sign your first call: account balances

Using the sign_get helper from section 6.3:

url, headers = sign_get("/api/v1/account/balances") data = requests.get(url, headers=headers).json()  for b in data["data"]["balances"]:     if float(b["free"]) > 0 or float(b["locked"]) > 0:         print(f"{b['coin']}: free={b['free']}, locked={b['locked']}")

If you see a 401 or result: false, revisit the auth section. If you see your real balances, you're authenticated.

Step 3 — Combine: portfolio value in USDT

You now have everything to compute a "total portfolio value in USDT":

  1. Fetch balances.

  2. For each non-zero coin, fetch the current price from a public ticker endpoint.

  3. Sum (free + locked) * price.

That's a complete, safe, read-only project — perfect for a first weekend.


8. Intermediate: place and manage orders

8.1 Place a limit order

url, headers, body = sign_post("/api/v1/trade/order", {     "symbol": "BTC_USDT",     "side": "BUY",     "type": "LIMIT",     "quantity": "0.001",     "price": "30000.00",     "clientOrderId": "my-order-001" }) print(requests.post(url, headers=headers, data=body).json())

Tip: always set clientOrderId if your code might retry. Without it, a retry can duplicate an order, leaving you with two open positions instead of one.

8.2 Cancel an order

DELETE /api/v1/trade/order?symbol=BTC_USDT&orderId=123456789

Sign exactly like a GET (no body).

8.3 List open orders

GET /api/v1/trade/openOrders?symbol=BTC_USDT

8.4 Walk historical orders (pagination)

GET /api/v1/trade/allOrders?symbol=BTC_USDT&limit=100&fromId={lastSeenId}

Keep calling with the fromId of the last order you saw, until you get fewer than limit results back.

8.5 Validate orders before sending

From /common/symbols, you got these fields. Use them on the client side:

  • quantity >= minQuantity

  • quantity <= maxQuantity

  • quantity * price >= minAmount (the "minimum notional" rule)

  • Round quantity to baseScale decimals, and price to quoteScale decimals

Skipping these checks is the second-most-common cause of order-rejection support tickets.

8.6 Market data endpoints

All public, no signature needed:

  • GET /api/v1/market/klines?symbol=BTC_USDT&interval=1M&limit=100 — candlesticks

  • GET /api/v1/market/tickers — 24h stats for all symbols

  • GET /api/v1/market/bookTickers — best bid/ask

  • GET /api/v1/market/depth?symbol=BTC_USDT&limit=10 — order book

  • GET /api/v1/market/trades?symbol=BTC_USDT&limit=50 — recent trades

Tip: these also accept perpetual symbols (e.g., BTC_USDT_PERP). There is no working /uapi/v1/market/... — futures market data goes through these /api/v1 endpoints.

Futures market data (also public):

  • GET /api/v1/market/fundingRates?symbol=BTC_USDT_PERP&limit=500 — historical funding rates. limit defaults to 1, so set it. Page backward with endTime.

  • GET /api/v1/market/indexes?symbol=BTC_USDT_PERP — current index price, mark price and next funding rate.

  • GET /api/v1/market/indexKlines and GET /api/v1/market/markKlines — index and mark price candles. Latest bars only: these endpoints accept endTime but ignore it.

  • GET /api/v1/market/openInterests — current snapshot only, every symbol in one response. It takes no parameters and ignores symbol.

Limits and depth. The maximum limit is 500 on klines, index and mark klines, and funding rates; a higher value returns MARKET_PARAMETER_ERROR. Daily futures candles go back to early 2023 for BTC, ETH and SOL. Intraday candles stop at about 10,000 bars, which is roughly 14 months of 1-hour bars. Funding rates go back to early 2023.


9. Advanced topics

9.1 Spot Grid bots

A grid bot is a parameterized strategy: pick a price range and a number of grid lines. Profit per grid follows from those two settings. The bot accumulates as price falls and sells as it rises, profiting from oscillation.

POST /api/v1/bot/orders/spotGrid/create{  "base": "BTC",  "quote": "USDT",  "buOrderData": {    "top": "50000",    "bottom": "40000",    "row": 20,    "gridType": "arithmetic",    "quoteTotalInvestment": "1000"  }}

Tip: validate first with POST /api/v1/bot/orders/spotGrid/checkParams (same body) — it returns the minimum and maximum investment, recommended slippage, and estimated fees without spending any funds.

Funding and risk. A spot grid never borrows, so your maximum loss is the amount you invest. Only two calls add funds to a running spot grid: investIn, and adjustParams with quoteInvest. Borrowing exists only in Leveraged Grid, which is a futures grid. Spot grid responses include loanAmount, interestAmount, liquidatePrice and leverage; on a spot grid these are always 0, 0, 0 and 1.

Once it's running you can:

  • POST /api/v1/bot/orders/spotGrid/adjustParams — change the price range (top/bottom) or grid count (row) live

  • POST /api/v1/bot/orders/spotGrid/investIn — add funds to the running bot

  • POST /api/v1/bot/orders/spotGrid/profit — extract accumulated profit without stopping the bot

  • POST /api/v1/bot/orders/spotGrid/cancel — stop the bot. Set closeSellModel on this call (see Closing a spot grid below)

  • GET /api/v1/bot/orders/spotGrid/aiStrategy?base=BTC&quote=USDT — get AI-suggested parameters (note: base and quote, not symbol)

Closing a spot grid. closeSellModel on the cancel call decides what happens to the coin the bot holds:

  • NOT_SELL (default) — return the coin and the quote as they are.

  • TO_QUOTE — sell the coin into the quote currency.

  • TO_USDT — sell the coin into USDT.

Set it on the cancel call. When you cancel through the API, the closeSellModel you set at creation is not used. If the cancel call leaves it out, NOT_SELL applies. The order's closeSellModel field shows the creation value while the bot runs, and the value that was applied after cancellation. The amount sold is rounded down to the coin's precision; any remainder is returned as coin.

Reading a closed spot grid. After cancellation, GET /api/v1/bot/orders/spotGrid/order reports what came back:

  • unlockUsdtAmount — quote returned at close: quoteAmountBeforeSell plus the proceeds of any coin sold, minus the trading fee.

  • baseAmount — coin returned without being sold.

  • profitWithdrawn — profit already taken out with spotGrid/profit while the bot ran. It is not part of unlockUsdtAmount.

Net result over the bot's life: unlockUsdtAmount + profitWithdrawn + value of returned baseAmount − quoteTotalInvestment. totalFeeInQuote and totalFeeInBase do not include the fees for the opening purchase or the closing sale.

9.2 Futures Grid bots

Same shape as spot grids, with a leverage parameter:

POST /api/v1/bot/orders/futuresGrid/create
{
"base": "BTC.PERP", // note the .PERP suffix on base
"quote": "USDT",
"buOrderData": {
"top": "65000", "bottom": "60000", "row": 10,
"gridType": "arithmetic",
"trend": "long", // REQUIRED: long | short | no_trend
"leverage": 2,
"quoteInvestment": "100"
}
}

Tip: validate first with POST /api/v1/bot/orders/futuresGrid/checkParams (same body — trend is required here too) — it returns min/max investment, estimated liquidation prices, margin split, and fees, without spending any funds.

Once it's running you can:

  • POST /api/v1/bot/orders/futuresGrid/adjustParams — with type=adjust_params, change the price range (top/bottom) or grid count (row); with type=invest_in, add investment

  • POST /api/v1/bot/orders/futuresGrid/reduce — close part of the position while the bot keeps running (reduceNum is an integer grid-line count, not a coin amount)

  • POST /api/v1/bot/orders/futuresGrid/cancel — stop the bot; the optional closeSellModel (TO_QUOTE or TO_USDT) decides what happens to the position

  • GET /api/v1/bot/orders/futuresGrid/order?buOrderId=... — fetch full order detail (status, PnL, position, liquidation price)

Which account funds a bot: futuresGrid/create takes quoteInvestment from your Primary Account, not your Futures or Trader account. Transfer to your Primary Account first, or the request is refused with balance insufficient.

checkParams is not a guarantee: passing it means your settings are well formed, not that create will succeed. Check that your Primary Account balance covers quoteInvestment as well.

If adjustParams is refused, read code first (see the FAQ). One cause you may hit is a bot whose unrealized PnL is negative — a grid is often in loss exactly when its range needs adjusting. Retry when the position is in profit, edit the range in the Pionex app, or enable Trailing Move at creation.

9.3 Smart Copy bots

The third bot type available via API — a portfolio of signal-driven futures positions:

  • POST /api/v1/bot/orders/smartCopy/checkParams — validate investment and leverage limits before creating

  • POST /api/v1/bot/orders/smartCopy/create — note this endpoint uses snake_case fields (bu_order_data, quote_total_investment) and requires a portfolio array with at least one item (base, signal_type, leverage)

  • GET /api/v1/bot/orders/smartCopy/order?buOrderId=... — full order detail including per-item positions

  • POST /api/v1/bot/orders/smartCopy/cancel — body uses bu_order_id

Related: POST /api/v1/bot/signal/listener posts custom trading signals to drive these bots — it requires account activation (email service@pionex.com) and the "Enable Reading" permission on your API key. GET /api/v1/bot/kol/selectCopyTradeList?shareCode=... lists curated KOL copy-trade strategies.

The signal listener is for signal providers. It pushes a signal to the Pionex signal platform, which forwards it to every Smart Copy bot subscribed to that signalType (your signal's UUID).

In data: action is buy to open a position or sell to close it. position_size is the target position as a fraction: "1" is 100%, and "0" closes the position. contracts is the number of contracts.

9.4 Futures direct trading

Note the /uapi/v1 path prefix:

GET  /uapi/v1/account/balances
GET /uapi/v1/account/positions
GET /uapi/v1/account/detail
GET /uapi/v1/account/leverage?symbol=BTC_USDT_PERP
GET /uapi/v1/trade/openOrders
GET /uapi/v1/trade/fills?symbol=BTC_USDT_PERP
GET /uapi/v1/trade/fundingFee?symbol=BTC_USDT_PERP
GET /uapi/v1/trade/isolatedMode?symbol=BTC_USDT_PERP

Note: All the GET (read) endpoints above work for any API key today. Write operations (placing futures orders, changing leverage/margin mode) are restricted while direct futures trading remains under development.

9.5 Earn — Dual Investments (beta)

GET  /api/v1/earn/dual/openProducts?symbol=BTC POST /api/v1/earn/dual/invests   { "productId": "...", "amount": "0.5" } GET  /api/v1/earn/dual/balances

Read the strike price, UP APY, and DOWN APY before subscribing. Funds are locked for the product duration.

9.6 WebSocket basics

wss://ws.pionex.com/wsPub

Two channel categories:

  • Public (no auth required) — ticker, kline, depth, trade

  • Private (auth required) — balance updates, order updates, position updates

Subscribe with a JSON message:

{ "op": "SUBSCRIBE", "topic": "TRADE", "symbol": "BTC_USDT" }

Important: WebSocket connections drop. Wrap your client in a reconnect-with-backoff loop and re-subscribe to all topics on reconnect.


10. Rate limits and reliability

10.1 What you get back

Pionex does not return X-RateLimit-* headers. The limits are 10 requests/second per IP and 10 requests/second per account (private endpoints), with each endpoint carrying a weight against that budget. Exceeding it returns HTTP 429 — back off before retrying.

10.2 How to stay safe

  1. Don't poll at full speed. A GET /openOrders every 200 ms is unnecessary; once a second is plenty for most strategies.

  2. Use WebSockets for change-driven data. Don't poll for price ticks — subscribe.

  3. Implement exponential backoff on 429 and 5xx responses:

import time, random  def with_backoff(fn, max_attempts=6):     for i in range(max_attempts):         r = fn()         if r.status_code not in (429, 500, 502, 503):             return r         sleep = (2 ** i) + random.random()         time.sleep(sleep)     raise RuntimeError("max retries exceeded")
  1. Batch where possible. Need 50 orders' status? Call GET /trade/allOrders once with a high limit, not 50 individual lookups.


11. Frequently Asked Questions

Getting started

Q: Do I need to apply for API access?

A: No — for spot, earn, and the Bot API, create a key and start; the Bot API only needs its Bot Reading / Bot Trading permissions enabled on the key. Direct futures trading is not available to any account, and there is no application or waitlist, but futures read endpoints work for every API key. Earn endpoints are in beta and may not be enabled for every region.

Q: Is the API free?
A: Yes. You only pay normal trading fees (the same rates as on the website).

Q: Can I use it from a browser?
A: Yes, but with care. Browsers can't keep secrets — anyone who inspects your page can read them. Either run the signing logic in a backend you control, or only use read-only keys with strict IP and origin restrictions, and never deploy a Trade-permission key client-side.

Q: Which programming language is best?

A: Python and JavaScript have the most examples. Anything that can do HTTPS plus HMAC-SHA256 works: Go, Rust, Java, C#, PHP, Ruby. The signing logic is around ten lines in any of them.

Q: Can I use the Pionex API to connect to external platforms?

A: Yes — it's a standard REST/WebSocket API, so anything that can make signed HTTPS requests can talk to it, including your own scripts, servers, and third-party tools. Whether a specific third-party platform works depends on whether that platform has built Pionex support on its side — the API doesn't restrict who calls it, but both sides have to speak the same integration. Check the platform's own documentation for whether it lists Pionex, and which of its integration methods it expects you to use. Pionex-side, the supported hooks are the Trade/Bot/Wallet/Earn endpoints in this guide plus Signal Bot for TradingView webhooks.

Q: Can I connect the Pionex API to other crypto exchanges like Bybit or Binance?

A: No. The Pionex API is not intended to be connected to other crypto exchanges, such as Bybit or Binance. It's designed only to interact with your own Pionex account — placing/managing your own orders, bots, and positions — not to bridge, mirror, or arbitrage trading activity with other exchange accounts.

Authentication

Q: My signature keeps coming back invalid. Where do I start?

A: Five things to check, in this order:

  1. Are query parameters sorted alphabetically?

  2. Is timestamp in the query, not the body?

  3. Does the body you sign exactly match the body you send (no extra whitespace)?

  4. Is your machine's clock within a few seconds of real time?

  5. Are PIONEX-KEY and PIONEX-SIGNATURE headers both present and not swapped?

Q: Why is timestamp in the query for POST requests?

A: That's how Pionex defines the canonical-message rule. It's a convention, not negotiable. If you put it in the body, your signature will mismatch.

Q: Can I rotate keys without downtime?
A: Yes — create a new key, deploy it to your code, then revoke the old one. Both work simultaneously during the overlap.

Q: Can I have multiple keys?
A: Yes. Create one key per use case (bot-prod, dashboard-readonly, dev-laptop). It makes revocation surgical when something goes wrong.

Trading

Q: What's the difference between quantity and amount?

A: quantity is the base currency amount (e.g., 0.5 BTC). amount is the quote currency value (e.g., 25,000 USDT). minQuantity and minAmount from /common/symbols enforce both at once: an order must satisfy both.

Q: My order keeps getting rejected with "minimum notional".

A: quantity * price must be at least minAmount. A 0.0001 BTC order at $30,000 equals $3 notional, which is often below the typical $10 minimum.

Q: How do I make my order placement idempotent?
A: Set clientOrderId to a unique value (for example, a UUID). If you retry the same clientOrderId, Pionex will not duplicate the order.

Q: Are partial fills possible on limit orders?

A: Yes. Watch filledQuantity and status (PARTIALLY_FILLED). Use the WebSocket order-update channel for real-time state.

Q: Are there test or sandbox endpoints?

A: Pionex does not currently publish a public sandbox. Standard practice is: develop with read-only keys, then place tiny real orders with quantity = minQuantity against a low-volume pair as a smoke test.

Bots

Q: Can I create the same bot types I see in the app?
A: Exactly three bot types are exposed via API: Spot Grid, Futures Grid, and Smart Copy. All other bot types in the app (Martingale, DCA, Rebalancing, Infinity Grid, TWAP, arbitrage, Smart Trade) are UI-only and have no API endpoints.

GET /api/v1/bot/orders returns only the bot types the API supports. Their buOrderType values are spot_grid, futures_grid, future_hedge_grid (Cross Margin Futures Grid) and smart_copy. Bots of other types are not returned, even if they are running on your account. Passing an unsupported type as a filter returns BOT_INVALID_ARGUMENT.

Leveraged Grid is a futures grid. It is returned as futures_grid.

Futures Lite has no bot endpoints. Its holdings appear only in GET /api/v1/wallet/balancesFull, under botAccount.detail[] with type: "futures_lite". Each entry gives buOrderId, baseList, investmentAmount and profit. No status, order or position detail is available.

Q: Can I tune a running bot?
A: Yes. adjustParams lets you change the price range (top/bottom) and grid count (row), or add investment, without canceling. On spot grids you can also investIn (add funds) and profit (withdraw profit); on futures grids you can reduce the position. There is no profit-rate parameter — profit per grid follows from the range and grid count.

Q: I'm getting BOT_INTERNAL_ERROR and I can't tell why.
A: Check the code field. It now tells you which of two things happened.

code

What it means

What to do

BOT_INVALID_ARGUMENT

Your request was refused. message says why — for example balance insufficient.

Fix what message names, then send it again.

BOT_INTERNAL_ERROR

Something failed on our side. message is always Internal error.

Retry with backoff. If it continues, contact support with your timestamps.

A common reason for a refused futuresGrid/create is too little quote currency in your Primary Account. Bot creation draws from your Primary Account, not from your Futures or Trader account.

If BOT_INTERNAL_ERROR comes back for something message should have explained, send support your timestamps.

Q: How does reduce differ from cancel?

A: reduce closes a percentage of the position but the bot keeps running. cancel stops the bot entirely.

Q: What does the aiStrategy endpoint actually do?
A: It returns Pionex-suggested grid parameters for a symbol, based on recent volatility. Treat it as a starting point, not gospel — review before deploying capital.

Futures

Q: How do I get access to the Futures API?

A: Direct Futures API trading is not available to any account. It remains in internal development, and there is no application, waitlist, or early-access process — requesting access is not possible.

Q: Why do I get “TRADE_TYPE_DENIED: user denied, not in whitelist” when placing a futures order through the API?
A: Direct futures trading via API (placing futures orders, or changing leverage or margin mode) is not available to any account yet. The capability is still in internal development, and there is no application, waitlist, or early-access process, so the “whitelist” in the error message does not mean you can apply for access. No release date has been announced. Read-only futures endpoints work with any API key. To automate futures trading today, you can create and manage Futures Grid bots through the Bot API, or use Signal Bot to trigger trades from external signals such as TradingView webhooks.

Q: What's the difference between isolated and cross margin?

A:

Isolated — only the margin you assigned to that position can be lost.

Cross — your entire futures wallet backs the position. Isolated is safer for learners.

One-way vs hedge mode?

A:

One-way — one position per symbol; opening the opposite side reduces or closes. Hedge — long and short can coexist. Most traders should start with one-way.

Q: How do funding fees show up?

A: Periodically (typically every eight hours, but check the symbol). Use GET /uapi/v1/trade/fundingFee to pull the historical record.

Earn

Q: Are dual investments principal-protected?

A: No. They have a "DOWN APY" floor in yield, but the underlying amount is at risk. Read the per-product details before subscribing.

Q: Can I cancel a dual investment early?
A: Generally no. Funds are locked for the product duration. Plan your liquidity accordingly.

Operational

Q: What rate limits should I plan for?
A: Plan for 10 requests/second per IP and per account (Pionex does not return X-RateLimit-* headers). A defensive starting point is no more than five requests per second per family of endpoints, with exponential backoff on 429 responses.

Q: How do I handle a 5xx error?

A: Retry with exponential backoff and jitter. Crucially, before retrying a POST, query state to confirm whether the prior request actually succeeded — server errors don't always mean the action failed.

Q: My WebSocket keeps dropping. Is something wrong?

A: That's normal at the network level. Implement: ping every 30 seconds, automatic reconnect with backoff, and re-subscribe to all topics on reconnect.

Q: How do I subscribe to multiple symbols?
A: Send multiple subscribe messages, or use the bulk-subscribe form supported by the channel. Each topic is independent.

Security

Q: I think my secret leaked. What do I do?

A:

  1. Open API Management and revoke the key immediately.

  2. Audit recent activity (orders, withdrawals if enabled).

  3. Create a new key with a new label.

  4. Search your codebase and commit history for the leaked secret, and rotate any related credentials.

Q: Should I commit my key or secret to git?

A: Never. Use environment variables, a .env file (in .gitignore), or a secrets manager. If you commit by accident, rotate the key immediately — git history is forever.

Q: Can I enable deposit/withdraw permission?
A: There's no deposit or withdrawal function in the API management. Currently, the API endpoint is only available for trades and bots.

Q: Can I restrict a key by IP?

A: Yes — strongly recommended for any key with Trade permission. Set the IP addresses of your server or workstation.

Q: Does Pionex see my secret?

A: Pionex stores a one-way hash, not the plaintext. They use it to verify your signatures the same way you generate them. That's why they can show you the secret only once.


12. Troubleshooting cheat-sheet

Symptom

Most likely cause

Fix

401 on every request

Wrong key or signature mismatch

Re-check sort order, body bytes, headers

401 only on POST

Body re-serialized after signing

Send the exact signed string as the body

result: false with timestamp error

Clock drift

Sync your system time

403

Permission not granted

Re-check key permissions. Direct futures trading is not available to any account.

429

Rate-limited (up to 24 hour from last request)

Add backoff; reduce poll frequency

Order rejected — minimum notional

quantity * price < minAmount

Increase order size

Order rejected — precision

Too many decimals

Round to baseScale / quoteScale

Bot won't start — BOT_INVALID_ARGUMENT

message names the reason, e.g. balance insufficient

Fix what message names. For funds, top up your Primary Account — Futures and Trader do not count

Bot won't start — BOT_INTERNAL_ERROR

Fault on our side

Retry with backoff; contact support if it continues

Bot won't start — P_TRADING_BOT_OPERATION_IS_FORBIDDEN, "account frozen"

The account is restricted

Contact support. Retrying will not help

WebSocket disconnects

Normal, or firewall idle-timeout

Reconnect with backoff; ping every 30 seconds

Signature works in curl, not in code

Library auto-encoding the body

Send raw signed bytes


13. Security best practices

  1. One key per use case. Easier to revoke, easier to audit.

  2. Least privilege. Read-only is the default; enable Trade only if needed.

  3. IP whitelist any key that can move money or place orders.

  4. Never log the secret. Strip auth headers from request logs.

  5. Never put the secret in client-side code. Browsers, mobile apps — assume any code shipped to a user is publicly readable.

  6. Rotate periodically. Every 90 days is a reasonable cadence; immediately on suspicion.

  7. Monitor usage. Pionex shows API key usage stats — review them weekly.

  8. Review code for accidental commits. Tools like git-secrets, trufflehog, or GitHub secret scanning catch leaks early.

  9. Use a secrets manager in production: AWS Secrets Manager, HashiCorp Vault, 1Password CLI, Doppler — anything but plain text on disk.

  10. Test on a small account. Don't aim a fresh trading bot at your main account on day one.


14. Glossary

Term

Definition

API key / Secret

Your username-and-password pair for the API. The secret signs requests; the key identifies you.

HMAC-SHA256

A keyed hash function. Same input plus same secret produces the same output, but you can't recover the secret from the output.

Canonical message

The exact string both you and Pionex hash to compare signatures.

Quote currency

The second asset in a pair (USDT in BTC_USDT).

Base currency

The first asset in a pair (BTC in BTC_USDT).

Notional

quantity × price — the dollar (or quote-asset) value of a trade.

Maker / Taker

Maker adds liquidity (your order rests on the book). Taker removes liquidity (your order matches an existing one).

Mark price

Pionex's reference price for futures, used for liquidations and unrealized PnL.

Funding fee

Periodic payment between longs and shorts on perpetual futures.

Liquidation price

The price at which a leveraged position is force-closed.

Idempotent

An operation safe to retry — same input produces the same effect. Use clientOrderId for idempotent order placement.

Rate limit

Maximum requests per time window before you're throttled.

WebSocket

A persistent, bidirectional connection — ideal for push notifications.

Strike price (Earn)

The price threshold that determines UP vs DOWN APY at maturity.


15. Where to go next

A suggested learning path:

  1. Build the read-only portfolio script from section 7.

  2. Place your first $10 limit order with clientOrderId retries.

  3. Spin up a tiny Spot Grid bot ($50 investment, narrow range) and watch it for a week.

  4. Layer in a WebSocket private channel to log fills as they happen.

  5. Move to futures only after you've operated spot bots for at least a month.

The official Pionex documentation has the latest endpoint list and any beta notices: https://www.pionex.com/docs/.

If you have any other questions regarding API, we sincerely invite you to join the Telegram group for better assistance: https://t.me/pionexapi

Final tip: if you hit a wall, the most useful debugging step is almost always to print your canonical message string and your signature side-by-side with a working curl example, and look for one character that differs. That one character is virtually always the bug.


What are the limitations of the API for futures trading and trading bots?

The API provided by Pionex is designed to facilitate trading activities, but it has specific limitations regarding futures trading and the use of trading bots. Below is a detailed explanation of these limitations:

  • Spot API (Manual Trade)

The API currently supports spot trading only. This means that users can execute trades for assets available in the spot market through the API. Spot trading involves the immediate exchange of assets at current market prices.

  • Futures API (Manual Trade) Exclusions

Direct Futures API trading is not available — it is still in internal development and has not been released to any account. There is no application or waitlist process. Supported alternatives:

  • Bot API: This includes support for creating and closing Futures Grid bots, which can serve as a temporary solution for automated futures strategies.

  • Signal Bot: You can also utilize the Signal Bot to execute trades based on external triggers or custom signals.

Happy building.

Did this answer your question?