Skip to main content

Overview

The clientOrderId is an optional identifier for tracking and managing orders with custom identifiers. It provides an additional layer of order management and tracking capabilities alongside the exchange-provided orderId.

Specifications

Type & Requirements

  • Type: String
  • Mandatory: No
  • Uniqueness: enforced only among open (pending) orders on the same market — the identifier can be reused once the previous order fills or cancels

Allowed Characters

  • Latin letters
  • Numbers
  • Dashes (-)
  • Dots (.)
  • Underscores (_)

Length and Format Guidelines

  • Recommended length: 32 characters
  • Case-sensitive: “Order1” and “order1” are different IDs
  • Leading/trailing spaces are not allowed
  • Cannot be an empty string if provided

Best Practices

Structured Naming Convention
// Format: strategy-pair-type-timestamp
const clientOrderId = "scalp-btcusdt-limit-1678234567";

// Format: botId-strategy-sequence
const clientOrderId = "bot123-grid-0001";

// Format: userAccount-orderType-customSequence
const clientOrderId = "trade15-market-a7b8c9";

Common Use Cases

Basic Limit Order
// Simple limit order with clientOrderId
const limitOrderRequest = {
  market: "BTC_USDT",
  side: "buy",
  amount: "0.01",
  price: "40000",
  clientOrderId: "limit-btc-buy-001"
};

Order Management

Tracking Orders

Track orders using clientOrderId through the following endpoints:1. Query Active OrdersUse the Query Active Orders endpoint (/api/v4/orders) to get all unexecuted orders:
// Request
const queryActiveOrders = {
  market: "BTC_USDT",
  clientOrderId: "dca-btc-market-002"
};
Example response includes order details such as ID, status, and execution information:
{
  "orderId": 4180284841,
  "clientOrderId": "dca-btc-market-002",
  "market": "BTC_USDT",
  "side": "buy",
  "type": "limit",
  "timestamp": 1595792396.165973,
  "dealMoney": "0",
  "dealStock": "0",
  "amount": "0.001",
  "price": "40000",
  "status": "NEW"
}
2. Query Order HistoryUse the Query Order History endpoint (/api/v4/trade-account/order/history) to get executed orders:
// Request
const queryOrderHistory = {
  market: "BTC_USDT",
  clientOrderId: "grid-btc-sell-003",
  limit: 50,
  offset: 0
};
Example response showing execution details and final order status. The response groups orders by market name:
{
  "BTC_USDT": [
    {
      "id": 4180284841,
      "clientOrderId": "grid-btc-sell-003",
      "side": "sell",
      "type": "limit",
      "ctime": 1595792396.165973,
      "ftime": 1595792396.999999,
      "dealMoney": "41.258268",
      "dealStock": "0.001",
      "amount": "0.001",
      "price": "41258.27",
      "status": "FILLED"
    }
  ]
}
3. Cancelling Orders Using ClientOrderIdUse the Cancel Order endpoint (/api/v4/order/cancel) to cancel an order by its clientOrderId:
// Request
const cancelOrderRequest = {
  market: "BTC_USDT",
  clientOrderId: "dca-btc-market-002"
};
Important notes about order cancellation:
  • Cancellation by clientOrderId takes priority over orderId
  • Use either orderId or clientOrderId, but not both in the same request
// Example response
{
  "orderId": 4180284841,
  "clientOrderId": "dca-btc-market-002",
  "market": "BTC_USDT",
  "side": "buy",
  "type": "limit",
  "timestamp": 1595792396.165973,
  "dealMoney": "0",
  "dealStock": "0",
  "amount": "0.001",
  "left": "0.001",
  "price": "40000",
  "status": "CANCELED"
}

Error Handling

Common Error Cases

Duplicate ID

The clientOrderId only has to be unique among the account’s open (pending) orders on the same market. Once a previous order is filled or canceled, the same identifier can be reused on the same market. The same identifier can also be used in parallel on different markets.

Invalid Format

Ensure the ID only contains allowed characters.

Length Limit

The recommended length is 32 characters, with a maximum permissible length of 64 characters.

Order Not Found

Handle cases where an order with the specified clientOrderId doesn’t exist.

Example error handling:

try {
  const order = await queryOrderByClientId("dca-btc-market-002");
  // Process order
} catch (error) {
  if (error.code === 36) {
    console.error("Invalid clientOrderId format");
  } else if (error.code === 2) {
    console.error("Order not found");
  } else {
    console.error("Unexpected error:", error);
  }
}

Example: Broker Implementation

