GeminiGemini
SandboxGet API key
  • Crypto Trading
  • Prediction Markets
Resources
  • Changelog

© 2026 Gemini Space Station, Inc.

Gemini Crypto Exchange LogoGemini Crypto Exchange Logo
REST APIs
    Orders
    Market Data
    Derivatives
    Margin Trading
    Staking
    Clearing
    Instant Orders
WebSocket
    AuthenticationMessage Format
    Streams
      Book TickerL2 Partial DepthL2 Differential DepthTrade StreamOrder EventsBalance Updates
    Playground
      Overviewconninfopingtimesubscribeunsubscribelist_subscriptionsdepthorder.placeorder.cancelorder.cancel_allorder.cancel_session
Agentic
FIX

Trading on Gemini

Build spot trading applications with real-time market data, order management, and account services on Gemini's institutional-grade exchange.

Get API key

REST APIs

APIs for every type of user — retail, business, and institutional.

1

Get your API credentials

Sign up at exchange.gemini.com, navigate to Settings → API, and create a key with the Trading scope enabled.

Terminal
export GEMINI_API_KEY="account-xxxxxxxxxxxxxxxx"
export GEMINI_API_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
2

Clone the samples repo and install dependencies

Clone the Gemini API samples repository, navigate to the Python directory, and install the required packages (requests and python-dotenv).

Python
git clone https://github.com/gemini/developer-platform.git
cd developer-platform/samples/python
pip install -r requirements.txt
3

Configure your environment

Create a .env file with your API credentials and the sandbox base URL. The sample uses python-dotenv to load these automatically.

Python
cat > .env << 'EOF'
GEMINI_API_KEY=account-xxxxxxxxxxxxxxxx
GEMINI_API_SECRET=xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
GEMINI_BASE_URL=https://api.sandbox.gemini.com/v1
EOF
4

Run the place order example

Run the example to place a sandbox limit order. The script handles HMAC-SHA384 signing automatically.

Terminal
python place_order.py
5

You're done!

Your order is live in the sandbox. Check the response for order_id and use it to query status or cancel.

Python
# Order confirmed ✓
Order placed: {'order_id': '7651834', 'symbol': 'btcusd', 'side': 'buy', ...}

WebSocket

Stream real-time prices, place orders, and receive fill notifications over a persistent WebSocket connection to wss://ws.gemini.com.

1

Set up credentials

Export your API key and secret as environment variables. WebSocket authentication requires account-scoped keys with time-based nonces enabled — keys without these settings will be rejected at connection time.

Terminal
export GEMINI_API_KEY="account-xxxxxxxxxxxxxxxx"
export GEMINI_API_SECRET="xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
2

Connect and stream prices

Connect to wss://ws.gemini.com, sign the handshake headers with your secret, then subscribe to {symbol}@bookTicker for real-time best-bid/ask updates.

Python
# pip install websockets
import asyncio, websockets, hmac, hashlib, base64, json, time

API_KEY = "your-api-key"
API_SECRET = "your-api-secret"
SYMBOL = "BTCUSD"

def auth_headers():
    nonce = str(int(time.time()))
    payload = base64.b64encode(nonce.encode())
    signature = hmac.new(API_SECRET.encode(), payload, hashlib.sha384).hexdigest()
    return {
        "X-GEMINI-APIKEY": API_KEY,
        "X-GEMINI-NONCE": nonce,
        "X-GEMINI-PAYLOAD": payload.decode(),
        "X-GEMINI-SIGNATURE": signature,
    }

async def stream_prices():
    async with websockets.connect("wss://ws.gemini.com", additional_headers=auth_headers()) as ws:
        await ws.send(json.dumps({
            "id": "1",
            "method": "subscribe",
            "params": [f"{SYMBOL}@bookTicker"],
        }))

        async for msg in ws:
            data = json.loads(msg)
            if "b" in data and "a" in data:
                print(f"{data['s']}  bid: ${data['b']} ({data['B']} BTC)  ask: ${data['a']} ({data['A']} BTC)")

asyncio.run(stream_prices())
3

Place an order

Subscribe to orders@account alongside the price stream, then send order.place once you see a price. Use cancelOnDisconnect=true as a query parameter to automatically cancel open orders if your connection drops.

Python
async def trade():
    url = "wss://ws.gemini.com?cancelOnDisconnect=true"
    async with websockets.connect(url, additional_headers=auth_headers()) as ws:
        await ws.send(json.dumps({
            "id": "1",
            "method": "subscribe",
            "params": [
                f"{SYMBOL}@bookTicker",  # live prices
                "orders@account",         # your order updates
            ],
        }))

        # Wait for a price, then place an order
        async for msg in ws:
            data = json.loads(msg)
            if "b" in data and "a" in data and data.get("s") == SYMBOL:
                break

        await ws.send(json.dumps({
            "id": "2",
            "method": "order.place",
            "params": {
                "symbol": SYMBOL,
                "side": "BUY",
                "type": "LIMIT",
                "timeInForce": "GTC",
                "price": "95000.00",
                "quantity": "0.01",
                "clientOrderId": "my-first-ws-order",
            },
        }))
4

Listen for fills & cancel

Order lifecycle events arrive on the orders@account stream. The X field carries the status (NEW, FILLED, etc.). To cancel, send order.cancel with the order ID from the i field.

Python
        # Watch order updates
        # X = status, S = side, p = price, q = quantity
        async for msg in ws:
            data = json.loads(msg)
            if data.get("X") in ("NEW", "OPEN", "FILLED", "PARTIALLY_FILLED"):
                print(f"Order {data['X']}: side={data.get('S')} price=${data.get('p')} qty={data.get('q')}")

            # Cancel once filled
            if data.get("X") == "FILLED":
                await ws.send(json.dumps({
                    "id": "3",
                    "method": "order.cancel",
                    "params": { "orderId": data.get("i") },
                }))
                break
5
Output
BTCUSD  bid: $95000.00 (0.50 BTC)  ask: $95001.00 (0.25 BTC)
Order NEW: side=BUY price=$95000.00 qty=0.01
Order OPEN: side=BUY price=$95000.00 qty=0.01
Order FILLED: side=BUY price=$95000.00 qty=0.01

Agentic

Build AI-powered trading agents using Gemini's MCP server and plug-and-play skills.

$ npm install -g developer-platform/packages/mcp-server
1

Build

Terminal
cd developer-platform/packages/mcp-server
npm install
npm run build
    
2

Configure

Terminal
# For Claude Code: (This will be be different for other tools.)
 claude mcp add gemini -s user -e GEMINI_API_KEY=<your_key> -e \
 GEMINI_API_SECRET=<your_secret> -- node <repo_root>/packages/mcp-server/dist/index.js
    
3

Validate

Terminal
claude mcp list
 
Last modified on April 17, 2026