GaiaExGaiaEx
API

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
EnvironmentBase URLStatus
Productionhttps://openapi.gaiaex.com/v1/tradeLive

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.

DomainProtocolPurpose
wss://openapi.gaiaex.comWSSPrimary — REST + WS on the same domain
wss://ws.gaiaex.comWSSDedicated 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.

Streamopenapi.gaiaex.comws.gaiaex.com
Perp Order Bookwss://openapi.gaiaex.com/ws/market/{symbol}wss://ws.gaiaex.com/market/{symbol}
Spot Order Bookwss://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.

Streamopenapi.gaiaex.comws.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_timeout of 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.
FeatureBinanceGaiaEx
SubscriptionJSON {"method":"SUBSCRIBE","params":[...]}URL path (/ws/market/BTC)
UnsubscribeJSON {"method":"UNSUBSCRIBE",...}Close connection, open new one
Multi-streamCombined stream /stream?streams=...One connection per symbol
KeepalivePUT listen key every 30minSend "ping" every 20s
User stream authListen key from RESTToken in Sec-WebSocket-Protocol

Terminal Walkthrough

Step 1: Install wscat

npm install -g wscat

Step 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
< pong

Step 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"))