Contract WebSocket Guide
The BigONE Contract WebSocket API differs significantly from the Spot API. It uses a URL-based subscription model for public data and a Header-based authentication model for private streams.
Prerequisites
- Public URL Base:
wss://api.big.one/ws/contract/v2 - Private URL:
wss://api.big.one/ws/contract/v2/stream - Authentication: Handled via the HTTP
Authorizationheader during the handshake.
Lesson 1: Public Market Data (URL Based)
Unlike the Spot API, where you send a JSON message to subscribe, the Contract API subscribes you based on the URL path you connect to.
The Logic
To watch a specific channel, you open a new connection to that specific URL. If you want to watch multiple markets, you open multiple connections.
Available Channels:
- Order Book:
.../depth@{symbol} - Trades:
.../trades@{symbol} - Candlesticks:
.../candlesticks/{period}@{symbol}
Code Example: Watch BTCUSD Order Book
import asyncio
import websockets
import json
# Note: The symbol is part of the URL
URL = "wss://api.big.one/ws/contract/v2/depth@BTCUSD"
async def watch_depth():
async with websockets.connect(URL) as ws:
print("Connected to BTCUSD Order Book")
while True:
msg = await ws.recv()
data = json.loads(msg)
# The first message is a full snapshot
# Subsequent messages are incremental updates
print(f"Update received. Best Bid: {data['bestPrices']['bid']}")
if __name__ == "__main__":
asyncio.run(watch_depth())
Lesson 2: Private Data Streams (Header Authentication)
To receive updates for your Positions, Orders, and Balances, you connect to a single unified "Stream" channel.
The Logic
- Generate a standard JWT.
- Pass the JWT in the
Authorizationheader during the WebSocket handshake. - The server validates the header. If invalid, the connection is closed with a 401 error.
Private Stream URL: wss://api.big.one/ws/contract/v2/stream
Code Example: Private Updates
import asyncio
import websockets
import json
import time
import jwt
API_KEY = "YOUR_KEY"
SECRET_KEY = "YOUR_SECRET"
def generate_token():
payload = {
"sub": API_KEY,
"nonce": int(time.time() * 1000000),
"iat": int(time.time()),
"exp": int(time.time()) + 60
}
return jwt.encode(payload, SECRET_KEY, algorithm="HS256")
async def watch_private():
token = generate_token()
headers = {"Authorization": f"Bearer {token}"}
url = "wss://api.big.one/ws/contract/v2/stream"
async with websockets.connect(url, extra_headers=headers) as ws:
print("Connected to Private Stream")
while True:
msg = await ws.recv()
data = json.loads(msg)
# The response is a container object
if "positions" in data:
for pos in data['positions']:
print(f"Position Update: {pos['symbol']} size: {pos['size']}")
if "orders" in data:
for order in data['orders']:
print(f"Order {order['id']} is {order['status']}")
if __name__ == "__main__":
asyncio.run(watch_private())
Complete Example: Multi-Stream Bot
For a real trading bot, you usually need to combine both.
import asyncio
import websockets
import json
async def main():
# Run both public and private listeners concurrently
await asyncio.gather(
watch_depth(), # From Lesson 1
watch_private() # From Lesson 2
)
if __name__ == "__main__":
asyncio.run(main())
Conclusion
The Contract WebSocket API is designed for performance with its URL-based routing.
Key Takeaways:
- URL Subscription: Each public market/channel needs its own connection.
- Header Auth: Private streams authenticate during the handshake, not via a message.
- Snapshots: Expect a full snapshot as the first message on every channel.
Next Steps:
- Read the Contract WebSocket Reference for a complete list of
periodandsymbolvalues. - Check the Contract Trading Guide to see how to trigger these updates via REST orders.