# Perps REST API

## Perps Market Endpoints

### Query symbols

`GET ${PERPS_ENDPOINT}/markets/symbols`

*Get perpetual contract information for all symbols.*

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

#### Query Parameters

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

#### Response

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

### Query coins

`GET ${PERPS_ENDPOINT}/markets/coins`

*Get information for all coins.*

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

#### Query Parameters

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

#### Response

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

### Query tickers

`GET ${PERPS_ENDPOINT}/markets/tickers`

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

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

#### Query Parameters

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

#### Response

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

### Query mini tickers

`GET ${PERPS_ENDPOINT}/markets/miniTickers`

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

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

#### Query Parameters

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

#### 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 mark prices

`GET ${PERPS_ENDPOINT}/markets/mark-prices`

*Mark price information for symbols.*

```bash
curl -X GET ${PERPS_ENDPOINT}/markets/mark-prices \
  -H 'Accept: application/json'
```

#### Query Parameters

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

#### Response

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

### Query book tickers

`GET ${PERPS_ENDPOINT}/markets/bookTickers`

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

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

#### Query Parameters

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

#### 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 ${PERPS_ENDPOINT}/markets/{symbol}/orderbook`

*Get order book depth for a perpetual symbol.*

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

#### Path Parameters

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

#### 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 ${PERPS_ENDPOINT}/markets/{symbol}/klines`

*Get candlestick/kline data for a perpetual symbol.*

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

#### Path Parameters

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

#### Query Parameters

| Name        | Type     | Required | Description                                                                                                                                                                                                                                                                        |
| ----------- | -------- | -------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `interval`  | `string` | `true`   | Kline interval (case-sensitive): `1m`, `5m`, `15m`, `30m`, `1h`, `4h`, `1d`, `1w`, `1M`. Note: day/week use lowercase (`1d`, `1w`); only month is uppercase (`1M`). The perps engine supports a smaller set than spot — `3m`, `2h`, `6h`, `8h`, `12h`, `3d` are **not** available. |
| `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: `1000`                                                                                                                                                                                                                            |

#### 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 ${PERPS_ENDPOINT}/markets/{symbol}/trades`

*Get recent public trades for a perpetual symbol.*

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

#### Path Parameters

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

#### 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) |

## Perps Account Endpoints

### Query balances

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

*Get current account balance.*

