Perpetual Futures Trading
Place and manage perpetual futures orders on GaiaEx via API: market, limit, stop-loss, and take-profit order types.
Place Order
POST https://openapi.gaiaex.com/v1/trade/order
Place a new perpetual order (market or limit).
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_address | string | Yes | Your wallet address |
symbol | string | Yes | Trading symbol (e.g., BTC, xyz:AAPL) |
is_buy | boolean | Yes | true for buy/long, false for sell/short |
size | string | Yes | Order size in contracts |
price | string | No | Limit price. Required for limit orders, omit for market. |
order_type | string | No | "market" (default) or "limit" |
reduce_only | boolean | No | If true, only reduces existing position (default: false) |
tp_price | string | No | Take-profit trigger price |
sl_price | string | No | Stop-loss trigger price |
leverage | int | No | Set leverage before placing (convenience field) |
leverage_type | string | No | "Cross" or "Isolated" |
client_id | string | No | Client-assigned order ID for idempotency |
Example Request:
{
"user_address": "0xYourAddress",
"symbol": "ETH",
"is_buy": true,
"size": "0.1",
"price": "3500.00",
"order_type": "limit"
}Response:
{
"success": true,
"orderId": 987654321,
"status": "resting",
"symbol": "ETH",
"side": "BUY",
"type": "LIMIT",
"origQty": "0.1",
"price": "3500.00",
"timestamp": 1743508800000
}TIP
For market orders, omit the price field and set order_type to "market" (or omit it, since "market" is the default).
Code Examples
AUTHENTICATION
The primary authentication method is a Bearer JWT session token in the Authorization header. HMAC API keys (X-GAIAEX-APIKEY / X-GAIAEX-TIMESTAMP / X-GAIAEX-SIGNATURE) are an alternative method intended for automated bots. The examples below use HMAC for illustration.
Python
import time, hmac, hashlib, requests, json
API_KEY = "your_api_key"
API_SECRET = "your_api_secret"
BASE = "https://openapi.gaiaex.com/v1/trade"
body = json.dumps({
"user_address": "0xYourAddress",
"symbol": "ETH",
"is_buy": True,
"size": "0.1",
"price": "3500.00",
"order_type": "limit"
})
timestamp = str(int(time.time() * 1000))
message = timestamp + "POST" + "/order" + body
signature = hmac.new(
API_SECRET.encode(), message.encode(), hashlib.sha256
).hexdigest()
resp = requests.post(f"{BASE}/order", data=body, headers={
"Content-Type": "application/json",
"X-GAIAEX-APIKEY": API_KEY,
"X-GAIAEX-TIMESTAMP": timestamp,
"X-GAIAEX-SIGNATURE": signature,
})
print(resp.json())JavaScript
const crypto = require('crypto');
const API_KEY = 'your_api_key';
const API_SECRET = 'your_api_secret';
const BASE = 'https://openapi.gaiaex.com/v1/trade';
const body = JSON.stringify({
user_address: '0xYourAddress',
symbol: 'ETH',
is_buy: true,
size: '0.1',
price: '3500.00',
order_type: 'limit'
});
const timestamp = Date.now().toString();
const message = timestamp + 'POST' + '/order' + body;
const signature = crypto
.createHmac('sha256', API_SECRET)
.update(message)
.digest('hex');
const resp = await fetch(`${BASE}/order`, {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-GAIAEX-APIKEY': API_KEY,
'X-GAIAEX-TIMESTAMP': timestamp,
'X-GAIAEX-SIGNATURE': signature,
},
body,
});
console.log(await resp.json());curl
TIMESTAMP=$(date +%s000)
BODY='{"user_address":"0xYourAddress","symbol":"ETH","is_buy":true,"size":"0.1","price":"3500.00","order_type":"limit"}'
SIGNATURE=$(echo -n "${TIMESTAMP}POST/order${BODY}" | \
openssl dgst -sha256 -hmac "your_api_secret" | awk '{print $2}')
curl -X POST https://openapi.gaiaex.com/v1/trade/order \
-H "Content-Type: application/json" \
-H "X-GAIAEX-APIKEY: your_api_key" \
-H "X-GAIAEX-TIMESTAMP: ${TIMESTAMP}" \
-H "X-GAIAEX-SIGNATURE: ${SIGNATURE}" \
-d "${BODY}"Cancel Order
POST https://openapi.gaiaex.com/v1/trade/order/cancel
Cancel a single open order by its order ID.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_address | string | Yes | Your wallet address |
symbol | string | Yes | Symbol of the order |
order_id | int | Yes | The order ID to cancel |
Example Request:
{
"user_address": "0xYourAddress",
"symbol": "ETH",
"order_id": 987654321
}Response:
{
"success": true,
"orderId": 987654321,
"symbol": "ETH",
"status": "CANCELED",
"timestamp": 1743508800000
}INFO
After modifying an order via POST /order/modify, always use the orderId returned by the modify response for subsequent cancel or modify calls — it may or may not differ from the original.
Code Examples
The gaiaex_post and gaiaexPost helpers include HMAC signing. See the Quick Start page for their implementation.
Python
body = json.dumps({
"user_address": "0xYourAddress",
"symbol": "ETH",
"order_id": 987654321
})
resp = gaiaex_post("/order/cancel", body)
print(resp.json())JavaScript
const body = JSON.stringify({
user_address: '0xYourAddress',
symbol: 'ETH',
order_id: 987654321,
});
const resp = await gaiaexPost('/order/cancel', body);
console.log(await resp.json());curl
BODY='{"user_address":"0xYourAddress","symbol":"ETH","order_id":987654321}'
# Sign and send (see Place Order for full signing example)
curl -X POST https://openapi.gaiaex.com/v1/trade/order/cancel \
-H "Content-Type: application/json" \
-H "X-GAIAEX-APIKEY: your_api_key" \
-H "X-GAIAEX-TIMESTAMP: ${TIMESTAMP}" \
-H "X-GAIAEX-SIGNATURE: ${SIGNATURE}" \
-d "${BODY}"Cancel All Orders
POST https://openapi.gaiaex.com/v1/trade/order/cancel-all
Cancel all open orders, optionally filtered by symbol.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_address | string | Yes | Your wallet address |
symbol | string | No | Filter by symbol. If omitted, cancels all open orders. |
Response:
{
"success": true,
"cancelled_count": 5,
"failed_count": 0,
"errors": null,
"cancelled_oids": [111, 222, 333, 444, 555],
"symbol": "ETH",
"timestamp": 1743508800000
}Modify Order
POST https://openapi.gaiaex.com/v1/trade/order/modify
MODIFY ORDER
This endpoint modifies in-place via the exchange's native modify operation; the orderId may remain the same. The response echoes back orderId (which may be the same as the original). Always use orderId from the modify response for any subsequent cancel or modify call. The original id is echoed back as oldOrderId so you can update your local state.
Modify an existing open order. Internally, this modifies the order in-place via the exchange's native modify operation; the orderId may remain the same.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_address | string | Yes | Your wallet address |
order_id | int | Yes | The order ID to modify |
symbol | string | Yes | Trading symbol |
is_buy | boolean | Yes | Direction |
size | string | Yes | New size |
price | string | Yes | New price |
order_type | string | No | "limit" (default) |
reduce_only | boolean | No | Default false |
Example Request:
{
"user_address": "0xYourAddress",
"order_id": 987654321,
"symbol": "ETH",
"is_buy": true,
"size": "0.2",
"price": "3400.00"
}Response:
{
"success": true,
"orderId": 987654322,
"oldOrderId": 987654321,
"status": "MODIFIED",
"symbol": "ETH",
"note": "The order was modified in-place. Use 'orderId' for subsequent cancel or modify.",
"timestamp": 1743508800000
}IMPORTANT
Use orderId from the modify response for any subsequent cancel/modify. The value of oldOrderId is the id you passed in — it may or may not remain valid. Update your local state to point at orderId after every modify.
Set Take-Profit / Stop-Loss
POST https://openapi.gaiaex.com/v1/trade/order/tpsl
Attach a take-profit and/or stop-loss order to an existing position.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_address | string | Yes | Your wallet address |
symbol | string | Yes | Trading symbol |
is_buy | boolean | Yes | Direction of the closing fill — opposite to the position direction. A long position uses false (sell to close); a short position uses true (buy to close). |
size | string | Yes | Size to close |
tp_price | string | No | Take-profit trigger price |
sl_price | string | No | Stop-loss trigger price |
tp_is_market | boolean | No | Use market order for TP (default: true) |
sl_is_market | boolean | No | Use market order for SL (default: true) |
INFO
At least one of tp_price or sl_price must be provided.
Example Request:
{
"user_address": "0xYourAddress",
"symbol": "BTC",
"is_buy": false,
"size": "0.001",
"tp_price": "75000",
"sl_price": "90000"
}Close Position
POST https://openapi.gaiaex.com/v1/trade/position/close
Close an open position partially or fully using a market order.
Request Body:
| Field | Type | Required | Description |
|---|---|---|---|
user_address | string | Yes | Your wallet address |
symbol | string | Yes | Symbol of the position to close |
size | string | No | Size to close. If omitted, closes the entire position. |
slippage | string | No | Maximum slippage tolerance (default: "0.01" = 1%) |
Example Request:
{
"user_address": "0xYourAddress",
"symbol": "ETH",
"slippage": "0.005"
}Response:
{
"success": true,
"orderId": 111222333,
"symbol": "ETH",
"side": "SELL",
"closedQty": "0.1",
"positionSide": "LONG",
"status": "filled",
"reduceOnly": true,
"timestamp": 1743508800000
}