# Spot REST API

## Spot Market Endpoints

### Query symbols

`GET ${SPOT_ENDPOINT}/markets/symbols`

*Get trading rules and symbol information for all spot symbols.*

```bash
curl -X GET ${SPOT_ENDPOINT}/markets/symbols \
  -H 'Accept: application/json'
```

#### Query Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `false`  | Symbol name, e.g. `vBTC_vUSDC` |

#### Response

| Field  | Type                | Description                                                                                                                                                           |
| ------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<SpotSymbol>` | Response data when code is `0`. See [`SpotSymbol`](/documentation/trading-api/rest-v1/schema.md#spotsymbol) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query coins

`GET ${SPOT_ENDPOINT}/markets/coins`

*Get information for all coins.*

```bash
curl -X GET ${SPOT_ENDPOINT}/markets/coins \
  -H 'Accept: application/json'
```

#### Query Parameters

| Name   | Type     | Required | Description            |
| ------ | -------- | -------- | ---------------------- |
| `coin` | `string` | `false`  | Coin name, e.g. `vBTC` |

#### Response

| Field  | Type              | Description                                                                                                                                                       |
| ------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<SpotCoin>` | Response data when code is `0`. See [`SpotCoin`](/documentation/trading-api/rest-v1/schema.md#spotcoin) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query tickers

`GET ${SPOT_ENDPOINT}/markets/tickers`

*Get 24hr rolling window price change statistics for all symbols.*

```bash
curl -X GET ${SPOT_ENDPOINT}/markets/tickers \
  -H 'Accept: application/json'
```

#### Query Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `false`  | Symbol name, e.g. `vBTC_vUSDC` |

#### Response

| Field  | Type                | Description                                                                                                                                                           |
| ------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<SpotTicker>` | Response data when code is `0`. See [`SpotTicker`](/documentation/trading-api/rest-v1/schema.md#spotticker) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query mini tickers

`GET ${SPOT_ENDPOINT}/markets/miniTickers`

*Get 24hr rolling window price change statistics for all symbols.*

```bash
curl -X GET ${SPOT_ENDPOINT}/markets/miniTickers \
  -H 'Accept: application/json'
```

#### Query Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `false`  | Symbol name, e.g. `vBTC_vUSDC` |

#### Response

| Field  | Type                | Description                                                                                                                                                           |
| ------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<MiniTicker>` | Response data when code is `0`. See [`MiniTicker`](/documentation/trading-api/rest-v1/schema.md#miniticker) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query book tickers

`GET ${SPOT_ENDPOINT}/markets/bookTickers`

*Best price/qty on the order book for symbols.*

```bash
curl -X GET ${SPOT_ENDPOINT}/markets/bookTickers \
  -H 'Accept: application/json'
```

#### Query Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `false`  | Symbol name, e.g. `vBTC_vUSDC` |

#### Response

| Field  | Type                | Description                                                                                                                                                           |
| ------ | ------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<BookTicker>` | Response data when code is `0`. See [`BookTicker`](/documentation/trading-api/rest-v1/schema.md#bookticker) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query order book

`GET ${SPOT_ENDPOINT}/markets/{symbol}/orderbook`

*Get order book depth for a symbol.*

```bash
curl -X GET "${SPOT_ENDPOINT}/markets/vBTC_vUSDC/orderbook?limit=20" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `true`   | Symbol name, e.g. `vBTC_vUSDC` |

#### Query Parameters

| Name    | Type     | Required | Description                             |
| ------- | -------- | -------- | --------------------------------------- |
| `limit` | `uint32` | `false`  | Depth limit. Default: `10`, Max: `1000` |

#### Response

| Field  | Type        | Description                                                                                                                                                         |
| ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `OrderBook` | Response data when code is `0`. See [`OrderBook`](/documentation/trading-api/rest-v1/schema.md#orderbook) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query candles/klines

`GET ${SPOT_ENDPOINT}/markets/{symbol}/klines`

*Get candlestick/kline data for a symbol.*

```bash
curl -X GET "${SPOT_ENDPOINT}/markets/vBTC_vUSDC/klines?interval=1h&limit=100" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `true`   | Symbol name, e.g. `vBTC_vUSDC` |

#### Query Parameters

| Name        | Type     | Required | Description                                                                                                                                                                                              |
| ----------- | -------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `interval`  | `string` | `true`   | Kline interval (case-sensitive): `1m`, `3m`, `5m`, `15m`, `30m`, `1h`, `4h`, `6h`, `8h`, `12h`, `1d`, `3d`, `1w`, `1M`. Note: day/week use lowercase (`1d`, `3d`, `1w`); only month is uppercase (`1M`). |
| `startTime` | `uint64` | `false`  | Start time in milliseconds                                                                                                                                                                               |
| `endTime`   | `uint64` | `false`  | End time in milliseconds                                                                                                                                                                                 |
| `limit`     | `uint32` | `false`  | Number of klines to return. Default: `500`, Max: `1500`                                                                                                                                                  |

#### Response

| Field  | Type              | Description                                                                                                                                                       |
| ------ | ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<RPCKline>` | Response data when code is `0`. See [`RPCKline`](/documentation/trading-api/rest-v1/schema.md#rpckline) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query recent trades

`GET ${SPOT_ENDPOINT}/markets/{symbol}/trades`

*Get recent public trades for a symbol.*

```bash
curl -X GET "${SPOT_ENDPOINT}/markets/vBTC_vUSDC/trades?limit=50" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name     | Type     | Required | Description                    |
| -------- | -------- | -------- | ------------------------------ |
| `symbol` | `string` | `true`   | Symbol name, e.g. `vBTC_vUSDC` |

#### Query Parameters

| Name    | Type     | Required | Description                                           |
| ------- | -------- | -------- | ----------------------------------------------------- |
| `limit` | `uint32` | `false`  | Number of trades to return. Default: `50`, Max: `500` |

#### Response

| Field  | Type           | Description                                                                                                                                                 |
| ------ | -------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<Trade>` | Response data when code is `0`. See [`Trade`](/documentation/trading-api/rest-v1/schema.md#trade) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

## Spot Accounts Endpoints

### Query balances

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/balances`

*Get current account balance.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/balances" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                            |
| ----------- | -------- | -------- | ---------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default. |

#### Response

| Field  | Type                  | Description                                                                                                                                                                             |
| ------ | --------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `SpotAccountBalances` | Response data when code is `0`. See [`SpotAccountBalances`](/documentation/trading-api/rest-v1/schema.md#spotaccountbalances) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query open orders

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/orders`

*Get all open orders for an account.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/orders?symbol=vBTC_vUSDC" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                            |
| ----------- | -------- | -------- | ---------------------------------------------------------------------- |
| `symbol`    | `string` | `false`  | Filter by symbol name                                                  |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default. |

#### Response

| Field  | Type                   | Description                                                                                                                                                                               |
| ------ | ---------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `SpotAccountOpenOrder` | Response data when code is `0`. See [`SpotAccountOpenOrder`](/documentation/trading-api/rest-v1/schema.md#spotaccountopenorder) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query state for frontend

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/state`

*Get comprehensive account state for UI initialization. Includes balances, open orders, and sync metadata.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/state" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                            |
| ----------- | -------- | -------- | ---------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default. |

#### Response

| Field  | Type          | Description                                                                                                                                                             |
| ------ | ------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `WsSpotState` | Response data when code is `0`. See [`WsSpotState`](/documentation/trading-api/rest-v1/schema.md#wsspotstate) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query API Keys

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/api-keys`

*Get list of API keys.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/api-keys" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                            |
| ----------- | -------- | -------- | ---------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default. |
| `name`      | `string` | `false`  | The name of the API key.                                               |

#### Response

| Field  | Type            | Description                                                                                                                                                   |
| ------ | --------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<APIKey>` | Response data when code is `0`. See [`APIKey`](/documentation/trading-api/rest-v1/schema.md#apikey) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query fee rate

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/fee-rate`

*Get the current maker/taker fee rates for the account, including fee tier, staking tier, and maker rebate tier. Optionally pass a symbol to include the symbol-level fee discount.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/fee-rate?symbol=vBTC_vUSDC" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                                              |
| ----------- | -------- | -------- | ---------------------------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default.                   |
| `symbol`    | `string` | `false`  | Symbol name, e.g. `vBTC_vUSDC`. When provided, the symbol-level fee discount is applied. |

#### Response

| Field  | Type      | Description                                                                                                                                                     |
| ------ | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `FeeRate` | Response data when code is `0`. See [`FeeRate`](/documentation/trading-api/rest-v1/schema.md#feerate) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query order history

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/orders/history`

*Get historical orders (filled, canceled, expired) for an account.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/orders/history?symbol=vBTC_vUSDC" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                            |
| ----------- | -------- | -------- | ---------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default. |
| `symbol`    | `string` | `false`  | Filter by symbol name                                                  |
| `startTime` | `uint64` | `false`  | Start time in milliseconds                                             |
| `endTime`   | `uint64` | `false`  | End time in milliseconds                                               |
| `limit`     | `uint32` | `false`  | Number of orders to return. Default: `50`, Max: `500`                  |

#### Response

| Field  | Type               | Description                                                                                                                                                         |
| ------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<SpotOrder>` | Response data when code is `0`. See [`SpotOrder`](/documentation/trading-api/rest-v1/schema.md#spotorder) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query user trades

`GET ${SPOT_ENDPOINT}/accounts/{userAddress}/trades`

*Get historical trade executions for an account.*

```bash
curl -X GET "${SPOT_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/trades?symbol=vBTC_vUSDC&limit=100" \
  -H 'Accept: application/json'
```

#### Path Parameters

| Name          | Type        | Required | Description      |
| ------------- | ----------- | -------- | ---------------- |
| `userAddress` | `HexString` | `true`   | User EVM address |

#### Query Parameters

| Name        | Type     | Required | Description                                                            |
| ----------- | -------- | -------- | ---------------------------------------------------------------------- |
| `accountID` | `uint64` | `false`  | The sub-account ID of the user. Primary account ID is used by default. |
| `symbol`    | `string` | `false`  | Filter by symbol name                                                  |
| `orderID`   | `uint64` | `false`  | Filter by order ID                                                     |
| `startTime` | `uint64` | `false`  | Start time in milliseconds                                             |
| `endTime`   | `uint64` | `false`  | End time in milliseconds                                               |
| `limit`     | `uint32` | `false`  | Number of trades to return. Default: `100`, Max: `1000`                |

#### Response

| Field  | Type               | Description                                                                                                                                                         |
| ------ | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `data` | `Array<UserTrade>` | Response data when code is `0`. See [`UserTrade`](/documentation/trading-api/rest-v1/schema.md#usertrade) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Transfer asset to EVM or perps

`POST ${SPOT_ENDPOINT}/accounts/transfers`

*Transfer assets between accounts.*

* Auth: signed write

```bash
curl -X POST ${SPOT_ENDPOINT}/accounts/transfers \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Key: <API-Key>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <TransferAssetRequest>
```

#### Request Body

See [`TransferAssetRequest`](/documentation/trading-api/rest-v1/schema.md#transferassetrequest) in [Schema](/documentation/trading-api/rest-v1/schema.md)

Additional Information:

* Number of decimal places of `transfer.amount` should not exceed coin precision. That is `transfer.amount % 10^{-coin.precision} = 0`.
* The `transfer.amount` must be a positive value.
* Transfer asset to EVM chain: `transfer.toAccountID=999`, `transfer.type=EVM_WITHDRAW`
* Transfer asset to perps chain: `transfer.toAccountID=999`, `transfer.type=PERPS_WITHDRAW`
* Internal transfer between spot chains is not supported yet.

#### Response

| Field  | Type           | Description                     |
| ------ | -------------- | ------------------------------- |
| `data` | `ResponseData` | Response data when code is `0`. |

* `ResponseData`

  | Name | Type     | Required | Description                                                                   |
  | ---- | -------- | -------- | ----------------------------------------------------------------------------- |
  | `id` | `uint64` | `true`   | Identifier for this transfer request. Same as `id` in `TransferAssetRequest`. |

## Spot Trading Endpoints

### Place multiple orders

`POST ${SPOT_ENDPOINT}/trade/orders/batch`

*Submit multiple orders atomically.*

* Auth: signed write

```bash
curl -X POST ${SPOT_ENDPOINT}/trade/orders/batch \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Key: <API-Key>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <BatchNewOrderParams>
```

#### Request Body

Find `BatchNewOrderRequest` and `BatchNewOrderItem` in [Schema](/documentation/trading-api/rest-v1/schema.md)

Additional Information:

* The batch cannot be empty.
* The length of batch should less than or equals to `100`.
* Basic Validation
  * The `order[i].clOrdID` must match `^[0-9a-zA-Z_-]{1,36}$`.
  * `order[i].clOrdID` must be unique among open orders. Reuse is allowed only after the previous order is filled.
  * For limit order
    * `order[i].timeInForce` can be `GTC`, `IOC`, `GTX`.
    * provide both `order[i].price` and `order[i].quantity`, do not send `order[i].funds`.
  * For market order
    * `order[i].timeInForce` must be `IOC`.
    * Provide either `order[i].quantity` or `order[i].funds`, not both. `order[i].funds` only available for market buy orders.
    * `order[i].price` optional for slippage protection.
  * The order will be rejected if basic validation failed.
* Price filter
  * The decimal precision of order price should not exceed `symbol.pricePrecision`. That is `order[i].price % 10^{-symbol.pricePrecision} = 0`.
  * The order price must be multiple of `symbol.tickSize`. That is `order[i].price % symbol.tickSize = 0`.
  * If `symbol.minPrice` is not `0`, the order price should greater than or equals to `symbol.minPrice`.
  * If `symbol.maxPrice` is not `0`, the order price should less than or equals to `symbol.maxPrice`.
  * The order will be rejected if price filter check failed.
* Lot size filter
  * The decimal precision of order quantity should not exceed `symbol.quantityPrecision`. That is `order[i].quantity % 10^{-symbol.quantityPrecision} = 0`.
  * The order quantity must be multiple of `symbol.stepSize`. That is `order[i].quantity % symbol.stepSize = 0`.
  * If `symbol.minQuantity` is not `0`, the order quantity should greater than or equals to `symbol.minQuantity`.
  * If `symbol.maxQuantity` is not `0`, the order quantity should less than or equals to `symbol.maxQuantity`.
  * The order will be rejected if lot size filter check failed.
* Market lot size filter
  * This is an additional check for market order.
  * If `symbol.marketMinQuantity` is not `0`, the order quantity should greater than or equals to `symbol.marketMinQuantity`.
  * If `symbol.marketMaxQuantity` is not `0`, the order quantity should less than or equals to `symbol.marketMaxQuantity`.
  * The order will be rejected if market lot filter check failed.
* Notional filter
  * For limit order, the order notional is `order[i].price * order[i].quantity`.
  * For market order with `order[i].funds` provided, the order notional is `order[i].funds`.
  * For market order without `order[i].funds`, the order notional is estimated as `symbol.lastTradePrice * order[i].quantity`.
  * If `symbol.minNotional` is not `0`, the order notional should greater than or equals to `symbol.minNotional`.
  * If `symbol.maxNotional` is not `0`, the order notional should less than or equals to `symbol.maxNotional`.
  * The order will be rejected if notional filter check failed.
* Other price limitation
  * for limit buy orders, the order price should less than or equal to `symbol.lastTradePrice * (1 + symbol.buyLimitUpRatio)`. Otherwise, the order is rejected.
  * for limit sell orders, the order price should greater than or equal to `symbol.lastTradePrice * (1 - symbol.sellLimitDownRatio)`. Otherwise, the order is rejected.
  * for market buy orders without price, the final execution price is bounded by `symbol.lastTradePrice * (1 + symbol.marketDeviationRatio)`. If price is provided, the final execution price is bounded by `min(order[i].price, symbol.lastTradePrice * (1 + symbol.marketDeviationRatio))`
  * for market sell orders without price, the final execution price is bounded by `symbol.lastTradePrice * (1 - symbol.marketDeviationRatio)`. If price is provided, the final execution price is bounded by `max(order[i].price, symbol.lastTradePrice * (1 - symbol.marketDeviationRatio))`

#### Response

| Field  | Type                  | Description                     |
| ------ | --------------------- | ------------------------------- |
| `data` | `Array<ResponseData>` | Response data when code is `0`. |

* `ResponseData`

  | Name      | Type     | Required | Description                                                                 |
  | --------- | -------- | -------- | --------------------------------------------------------------------------- |
  | `code`    | `int32`  | `true`   | Response status code, `0` for success and other code for failure.           |
  | `clOrdID` | `string` | `true`   | Client order id; same as `clOrdID` in `BatchNewOrderItem`.                  |
  | `error`   | `string` | `false`  | Error description for individual order. Only provided when code is not `0`. |
  | `orderID` | `uint64` | `false`  | Order id. Only provided when the code is `0`.                               |

The length of the response result array is usually the same as the length of batched request.

**Important**: Some errors are a deterministic function of the payload itself, and these are instead returned earlier as part of pre-validation. In this case, only one error is returned for the entire payload, as some of these errors do not apply to a specific order.

For API users that use batching, it's recommended to handle the case where a single error is returned for a batch of multiple orders. In this case, the response could be duplicated n times before being sent to the callback function, as the whole batch was rejected for this same reason.

### Cancel multiple orders

`DELETE ${SPOT_ENDPOINT}/trade/orders/batch`

*Submit multiple order cancellations atomically.*

* Auth: signed write

```bash
curl -X DELETE ${SPOT_ENDPOINT}/trade/orders/batch \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Key: <API-Key>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <BatchCancelOrderRequest>
```

#### Request Body

Find `BatchCancelOrderRequest` and `BatchCancelOrderItem` in [Schema](/documentation/trading-api/rest-v1/schema.md)

Additional Information:

* The batch cannot be empty.
* The length of batch should less than or equals to `100`.

#### Response

| Field  | Type                  | Description                     |
| ------ | --------------------- | ------------------------------- |
| `data` | `Array<ResponseData>` | Response data when code is `0`. |

* `ResponseData`

  | Name          | Type     | Required | Description                                                                 |
  | ------------- | -------- | -------- | --------------------------------------------------------------------------- |
  | `code`        | `int32`  | `true`   | Response status code, `0` for success and other code for failure.           |
  | `clOrdID`     | `string` | `true`   | Client order id; same as `clOrdID` in `BatchCancelOrderItem`.               |
  | `error`       | `string` | `false`  | Error description for individual order. Only provided when code is not `0`. |
  | `orderID`     | `uint64` | `false`  | Order id. Only provided when the code is `0`.                               |
  | `origClOrdID` | `string` | `false`  | Client order id of the canceled order. Only provided when code is `0`.      |

The length of the response result array is usually the same as the length of batched request.

**Important**: Some errors are a deterministic function of the payload itself, and these are instead returned earlier as part of pre-validation. In this case, only one error is returned for the entire payload, as some of these errors do not apply to a specific order.

For API users that use batching, it's recommended to handle the case where a single error is returned for a batch of multiple orders. In this case, the response could be duplicated n times before being sent to the callback function, as the whole batch was rejected for this same reason.

### Replace multiple orders

`POST ${SPOT_ENDPOINT}/trade/orders/replace`

*Replace/modify existing orders atomically.*

* Auth: signed write

```bash
curl -X POST ${SPOT_ENDPOINT}/trade/orders/replace \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Key: <API-Key>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <ReplaceOrderRequest>
```

#### Request Body

Find `ReplaceOrderRequest` and `ReplaceParams` in [Schema](/documentation/trading-api/rest-v1/schema.md)

Additional Information:

* Basic Validation
  * The batch cannot be empty.
  * The length of batch should less than or equals to `100`.
  * Only limit `GTC` and limit `GTX` can be replaced.
  * Only order with status `NEW` and `PARTIALLY_FILLED` can be replaced.
  * Either `replace.origOrderID` or `replace.origClOrdID` should be provided, but not both.
  * At least one of `replace.price` and `replace.quantity` should be provided.
* Price filter
  * The decimal precision of replacement price should not exceed `symbol.pricePrecision`, if provided. That is `replace.price % 10^{-symbol.pricePrecision} = 0`.
  * The replacement price must be multiple of `symbol.tickSize`. That is `replace.price % symbol.tickSize = 0`.
  * If `symbol.minPrice` is not `0`, the replacement price should greater than or equals to `symbol.minPrice`.
  * If `symbol.maxPrice` is not `0`, the replacement price should less than or equals to `symbol.maxPrice`.
  * The replacement will be rejected if price filter check failed.
* Lot size filter
  * The decimal precision of replacement quantity should not exceed `symbol.quantityPrecision`. That is `replace.quantity % 10^{-symbol.quantityPrecision} = 0`.
  * The replacement quantity must be multiple of `symbol.stepSize`. That is `replace.quantity % symbol.stepSize = 0`.
  * If `symbol.minQuantity` is not `0`, the replacement quantity should greater than or equals to `symbol.minQuantity`.
  * If `symbol.maxQuantity` is not `0`, the replacement quantity should less than or equals to `symbol.maxQuantity`.
  * The replacement will be rejected if lot size filter check failed.
* Notional filter
  * The replacement notional is `replace.price * replace.quantity`. If `replace.price` not provided, `order.price` is used. If `replace.quantity` not provided, `order.quantity` is used.
  * If `symbol.minNotional` is not `0`, the replacement notional should greater than or equals to `symbol.minNotional`.
  * If `symbol.maxNotional` is not `0`, the replacement notional should less than or equals to `symbol.maxNotional`.
  * The replacement will be rejected if notional filter check failed.

#### Response

| Field  | Type                  | Description                     |
| ------ | --------------------- | ------------------------------- |
| `data` | `Array<ResponseData>` | Response data when code is `0`. |

* `ResponseData`

  | Name      | Type     | Required | Description                                                                 |
  | --------- | -------- | -------- | --------------------------------------------------------------------------- |
  | `code`    | `int32`  | `true`   | Response status code, `0` for success and other code for failure.           |
  | `clOrdID` | `string` | `true`   | Client order id; same as `clOrdID` in `ReplaceParams`.                      |
  | `error`   | `string` | `false`  | Error description for individual order. Only provided when code is not `0`. |
  | `orderID` | `uint64` | `false`  | Order id of the replaced order. Only provided when the code is `0`.         |

The length of the response result array is usually the same as the length of batched request.

**Important**: Some errors are a deterministic function of the payload itself, and these are instead returned earlier as part of pre-validation. In this case, only one error is returned for the entire payload, as some of these errors do not apply to a specific order.

For API users that use batching, it's recommended to handle the case where a single error is returned for a batch of multiple orders. In this case, the response could be duplicated n times before being sent to the callback function, as the whole batch was rejected for this same reason.

### Schedule cancel orders

`POST ${SPOT_ENDPOINT}/trade/orders/schedule-cancel`

*Schedule a cancel-all operation at a future time. Omitting the time clears the scheduled cancel.*

* Auth: signed write

```bash
curl -X POST ${SPOT_ENDPOINT}/trade/orders/schedule-cancel \
  -H 'Content-Type: application/json' \
  -H 'Accept: application/json' \
  -H 'X-API-Key: <API-Key>' \
  -H 'X-API-Sign: <API-Sign>' \
  -H 'X-API-Nonce: <API-Nonce>' \
  -d <ScheduleCancelRequest>
```

#### Request Body

See [`ScheduleCancelRequest`](/documentation/trading-api/rest-v1/schema.md#schedulecancelrequest) in [Schema](/documentation/trading-api/rest-v1/schema.md)

| Name                 | Type     | Required | Description                                                             |
| -------------------- | -------- | -------- | ----------------------------------------------------------------------- |
| `accountID`          | `uint64` | `true`   | Account identifier.                                                     |
| `scheduledTimestamp` | `uint64` | `false`  | Unix timestamp in milliseconds when the cancel-all should be triggered. |

Additional Information:

* The scheduled time must be at least `5` seconds after the current time.
* When triggered, all open orders are canceled and a trigger count increments (max `10` per day, resets at `00:00 UTC`).
* Omitting `scheduledTimestamp` removes the scheduled cancel.

#### Response

* No endpoint-specific `data` payload.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://sodex.com/documentation/trading-api/rest-v1/sodex-rest-spot-api.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
