Use this file to discover all available pages before exploring further.
The Price API streams real-time indicative prices from Bebop’s market makers over WebSocket using protobuf-encoded messages. This guide walks you through connecting, decoding, and processing the stream.
What you’ll build: A WebSocket client that receives and decodes real-time pricing data.Time required: 10-15 minutesPrerequisites: Python 3.10+, uv (or pip), and an API key from Bebop.
Bids are ordered best (highest) first, asks are ordered best (lowest) first. Each level represents a price point with available size in base token units.For example, if bids = [2450.50, 1.5, 2449.80, 3.0], that means:
Putting it all together - a complete script that connects, resolves a trading pair, and prints live pricing:
import asyncioimport httpximport websocketsfrom bebop_pb2 import BebopPricingUpdate # type: ignoreNETWORK = "ethereum"USERNAME = "<you_username>"API_KEY = "<your_api_key>"WSS_URL = ( f"wss://api.bebop.xyz/pmm/{NETWORK}/v3/pricing" f"?format=protobuf" f"&name={USERNAME}" f"&authorization={API_KEY}" f"&gasless=false" f"&expiry_type=standard")PAIR = "WETH/USDC"def address_to_hex(b: bytes) -> str: return "0x" + b.hex()def to_levels(flat: list[float]) -> list[tuple[float, float]]: it = iter(flat) return list(zip(it, it, strict=True))# 1. Resolve token addressesresp = httpx.get(f"https://api.bebop.xyz/pmm/{NETWORK}/v3/tokenlist", timeout=10.0)tokens = {t["symbol"]: t for t in resp.json().get("tokens", {})}base_symbol, quote_symbol = PAIR.split("/")base_addr = tokens[base_symbol]["address"].lower()quote_addr = tokens[quote_symbol]["address"].lower()# 2. Connect to the pricing streamasync def main(): async with websockets.connect( WSS_URL, ping_interval=20, ping_timeout=10, max_size=2**21 ) as ws: print(f"Connected - streaming {PAIR} on {NETWORK}\n") async for blob in ws: update = BebopPricingUpdate() update.ParseFromString(blob) for pair in update.pairs: if ( address_to_hex(pair.base).lower() != base_addr or address_to_hex(pair.quote).lower() != quote_addr ): continue bids = to_levels(list(pair.bids)) asks = to_levels(list(pair.asks)) if not bids or not asks: continue best_bid = bids[0][0] best_ask = asks[0][0] mid = (best_bid + best_ask) / 2 spread = (best_ask - best_bid) / mid * 10_000 print( f"{PAIR} mid: {mid:.2f} " f"spread: {spread:.1f} bps " f"best bid: {best_bid:.2f} " f"best ask: {best_ask:.2f} " f"levels: {len(bids)}b / {len(asks)}a" )asyncio.run(main())
Prices are indicative. The Price API streams real-time market data for monitoring and pre-trade analysis. To get firm, executable quotes, use the RFQ API.