```bash
curl -X GET ${PERPS_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` | `PerpsAccountBalance` | Response data when code is `0`. See [`PerpsAccountBalance`](/documentation/trading-api/rest-v1/schema.md#perpsaccountbalance) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query open orders

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

*Get all open orders for an account.*

```bash
curl -X GET "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/orders?symbol=BTC-USD" \
  -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` | `PerpsAccountOpenOrder` | Response data when code is `0`. See [`PerpsAccountOpenOrder`](/documentation/trading-api/rest-v1/schema.md#perpsaccountopenorder) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query open positions

`GET ${PERPS_ENDPOINT}/accounts/{userAddress}/positions`

*Get all open positions for an account.*

```bash
curl -X GET "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/positions" \
  -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` | `PerpsAccountOpenPosition` | Response data when code is `0`. See [`PerpsAccountOpenPosition`](/documentation/trading-api/rest-v1/schema.md#perpsaccountopenposition) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query state for frontend

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

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

```bash
curl -X GET ${PERPS_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` | `WsPerpsState` | Response data when code is `0`. See [`WsPerpsState`](/documentation/trading-api/rest-v1/schema.md#wsperpsstate) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query API Keys

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

*Get list of API keys.*

```bash
curl -X GET "${PERPS_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 ${PERPS_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 "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/fee-rate?symbol=BTC-USD" \
  -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. `BTC-USD`. 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 ${PERPS_ENDPOINT}/accounts/{userAddress}/orders/history`

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

```bash
curl -X GET "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/orders/history?symbol=BTC-USD" \
  -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<PerpsOrder>` | Response data when code is `0`. See [`PerpsOrder`](/documentation/trading-api/rest-v1/schema.md#perpsorder) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Query position history

`GET ${PERPS_ENDPOINT}/accounts/{userAddress}/positions/history`

*Get historical positions (closed) for an account.*

```bash
curl -X GET "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/positions/history?symbol=BTC-USD" \
  -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 positions to return. Default: `50`, Max: `500`               |

#### Response

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

### Query trades

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

*Get historical trade executions for an account.*

```bash
curl -X GET "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/trades?symbol=BTC-USD&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) |

### Query funding history

`GET ${PERPS_ENDPOINT}/accounts/{userAddress}/fundings`

*Get historical funding payments (paid or received) for an account.*

```bash
curl -X GET "${PERPS_ENDPOINT}/accounts/0x0123456789070ce8f0d6bab722103d12674bc257/fundings?symbol=BTC-USD" \
  -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                                                  |
| `positionID` | `uint64` | `false`  | Filter by position 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<PerpsUserFunding>` | Response data when code is `0`. See [`PerpsUserFunding`](/documentation/trading-api/rest-v1/schema.md#perpsuserfunding) in [Schema](/documentation/trading-api/rest-v1/schema.md) |

### Transfer asset to spot

`POST ${PERPS_ENDPOINT}/accounts/transfers`

*Transfer assets between accounts.*

* Auth: signed write

```bash
curl -X POST ${PERPS_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.
* Number of decimal places of `transfer.amount` should not exceed coin precision.
* Transfer asset to spot chain: `transfer.toAccountID=999`, `transfer.type=SPOT_WITHDRAW`
* Transfer assets to the EVM chain is not supported yet.
* Internal transfer between perps chains is not supported yet.
* The request is rejected when margin check failed.

#### 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`. |

### Update collateral

`POST ${PERPS_ENDPOINT}/trade/collateral`

*Add or remove cross-margin collateral for a non-USDC asset.*

> Testnet only. This endpoint is currently available on testnet environments only.

* Auth: signed write

```bash
curl -X POST ${PERPS_ENDPOINT}/trade/collateral \
  -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 <UpdateCollateralRequest>
```

#### Request Body

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

Additional Information:

* `coinID` must be a non-USDC coin. `coinID=0` is rejected.
* Number of decimal places of `amount` should not exceed the target coin precision.
* The `amount` must be a non-zero value.
* Positive `amount` adds wallet balance to collateral; negative `amount` removes collateral back to free wallet balance.

#### Response

* No endpoint-specific `data` payload.

## Perps Trading Endpoints

### Place multiple orders

`POST ${PERPS_ENDPOINT}/trade/orders`

*Submit one or more perpetual orders in a single signed payload.*

* Auth: signed write

```bash
curl -X POST ${PERPS_ENDPOINT}/trade/orders \
  -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 <PerpsNewOrderRequest>
```

#### Request Body

Find `PerpsNewOrderRequest` and `PerpsOrderItem` 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`.
  * The `order[i].clOrdID` must match `^[0-9a-zA-Z_-]{1,36}$`.
  * The `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.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 decimal precision of order stop price should not exceed `symbol.pricePrecision`. That is `order[i].stopPrice % 10^{-symbol.pricePrecision} = 0`.
  * The order stop price must be multiple of `symbol.tickSize`. That is `order[i].stopPrice % symbol.tickSize = 0`.
  * If `symbol.minPrice` is not `0`, the order stop price should greater than or equals to `symbol.minPrice`.
  * If `symbol.maxPrice` is not `0`, the order stop 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.
* Margin check
  * The order will be rejected if account margin is not enough to place the order.
* Other price limitation for non-TP/SL orders.
  * for limit buy orders, the order price should less than or equal to `symbol.markPrice * (1 + symbol.buyLimitUpRatio)`. Otherwise, the order is rejected.
  * for limit sell orders, the order price should greater than or equal to `symbol.markPrice * (1 - symbol.sellLimitDownRatio)`. Otherwise, the order is rejected.
  * for market buy orders without price, the final execution price is bounded by `symbol.indexPrice * (1 + symbol.marketDeviationRatio)`. If price is provided, the final execution price is bounded by `min(order[i].price, symbol.indexPrice * (1 + symbol.marketDeviationRatio))`
  * for market sell orders without price, the final execution price is bounded by `symbol.indexPrice * (1 - symbol.marketDeviationRatio)`. If price is provided, the final execution price is bounded by `max(order[i].price, symbol.indexPrice * (1 - symbol.marketDeviationRatio))`
* For order with TP/SL
  * The length of batch should be `2` or `3`.
  * The `orders[0].modifier = BRACKET`, `orders[1 or 2].modifier = ATTACHED_STOP`.
  * The `orders[0].reduceOnly = false`, `orders[1 or 2].reduceOnly = true`.
  * The `orders[1 or 2].stopPrice`, `orders[1 or 2].stopType`, `orders[1 or 2].triggerType` are provided.
  * Only one of `orders[1]` and `orders[2]` is take profit order.
  * Only one of `orders[1]` and `orders[2]` is stop loss order.
* For Position with TP/SL
  * The user has a position with this symbol.
  * The `orders[i].modifier = STOP`.
  * The `orders[i].reduceOnly = true`.
  * The `orders[i].stopPrice`, `orders[i].stopType`, `orders[i].triggerType` are provided.
  * For TP/SL without quantity, it is treated as global TP/SL. When triggered, generated order will have full position size as quantity.
* For TP/SL without order and position (standalone TP/SL)
  * `orders[i].modifier = STOP`
  * `orders[i].reduceOnly = false`
  * The `orders[i].stopPrice`, `orders[i].stopType`, `orders[i].triggerType` are provided.

#### 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 `PerpsNewOrderRequest`.               |
  | `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 ${PERPS_ENDPOINT}/trade/orders`

*Cancel one or more orders by order ID or client order ID.*

* Auth: signed write

```bash
curl -X DELETE ${PERPS_ENDPOINT}/trade/orders \
  -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 <PerpsCancelOrderRequest>
```

#### Request Body

Find `PerpsCancelOrderRequest` and `PerpsCancelItem` 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`.
* The `cancel[i].clOrdID` should match `^[0-9a-zA-Z_-]{1,36}$`, if provided.
* Provide either `cancel[i].orderID` or `cancel[i].clOrdID`, but not both.

#### 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 `PerpsCancelOrderRequest`.            |
  | `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.

### Replace multiple orders

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

*Replace/modify existing orders atomically.*

* Auth: signed write

```bash
curl -X POST ${PERPS_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

See [`ReplaceOrderRequest`](/documentation/trading-api/rest-v1/schema.md#replaceorderrequest) 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 non-TP/SL 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.
* Margin check
  * The replacement will be rejected if account margin is not enough to replace the order.

#### 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.

### Modify TP/SL order

`POST ${PERPS_ENDPOINT}/trade/orders/modify`

*Replace/modify an existing TP/SL order.*

* Auth: signed write

```bash
curl -X POST ${PERPS_ENDPOINT}/trade/orders/modify \
  -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 <ModifyOrderRequest>
```

#### Request Body

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

Additional Information:

* The order must be a TP/SL order.
* Provide either `modify.orderID` or `cmodify.lOrdID`, but not both.
* Provide at least one of `modify.price`, `modify.quantity`, or `modify.stopPrice`.
* The `modify.price` and `modify.stopPrice` must pass price filter.
* The `modify.quantity` must pass lot size filter and market lot size filter.
* The `modify.price` and `modify.quantity` must pass notional filter.

#### Response

* No endpoint-specific `data` payload.

### Schedule cancel orders

`POST ${PERPS_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 ${PERPS_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.

### Update leverage

`POST ${PERPS_ENDPOINT}/trade/leverage`

*Update leverage and margin mode for a symbol.*

* Auth: signed write

```bash
curl -X POST ${PERPS_ENDPOINT}/trade/leverage \
  -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 <UpdateLeverageRequest>
```

#### Request Body

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

Additional Information:

* The leverage must less than or equals to `symbol.maxLeverage`.
* The request is rejected when this account has open orders or open positions on this symbol.

#### Response

* No endpoint-specific `data` payload.

### Update isolated margin

`POST ${PERPS_ENDPOINT}/trade/margin`

*Add or remove margin from an isolated position.*

* Auth: signed write

```bash
curl -X POST ${PERPS_ENDPOINT}/trade/margin \
  -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 <UpdateMarginRequest>
```

#### Request Body

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

Additional Information:

* Number of decimal places of `transfer.amount` should not exceed coin (`vUSDC`) precision. That is `transfer.amount % 10^{-coin.precision} = 0`.
* The `transfer.amount` must be a non-zero value.
* The request is rejected when margin check failed.

#### 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-perps-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.
