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" |
time_in_force | string | No | "GTC" (default), "IOC", or "ALO". GTC = Good Till Cancelled; IOC = Immediate Or Cancel; ALO = Add Liquidity Only (Post-Only). |
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": "open",
"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
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}"Test Order
POST https://openapi.gaiaex.com/v1/trade/order/test
Validates an order without actually placing it. Useful for testing your integration. Accepts the same request body as POST /order.
Response (on validation success):
{
"success": true,
"message": "Order validation passed",
"symbol": "BTC",
"side": "BUY",
"type": "LIMIT",
"origQty": "0.001",
"price": "80000",
"timestamp": 1743508800000
}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": "cancelled",
"timestamp": 1743508800000
}WARNING
After modifying an order via POST /order/modify, the original orderId is invalidated. Always use the new orderId returned by the modify response.
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": [],
"cancelled_oids": [111, 222, 333, 444, 555],
"symbol": "ETH",
"timestamp": 1743508800000
}Modify Order
POST https://openapi.gaiaex.com/v1/trade/order/modify
MODIFY REPLACES THE ORDER
This endpoint cancels the original order and creates a new one. The response returns a new orderId; the old id is no longer valid. 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 cancels the original order and places a new one, returning a new order ID.
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 replaced. Use 'orderId' for subsequent cancel or modify.",
"timestamp": 1743508800000
}IMPORTANT
Use orderId (the new id) for any subsequent cancel/modify. The value of oldOrderId is the id you passed in — it is now void. 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 TP/SL trigger side |
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
}