BitMart Spot Trading
Overview
| # | Category | API Endpoint | Type | Description |
|---|----------|-------------|------|-------------|
| 1 | Market Data | GET /spot/quotation/v3/ticker | READ | Get single pair ticker |
| 2 | Market Data | GET /spot/quotation/v3/tickers | READ | Get all pair tickers |
| 3 | Market Data | GET /spot/quotation/v3/books | READ | Order book depth (max 50) |
| 4 | Market Data | GET /spot/quotation/v3/trades | READ | Recent public trades (max 50) |
| 5 | Market Data | GET /spot/quotation/v3/klines | READ | Historical K-line/candlestick |
| 6 | Market Data | GET /spot/quotation/v3/lite-klines | READ | Latest K-line data |
| 7 | Market Data | GET /spot/v1/symbols/details | READ | Trading pair details |
| 8 | Market Data | GET /spot/v1/symbols | READ | Trading pair list |
| 9 | Market Data | GET /spot/v1/currencies | READ | All supported currencies |
| 10 | Account | GET /account/v1/wallet | READ | Account balance (all wallets) |
| 11 | Account | GET /spot/v1/wallet | READ | Spot wallet balance |
| 12 | Account | GET /spot/v1/trade_fee | READ | Actual trade fee rate |
| 13 | Account | GET /spot/v1/user_fee | READ | Base fee rate (account tier) |
| 14 | Margin Account | GET /spot/v1/margin/isolated/account | READ | Isolated margin account details |
| 15 | Margin Account | GET /spot/v1/margin/isolated/pairs | READ | Borrowing rate & amount |
| 16 | Margin Account | GET /spot/v1/margin/isolated/borrow_record | READ | Borrow record |
| 17 | Margin Account | GET /spot/v1/margin/isolated/repay_record | READ | Repayment record |
| 18 | Trading | POST /spot/v2/submit_order | WRITE | Place single order |
| 19 | Trading | POST /spot/v1/margin/submit_order | WRITE | Place margin order |
| 20 | Trading | POST /spot/v4/batch_orders | WRITE | Batch orders (max 10) |
| 21 | Trading | POST /spot/v3/cancel_order | WRITE | Cancel single order |
| 22 | Trading | POST /spot/v4/cancel_orders | WRITE | Cancel multiple orders |
| 23 | Trading | POST /spot/v4/cancel_all | WRITE | Cancel all open orders |
| 24 | Order Query | POST /spot/v4/query/order | READ | Query order by order ID |
| 25 | Order Query | POST /spot/v4/query/client-order | READ | Query by client order ID |
| 26 | Order Query | POST /spot/v4/query/open-orders | READ | All open orders |
| 27 | Order Query | POST /spot/v4/query/history-orders | READ | Historical orders |
| 28 | Order Query | POST /spot/v4/query/trades | READ | Account trade history |
| 29 | Order Query | POST /spot/v4/query/order-trades | READ | Trades for specific order |
| 30 | Margin Loan | POST /spot/v1/margin/isolated/borrow | WRITE | Margin borrow (isolated) |
| 31 | Margin Loan | POST /spot/v1/margin/isolated/repay | WRITE | Margin repay (isolated) |
| 32 | Margin Loan | POST /spot/v1/margin/isolated/transfer | WRITE | Margin asset transfer |
| 33 | System | GET /system/time | READ | Get server time (milliseconds) |
| 34 | System | GET /system/service | READ | Get system service status / maintenance |
Skill Routing
| User Intent | Correct Skill | |------------|---------------| | Spot buy/sell, order management, balance, fee rates | bitmart-exchange-spot (this skill) | | Futures/contract trading, leverage, TP/SL, plan orders | bitmart-exchange-futures |
Authentication
Credential Check (Before Any Private API Call)
Before calling any authenticated endpoint, verify credentials are available:
- Check for environment variables:
BITMART_API_KEY— API keyBITMART_API_SECRET— Secret keyBITMART_API_MEMO— Memo string
- Or check for config file:
~/.bitmart/config.toml[default] api_key = "your-api-key" api_secret = "your-secret-key" memo = "your-memo" - If missing: STOP. Guide user to set up credentials. Do NOT proceed with any authenticated call.
Key display rules: When displaying credentials back to the user, show only the first 5 and last 4 characters (e.g., bmk12...9xyz). NEVER display full secret or memo values.
Auth Levels
| Level | When | Headers Required |
|-------|------|-----------------|
| NONE | Public market data (endpoints 1-9) | None |
| KEYED | Read-only private data — balances, fees, margin account, borrow/repay records (endpoints 10-17) | X-BM-KEY |
| SIGNED | Write operations and order queries (endpoints 18-32) | X-BM-KEY + X-BM-SIGN + X-BM-TIMESTAMP |
Signature Generation
timestamp = current UTC time in milliseconds
message = "{timestamp}#{memo}#{request_body_json}"
signature = HMAC-SHA256(secret_key, message) → hex string
- For POST requests:
request_body_jsonis the JSON body string. - For GET requests:
request_body_jsonis an empty string"".
Required Headers (SIGNED)
| Header | Value |
|--------|-------|
| Content-Type | application/json |
| X-BM-KEY | API key |
| X-BM-SIGN | Hex-encoded HMAC-SHA256 signature |
| X-BM-TIMESTAMP | Current UTC timestamp in milliseconds |
See references/authentication.md for full setup guide and troubleshooting.
API Base
- Base URL:
https://api-cloud.bitmart.com - Symbol Format:
BTC_USDT(base_quote, underscore separated)
Standard Response Format
Success:
{
"code": 1000,
"message": "OK",
"trace": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": { ... }
}
Error:
{
"code": 51003,
"message": "Account Limit",
"trace": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"data": null
}
Important: code == 1000 means success. Any other code is an error.
GET requests: Parameters go in the query string. POST requests: Parameters go in the JSON body.
Rate Limits
| Endpoint | Rate | Target |
|----------|------|--------|
| GET /spot/quotation/v3/ticker | 15 req/2sec | IP |
| GET /spot/quotation/v3/tickers | 10 req/2sec | IP |
| GET /spot/quotation/v3/lite-klines | 15 req/2sec | IP |
| GET /spot/quotation/v3/klines | 10 req/2sec | IP |
| GET /spot/quotation/v3/books | 15 req/2sec | IP |
| GET /spot/quotation/v3/trades | 15 req/2sec | IP |
| GET /spot/v1/currencies | 8 req/2sec | IP |
| GET /spot/v1/symbols | 8 req/2sec | IP |
| GET /spot/v1/symbols/details | 12 req/2sec | IP |
| Balance | 12 req/2sec | KEY |
| Trade Fee / User Fee | 2 req/2sec | KEY |
| Margin Account | 12 req/2sec | KEY |
| Margin Pairs | 2 req/2sec | KEY |
| Borrow / Repay Records | 150 req/2sec | KEY |
| Place Order (spot) | 40 req/2sec | UID |
| Batch Place Orders (/spot/v4/batch_orders) | 40 req/2sec | UID |
| Place Order (margin) | 20 req/1sec | UID |
| Cancel Order | 40 req/2sec | UID |
| Cancel Multiple (/spot/v4/cancel_orders) | 40 req/2sec | UID |
| Cancel All | 1 req/3sec | UID |
| Query Order by ID | 50 req/2sec | KEY |
| Query by Client Order ID (/spot/v4/query/client-order) | 50 req/2sec | KEY |
| Open / History / Trades | 12 req/2sec | KEY |
| Order-Trades | 12 req/2sec | KEY |
| Margin Borrow / Repay / Transfer | 2 req/2sec | KEY |
| GET /system/time | 10 req/sec | IP |
| GET /system/service | 10 req/sec | IP |
Rate limit response headers:
X-BM-RateLimit-Remaining— Number of requests already used in the current windowX-BM-RateLimit-Limit— Maximum allowed requests in the current windowX-BM-RateLimit-Reset— Current time window length (seconds)
Warning: If X-BM-RateLimit-Remaining > X-BM-RateLimit-Limit, stop calling immediately to avoid ban.
If rate limited (HTTP 429), wait for the reset period before retrying.
Quickstart
Example 1: Get BTC price (no auth)
curl -s 'https://api-cloud.bitmart.com/spot/quotation/v3/ticker?symbol=BTC_USDT'
Example 2: Get account balance (KEYED)
curl -s -H "X-BM-KEY: $BITMART_API_KEY" \
'https://api-cloud.bitmart.com/account/v1/wallet'
Example 3: Place limit buy order (SIGNED)
TIMESTAMP=$(date +%s000)
BODY='{"symbol":"BTC_USDT","side":"buy","type":"limit","size":"0.001","price":"60000"}'
SIGN=$(echo -n "${TIMESTAMP}#${BITMART_API_MEMO}#${BODY}" | openssl dgst -sha256 -hmac "$BITMART_API_SECRET" | awk '{print $2}')
curl -s -X POST 'https://api-cloud.bitmart.com/spot/v2/submit_order' \
-H "Content-Type: application/json" \
-H "X-BM-KEY: $BITMART_API_KEY" \
-H "X-BM-SIGN: $SIGN" \
-H "X-BM-TIMESTAMP: $TIMESTAMP" \
-d "$BODY"
API Reference
See references/api-reference.md for full endpoint documentation with parameters, examples, and response formats.
Reference: Order Types
| Type | Description |
|------|-------------|
| limit | Execute at specified price or better |
| market | Execute immediately at best available price |
| limit_maker | Post-only; rejected if it would immediately match (ensures maker fee) |
| ioc | Immediate-or-cancel; unfilled portion is canceled immediately |
Reference: Order Sides
| Side | Description |
|------|-------------|
| buy | Buy base currency with quote currency |
| sell | Sell base currency for quote currency |
Reference: Order States
| State | Description |
|-------|-------------|
| new | Order accepted, not yet filled |
| partially_filled | Partially executed, still open |
| filled | Fully executed |
| canceled | Canceled by user |
| partially_canceled | Partially filled, then canceled |
Reference: Cancel Sources
| Source | Description |
|--------|-------------|
| "" (empty) | Not canceled |
| user | Canceled by user |
| system | Canceled by system (e.g., insufficient balance) |
| stp | Canceled by self-trade prevention |
Reference: STP Modes
| Mode | Description |
|------|-------------|
| none | No self-trade prevention |
| cancel_maker | Cancel the resting (maker) order if self-trade detected |
| cancel_taker | Cancel the incoming (taker) order if self-trade detected |
| cancel_both | Cancel both orders if self-trade detected |
Reference: Trade Roles
| Role | Description |
|------|-------------|
| taker | Order matched immediately against resting order |
| maker | Order rested on book and was matched later |
Reference: Parameter Naming Convention
CRITICAL — Wrong case = silently ignored field. The API does NOT return an error for misnamed params; it simply ignores them, causing unexpected behavior or wrong results. Always verify the endpoint version before constructing any request body.
| API Version | Convention | Examples |
|-------------|-----------|----------|
| v1-v3 | snake_case | client_order_id, order_id, start_time |
| v4 | camelCase | clientOrderId, orderId, orderMode, startTime |
Mixed-case exceptions (must be memorized):
POST /spot/v2/submit_order:stpMode(camelCase) alongsideclient_order_id(snake_case)POST /spot/v1/margin/submit_order:clientOrderId(camelCase in a v1 endpoint)
Reference: K-Line Steps
| Step (minutes) | Description | |----------------|-------------| | 1 | 1-minute candles | | 5 | 5-minute candles | | 15 | 15-minute candles | | 30 | 30-minute candles | | 60 | 1-hour candles | | 120 | 2-hour candles | | 240 | 4-hour candles | | 1440 | 1-day candles | | 10080 | 1-week candles | | 43200 | 1-month candles |
Operation Flow
Step 0: Credential Check
Verify BITMART_API_KEY, BITMART_API_SECRET, and BITMART_API_MEMO are available via environment variables or ~/.bitmart/config.toml. If missing, STOP and guide the user to set up credentials.
Step 1: Identify User Intent
Parse user request and map to a READ or WRITE operation:
- READ operations: market data, balance queries, order queries, fee rates
- WRITE operations: place order, cancel order, batch orders
Timestamp Display Rules
API responses contain Unix timestamps in different units. When displaying any timestamp to the user, always convert to human-readable local time.
| Field | Unit | Conversion |
|-------|------|------------|
| createTime, updateTime (order responses) | Milliseconds | ÷ 1000 → Unix seconds → local time |
| server_time (system time) | Milliseconds | ÷ 1000 → Unix seconds → local time |
| t (K-line candle open time) | Seconds | Direct → Unix seconds → local time |
| create_time (borrow records) | Seconds | Direct → Unix seconds → local time |
| repay_time (repay records) | Seconds | Direct → Unix seconds → local time |
Display format: YYYY-MM-DD HH:MM:SS in the user's local timezone. Example: timestamp 1700000000000 (ms) → 2023-11-15 06:13:20 (UTC+8).
Common mistakes to avoid:
- Do NOT treat millisecond timestamps as seconds (produces dates in year 55000+)
- Do NOT display raw numeric timestamps — always convert to readable format
- Do NOT assume UTC — convert to the user's local timezone
Step 2: Execute
-
READ: Call the API endpoint, parse response, format data for user display.
-
WRITE: Follow these sub-steps strictly in order:
2a. Parameter naming check (prevents silent failures):
- Identify the API version of the target endpoint
- v4 endpoints (
/spot/v4/...): ALL params must be camelCase (clientOrderId,orderId,orderMode,startTime) - v1–v3 endpoints: ALL params must be snake_case (
client_order_id,order_id,start_time) - Special exception:
POST /spot/v2/submit_orderuses mixed —client_order_id(snake_case) +stpMode(camelCase) - The API does NOT return an error for wrong-case params — it silently ignores them, causing wrong orders or failed queries
2b. Order type rules — params, precision, minimum validation:
First call
GET /spot/v1/symbols/details, locate the symbol indata.symbols[], extract:price_max_precision,quote_increment,min_buy_amount,min_sell_amount.Then branch:
type=market,side=buy— Market buy:- Send only
notional(USDT/quote amount). Do NOT sendsizeorprice— silently ignored and causes error 50021. - Validate:
float(notional) >= min_buy_amount. If not, STOP — suggest"notional":"<min_buy_amount>". API returns 51012 otherwise. - Body:
{"symbol":"XRP_USDT","side":"buy","type":"market","notional":"5"}
type=market,side=sell— Market sell:- Send only
size(base currency quantity, e.g. XRP amount). Do NOT sendpriceornotional. - Truncate
sizetoquote_incrementprecision. - Estimate value:
size * current_last_price. If estimated value< min_sell_amount, STOP and warn user. - Body:
{"symbol":"XRP_USDT","side":"sell","type":"market","size":"10"}
type=limit— Limit order:- Send
size+price. Truncatepricetoprice_max_precision,sizetoquote_increment. - Note: If price exceeds
price_max_precision, the API silently truncates the extra decimals instead of returning an error. Always truncate client-side to ensure the submitted price matches the intended price. - Calculate
order_value = size * price. Iforder_value < min_buy_amount(buy) or< min_sell_amount(sell), STOP. - If user requested "buy all" / "use full balance":
size = floor(balance / price)at precision, re-verify minimum. - No hidden risk — order sits on the book until filled or canceled.
type=limit_maker— Post-only (maker-only):- Same params as
limit(size+price). Same precision/minimum rules. - CRITICAL behavioral note: The server auto-cancels the order (no error) if the price would immediately match:
- Buy
limit_maker: ifprice >= best_ask, order is silently canceled. Price must be below best ask. - Sell
limit_maker: ifprice <= best_bid, order is silently canceled. Price must be above best bid.
- Buy
- Inform user of this risk when setting an aggressive
limit_makerprice.
type=ioc— Immediate-or-Cancel:- Same params as
limit(size+price). Same precision/minimum rules. - Behavioral note: Fills whatever quantity is available immediately at the given price; the unfilled remainder is immediately canceled. User may receive a partial fill or no fill at all.
2c. Confirm and execute:
- Present order summary based on type:
- market buy: symbol, side=buy, type=market, notional amount
- market sell: symbol, side=sell, type=market, size (quantity)
- limit/limit_maker/ioc: symbol, side, type, size, price, estimated order value
- For
limit_maker: include a reminder that the order will be auto-canceled if the price crosses the spread. - Ask for explicit "CONFIRM" before executing. Only proceed after user confirms.
Step 3: Verify (WRITE only)
- After placing an order: Call
POST /spot/v4/query/orderwith{"orderId":"..."}to confirm order status. - After canceling an order: Call
POST /spot/v4/query/open-ordersto verify the order is no longer open. - Report the verified result to the user.
Cross-Skill Workflows
Workflow 1: Check Price → Check Balance → Buy
- bitmart-exchange-spot →
GET /spot/quotation/v3/ticker?symbol=BTC_USDT— Get current price - bitmart-exchange-spot →
GET /account/v1/wallet— Check available balance - bitmart-exchange-spot →
POST /spot/v2/submit_order— Place buy order (after user CONFIRM) - bitmart-exchange-spot →
POST /spot/v4/query/order— Verify order execution
Error Handling
| Code | Description | Action |
|------|-------------|--------|
| 1000 | Success | Process response normally |
| 30002 | X-BM-KEY not found | Check that API key is set correctly |
| 30005 | X-BM-SIGN is wrong | Verify signature generation (timestamp, memo, body format) |
| 30007 | Timestamp/recvWindow validation failed | Sync system clock (NTP), send X-BM-TIMESTAMP as Unix milliseconds, and ensure (serverTime - timestamp) <= recvWindow; recvWindow must be Long in (0,60000], default 5000 (max 60000) |
| 30010 | IP forbidden | Check API key IP whitelist settings |
| 30013 | Rate limit exceeded | Wait for rate limit window to reset, then retry |
| 51003 | Account Limit | Reduce borrow/repay/transfer scope or verify account restrictions |
| 51006 | Exceeds the amount to be repaid | Ensure repay amount is not greater than outstanding principal + interest |
| 51007 | order_mode not found | Use a valid orderMode value (spot or iso_margin) on v4 query endpoints |
| 50021 | param error | For market buy, use notional (USDT amount) — do NOT use size; size is silently ignored and causes this error |
| 51011 | param not match : size * price >= X | Read symbol constraints from GET /spot/v1/symbols/details; enforce side-specific minimum notional (min_buy_amount/min_sell_amount) |
| 51012 | below minimum order amount | notional (for market buy) or size * price (for limit) is below min_buy_amount; increase order value to at least the symbol minimum |
| 40044 | Invalid order size | Call GET /spot/v1/symbols/details; use symbol precision/increment fields and truncate (not round) size and price |
| 50023 | Operation is limited | Pair may not support API trading; use a different pair |
| 429 | HTTP rate limit | Back off exponentially, check X-BM-RateLimit-Reset header |
| 418 | IP banned | Stop all requests immediately; wait before retrying |
Security Notes
- Never display full API keys or secrets. Show first 5 + last 4 characters only (e.g.,
bmk12...9xyz). - All WRITE operations require explicit user confirmation before execution. Present a clear summary of the action and wait for "CONFIRM".
- Recommend IP whitelist on API keys for additional security.
- Recommend minimum permissions: Read-Only + Spot-Trade only (no Withdraw permission).
- All trading outputs include disclaimer: "Not financial advice. You are solely responsible for your investment decisions."
微信扫一扫