For the full Broker Program integration guide — program enrollment, sub-account setup, fee share model, and revenue monitoring — see Broker Guide.

Broker Implementation Guide

ClientOrderId StructureFormat: brk-{clientId}-{orderType}-{purpose}-{timestamp} Example: brk-ind123-limit-spot-1678234567Components:
  • brk: Broker identifier prefix
  • clientId: Internal client identifier
  • orderType: Order type (market/limit)
  • purpose: Trading purpose/strategy
  • timestamp: Keeps each identifier distinct across submissions

Individual Clients

brk-ind123-market-spot-1678234567

Corporate Clients

brk-corp789-limit-hedge-1678234567

Managed Portfolios

brk-port555-market-dca-1678234567

Trading Purpose Examples

Spot Trading

brk-ind123-market-spot-1678234567

DCA Strategy

brk-port555-market-dca-1678234567

Grid Trading

brk-ind123-limit-grid-1678234567

Portfolio Rebalancing

brk-port555-limit-rebal-1678234567

API Usage Example

// Create an order for a client
const createClientOrder = {
  market: "BTC_USDT",
  side: "buy",
  amount: "0.01",
  price: "40000",
  clientOrderId: "brk-ind123-limit-spot-1678234567"
};

// Query client's active orders
const queryClientOrders = {
  market: "BTC_USDT",
  clientOrderId: "brk-ind123-limit-spot-1678234567"
};

// Cancel client's order using clientOrderId
const cancelClientOrder = {
  market: "BTC_USDT",
  clientOrderId: "brk-ind123-limit-spot-1678234567"
};

// Get historical data for client orders
const getClientOrderHistory = {
  market: "BTC_USDT",
  clientOrderId: "brk-ind123-limit-spot-1678234567",
  limit: 50,
  offset: 0
};
This structured approach allows brokers to:
  • Track orders for multiple clients
  • Identify order types and purposes
  • Maintain unique identifiers
  • Query and manage orders efficiently

Order Management for Brokers

Client Order Management

Cancelling Client Orders

Brokers can efficiently cancel orders for any of their clients using the structured clientOrderId:
// Function to cancel a client's order
async function cancelClientOrder(clientId, orderPurpose, orderId) {
  const cancelRequest = {
    market: "BTC_USDT",
    clientOrderId: `brk-${clientId}-limit-${orderPurpose}-${orderId}`
  };

  try {
    const response = await api.post('/api/v4/order/cancel', cancelRequest);
    return response.data;
  } catch (error) {
    console.error(`Failed to cancel order for client ${clientId}:`, error);
    throw error;
  }
}

// Example usage
await cancelClientOrder('ind123', 'spot', '1678234567');

Retrieving Historical Client Orders

The Query Order History endpoint (/api/v4/trade-account/order/history) supports exact clientOrderId lookup only: pass the full identifier to retrieve a single order. When clientOrderId is supplied, the endpoint switches to single-order lookup mode and ignores the startDate, endDate, and status filters. Pattern or prefix matching on clientOrderId is not supported.
// Exact lookup of one client order (single-order mode)
const lookupClientOrder = {
  market: "BTC_USDT",
  clientOrderId: "brk-ind123-limit-spot-1678234567"
};
For reporting across many client orders, retrieve history in list mode — filtered by market, startDate, and endDate (Unix seconds) — and parse the structured identifiers client-side, as shown below.

Broker Analytics and Reporting

With structured clientOrderId patterns, brokers can reconstruct per-client reporting from order history without a separate order database — each ID segment maps to a report dimension:
ID segmentEncodesAnalytics use
brkBroker prefixSeparates broker flow from other orders
clientIdInternal client identifierGroups orders and volume per client
orderTypeOrder type (market/limit)Order-type mix per client
purposeTrading purpose/strategy (spot, dca, grid, rebal)Order count and volume per strategy
timestampSubmission timeKeeps IDs distinct; submission-time analysis
The critical path is the parser — split the ID and validate its shape. Aggregating parsed segments into per-client totals (order counts, dealMoney volume, per-purpose breakdowns) is standard reporting code on top of it:
// Parse clientOrderId back into its metadata segments
// Format: brk-{clientId}-{orderType}-{purpose}-{timestamp}
function parseClientOrderId(clientOrderId) {
  const parts = clientOrderId.split('-');
  if (parts.length !== 5 || parts[0] !== 'brk') {
    throw new Error('Invalid broker clientOrderId format');
  }
  return {
    clientId: parts[1],
    orderType: parts[2],
    purpose: parts[3],
    timestamp: parseInt(parts[4])
  };
}