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 |
| Testnet | https://testnet.openapi.gaiaex.com/v1/trade | Coming Q3 2026 |
TESTNET
The testnet environment is under development. It will provide a full sandbox with test funds for integration testing. Contact [email protected] for early access.
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...).
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: Connections without activity are closed after 86,400 seconds (24 hours). Send periodic pings to keep 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","coin":"BTC","levels":[{"px":"84250.00","sz":"1.234","n":3}],"time":1712345678000}
< {"type":"orderbook","coin":"BTC","levels":[{"px":"84251.50","sz":"0.500","n":1}],"time":1712345679000}
> 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("levels"):
top = msg["levels"][0]
print(f"{symbol}: {top['px']} x {top['sz']}")
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('levels', []))} levels")
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"))