Skip to main content
The pricing WebSocket receives order books streamed from market makers. Bebop uses your levels to determine whether a path exists for a user order. Pricing updates are Protobufs sent to the /pricing endpoint. See Connection for WebSocket setup. Levels you stream are combined to derive cross-pairs. See Routing › Cross-pair derivation.

Requirements

  • Stream levels against USDC or another chain-appropriate stablecoin. You can also stream against liquid majors like WETH.
  • Quote any cross-pair derivable from your streams.
  • Do not send pricing updates more frequently than every 400 ms.
  • Streamed levels must match the prices you actually quote. Solvers precompute expected prices from your stream; divergence gives them a worse realized price than estimated. Bebop monitors the gap between streams and firm quotes, and repeated divergence can get you banned.
  • Do not include duplicate prices in the same update:
    "bids": [
        [0.443005,100],    // price, amount
        [0.443005,100.2],  // same price, NOT allowed
    ],
    
  • Avoid zero or negative prices and sizes.
  • Keep bids below asks. Bebop ignores pairs where bid ≥ ask until the spread is valid.
  • Bebop ignores pairs with spreads wider than 1000 bps until the spread tightens.
To skip a direction for a pair, send empty bids or asks as an empty array.

Message handling

When Bebop receives a valid pricing update, it sends a success message. Parsing or validation errors come back as error messages.
{
    "chain_id": 1,
    "msg_topic": "pricing",
    "msg_type": "success",
    "msg": {
        "code": 10,
        "text": "Message processed successfully",
        "reason": ""
    }
}
A non-Protobuf message on the Protobuf endpoint closes the WebSocket connection.

Sending pricing updates as Protobufs

Pricing updates must use Protobuf. JSON pricing is deprecated. See Connection › Endpoints for the pricing endpoint URL.

Schema

levels_update.proto
syntax = "proto3";

package bebop;

message LevelInfo {
  bytes base_address = 1;
  uint32 base_decimals = 2;
  bytes quote_address = 3;
  uint32 quote_decimals = 4;
  repeated double bids = 5 [packed=true];  // [price, amount, price, amount, ...]
  repeated double asks = 6 [packed=true];  // [price, amount, price, amount, ...]
}

message LevelMsg {
  repeated LevelInfo levels = 1;
  bytes maker_address = 2;
}

message LevelsSchema {
  uint32 chain_id = 1;
  string msg_topic = 2;  // pricing
  string msg_type = 3;  // update
  LevelMsg msg = 4;
}

Parsing incoming messages

Generate Protobuf classes from the two schemas above using protoc. See protobuf.dev/installation if you’re new to Protobuf. Then parse incoming WebSocket messages with the generated classes:
raw_message: bytes = await websocket.recv()
protobuf_msg: WebSocketResponse = websocket_response_pb2.WebSocketResponse.FromString(raw_message)