API & WebSocket Servers
REST and WebSocket base URLs, connection endpoints, keep-alive requirements, and rate limits for GaiaEx API access.
REST Base URL
All REST API requests are sent to:
https://openapi.gaiaex.com/v1/trade| Environment | Base URL | Status |
|---|---|---|
| Production | https://openapi.gaiaex.com/v1/trade | Live |
All endpoints accept and return application/json. HMAC-SHA256 or Bearer token authentication is required for private endpoints.
WebSocket Servers
GaiaEx provides two WebSocket domains. Both connect to the same backend — choose whichever is convenient.
| Domain | Protocol | Purpose |
|---|---|---|
wss://openapi.gaiaex.com | WSS | Primary — REST + WS on the same domain |
wss://ws.gaiaex.com | WSS | Dedicated WS domain (shorter paths) |
INFO
Both domains use TLS (wss://). Unencrypted ws:// connections are not accepted in production.
Public Streams (No Auth)
Public streams do not require authentication. Connect directly with the symbol in the URL path.
| Stream | openapi.gaiaex.com | ws.gaiaex.com |
|---|---|---|
| Perp Order Book | wss://openapi.gaiaex.com/ws/market/{symbol} | wss://ws.gaiaex.com/market/{symbol} |
| Spot Order Book | wss://openapi.gaiaex.com/ws/market/spot/{symbol} | wss://ws.gaiaex.com/market/spot/{symbol} |
Replace {symbol} with the trading symbol, e.g. BTC, ETH, xyz:AAPL.
Private Streams (Auth Required)
Private streams require a valid session token. See the User Data Stream page for authentication methods.
| Stream | openapi.gaiaex.com | ws.gaiaex.com |
|---|---|---|
| User Data (positions, orders, balance) | wss://openapi.gaiaex.com/ws/user/{address} | wss://ws.gaiaex.com/user/{address} |
| Wallet (on-chain balances, swaps) | wss://openapi.gaiaex.com/ws/wallet/{address} | wss://ws.gaiaex.com/wallet/{address} |
Replace {address} with the user's wallet address (e.g. 0xA6E3...).
WARNING
The wss://ws.gaiaex.com/wallet/{address} path has a known nginx routing issue — the proxy is missing the /ws/ prefix rewrite for the /wallet/ path. Use wss://openapi.gaiaex.com/ws/wallet/{address} instead to ensure correct routing.
Connection Notes
- Ping/Pong: Send a text message
"ping"to keep the connection alive. The server responds with"pong". - Reconnection: If the connection drops, reconnect with exponential backoff (1s, 2s, 4s, ..., max 30s).
- No subscribe/unsubscribe: Unlike Binance, GaiaEx uses URL-path-based subscriptions. To change the symbol, open a new connection.
- Idle timeout: The nginx proxy is configured with a
proxy_read_timeoutof 86,400 seconds (24 hours) — this is a proxy-level configuration, not an application-level close. Send periodic pings to keep the connection alive. - Compression: Per-message deflate is supported but not required.
| Feature | Binance | GaiaEx |
|---|---|---|
| Subscription | JSON {"method":"SUBSCRIBE","params":[...]} | URL path (/ws/market/BTC) |
| Unsubscribe | JSON {"method":"UNSUBSCRIBE",...} | Close connection, open new one |
| Multi-stream | Combined stream /stream?streams=... | One connection per symbol |
| Keepalive | PUT listen key every 30min | Send "ping" every 20s |
| User stream auth | Listen key from REST | Token in Sec-WebSocket-Protocol |
Terminal Walkthrough
Step 1: Install wscat
npm install -g wscatStep 2: Connect to Public Orderbook
$ wscat -c wss://openapi.gaiaex.com/ws/market/BTC
Connected (press CTRL+C to quit)
< {"type":"orderbook","symbol":"BTC","bids":[["84250.00","1.234"],["84249.50","0.500"]],"asks":[["84251.50","0.800"]],"priceDecimals":2,"timestamp":1712345678000,"stale":false,"displayName":"BTC","feed_connected":true}
> ping
< pongStep 3: Connect to Private User Stream
$ wscat -c wss://openapi.gaiaex.com/ws/user/0xYourAddress \
-s "Bearer.your_session_token_here"
Connected (press CTRL+C to quit)
< {"type":"update","positions":[],"orders":[],"balance":{"usdc_balance":"1000.00","available":"1000.00"},...}Step 4: Python — Multi-Symbol Monitoring
import asyncio
import json
import websockets
SYMBOLS = ["BTC", "ETH", "SOL"]
async def monitor_symbol(symbol: str):
uri = f"wss://openapi.gaiaex.com/ws/market/{symbol}"
async with websockets.connect(uri) as ws:
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "orderbook" and msg.get("bids"):
top_bid = msg["bids"][0]
print(f"{symbol}: {top_bid[0]} x {top_bid[1]}")
async def main():
await asyncio.gather(*(monitor_symbol(s) for s in SYMBOLS))
asyncio.run(main())Step 5: Python — Reconnection with Exponential Backoff
import asyncio
import json
import websockets
async def stream_with_reconnect(symbol: str):
delay = 1
while True:
try:
uri = f"wss://openapi.gaiaex.com/ws/market/{symbol}"
async with websockets.connect(uri) as ws:
delay = 1 # Reset on successful connect
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "orderbook":
print(f"{symbol}: {len(msg.get('bids', []))} bids, {len(msg.get('asks', []))} asks")
except (websockets.ConnectionClosed, OSError) as e:
print(f"Disconnected: {e}. Reconnecting in {delay}s...")
await asyncio.sleep(delay)
delay = min(delay * 2, 30) # Max 30s backoff
asyncio.run(stream_with_reconnect("ETH"))