Skip to main content

Stream Filtering Guide

Updated on
Jan 07, 2026

Overview

Hyperliquid streaming APIs support powerful filtering capabilities to help you receive only the data you need. Filters work across gRPC, JSON-RPC, and WebSocket protocols, allowing you to subscribe to specific events, users, trading pairs, and more.

Supported Protocols:


  • gRPC Streaming API - High-performance streaming with filters
  • JSON-RPC over WebSocket - Standard WebSocket filtering
  • WebSocket API - Real-time filtered subscriptions

Why Use Filtering?

Without filtering, streaming from Hyperliquid can generate massive amounts of data. The exchange processes thousands of trades, orders, and events per minute across hundreds of trading pairs. Filtering is essential because it allows you to:

  • Reduce bandwidth and improve performance - Receive only relevant data instead of processing everything, significantly reducing network traffic and processing overhead
  • Focus on specific data - Track particular trading pairs, users, or event types instead of consuming all market data
  • Build efficient applications - Create focused applications without overwhelming data streams that could impact performance
  • Enable real-time decision making - Process targeted data faster for alerts, notifications, and trading decisions

Basic Filtering Concepts

Before diving into syntax, here are the key concepts:


  1. Streams - Different data types (trades, orders, events, etc.)
  2. Fields - Properties within each stream that can be filtered
  3. Values - Specific criteria you want to match
  4. Logic - How multiple filters combine (AND/OR)

Simple Example:

"I want to see only BTC trades that are buys (not sells)"

Filter: {"coin": ["BTC"], "side": ["B"]}

Available Streams

Stream Name
trades
Description
Filled trades/executions
Data Format
Tuple: [user_address, fill_data]
Stream Name
orders
Description
Order status updates
Data Format
Object with order fields
Stream Name
book_updates
Description
Order book changes
Data Format
Object with price/size
Stream Name
twap_orders
Description
TWAP order statuses
Data Format
Flexible object
Stream Name
events
Description
Ledger updates, deposits, withdrawals, funding
Data Format
Nested object
Stream Name
writer_actions
Description
System actions, spot sends
Data Format
Object with action type
Stream Name
blocks
Description
Raw replica commands (gRPC only, NO FILTERING)
Data Format
Full block data

Filter Syntax

Both WebSocket and gRPC APIs use the same filter logic, but with different syntax formats:


{
"jsonrpc": "2.0",
"method": "hl_subscribe",
"params": {
"streams": ["<stream_name>"],
"filters": {
"<field_name>": ["<value1>", "<value2>"]
}
},
"id": 1
}

Filter Logic

AND Across Fields

When multiple fields are specified, ALL must match:

{"filters": {"coin": ["BTC"], "side": ["B"]}}

Returns events where coin=BTC AND side=B

OR Within Field

When multiple values are specified for one field, ANY can match:

{"filters": {"coin": ["BTC", "ETH", "HYPE"]}}

Returns events where coin=BTC OR coin=ETH OR coin=HYPE

Combined Example

{"filters": {"coin": ["BTC", "ETH"], "side": ["B"]}}

Returns events where (coin=BTC OR coin=ETH) AND side=B

Recursive Field Matching

Filters automatically search through nested JSON objects:

// This data:
{"inner": {"LedgerUpdate": {"users": ["0xABC"], "delta": {"type": "deposit"}}}}

// Matches this filter:
{"filters": {"type": ["deposit"]}}

Special Filter Values

Value
"*"
Meaning
Field exists (any value)
Use Case
Find all liquidations: {"liquidation": ["*"]}
Value
"exists"
Meaning
Same as "*"
Use Case
Alternative syntax: {"liquidation": ["exists"]}
Value
"null"
Meaning
Field is null
Use Case
Find unfilled TWAPs: {"twapId": ["null"]}
Existence Filter Examples
// Find all trades that are liquidations
{"filters": {"liquidation": ["*"]}}

// Find all trades with a builder
{"filters": {"builder": ["*"]}}

// Find trades without TWAP ID
{"filters": {"twapId": ["null"]}}

Stream-Specific Fields

Trades Stream

Filter completed trades and fills by user, trading pair, side, price, and execution details.

Format: Each event is a tuple [user_address, fill_data]

Field
user
Type
string
Description
Wallet address (matches tuple first element)
Example Filter
{"user": ["0x123..."]}
Field
coin
Type
string
Description
Trading pair
Example Filter
{"coin": ["BTC", "ETH"]}
Field
side
Type
string
Description
"A" (ask/sell) or "B" (bid/buy)
Example Filter
{"side": ["B"]}
Field
px
Type
string
Description
Execution price
Example Filter
{"px": ["50000"]}
Field
sz
Type
string
Description
Size executed
Example Filter
Field
dir
Type
string
Description
Direction
Example Filter
{"dir": ["Open Long", "Close Short"]}
Field
crossed
Type
boolean
Description
Crossed the spread
Example Filter
{"crossed": ["true"]}
Field
fee
Type
string
Description
Fee amount
Example Filter
Field
feeToken
Type
string
Description
Fee token
Example Filter
{"feeToken": ["USDC"]}
Field
hash
Type
string
Description
Transaction hash
Example Filter
{"hash": ["0xabc..."]}
Field
oid
Type
number
Description
Order ID
Example Filter
{"oid": ["12345"]}
Field
tid
Type
number
Description
Trade ID
Example Filter
Field
cloid
Type
string
Description
Client order ID (optional)
Example Filter
{"cloid": ["0x..."]}
Field
twapId
Type
number/null
Description
TWAP ID if from TWAP
Example Filter
{"twapId": ["*"]}
Field
builder
Type
string
Description
Builder address (optional)
Example Filter
{"builder": ["0x999..."]}
Field
builderFee
Type
string
Description
Builder fee (optional)
Example Filter
Field
liquidation
Type
object
Description
Liquidation data (optional)
Example Filter
{"liquidation": ["*"]}
Field
liquidation.liquidatedUser
Type
string
Description
Liquidated user address
Example Filter
{"liquidatedUser": ["0x..."]}
Field
liquidation.method
Type
string
Description
Liquidation method
Example Filter
{"method": ["market"]}
Field
liquidation.markPx
Type
string
Description
Mark price at liquidation
Example Filter
Trades Filter Examples
// Get all BTC buys
{"streams": ["trades"], "filters": {"coin": ["BTC"], "side": ["B"]}}

// Get liquidations only
{"streams": ["trades"], "filters": {"liquidation": ["*"]}}

// Get trades for specific user
{"streams": ["trades"], "filters": {"user": ["0x727956612a8700627451204a3ae26268bd1a1525"]}}

// Get TWAP executions only
{"streams": ["trades"], "filters": {"twapId": ["*"]}}

Orders Stream

Monitor order status updates including placements, cancellations, and partial fills.

Field
coin
Type
string
Description
Trading pair
Example Filter
{"coin": ["ETH"]}
Field
side
Type
string
Description
"A" or "B"
Example Filter
{"side": ["A"]}
Field
limit_px
Type
string
Description
Limit price
Example Filter
Field
sz
Type
string
Description
Current size
Example Filter
Field
orig_sz
Type
string
Description
Original size
Example Filter
Field
oid
Type
number
Description
Order ID
Example Filter
{"oid": ["12345"]}
Field
timestamp
Type
number
Description
Order timestamp
Example Filter
Orders Filter Examples
// Get all ETH orders
{"streams": ["orders"], "filters": {"coin": ["ETH"]}}

// Get sell orders only
{"streams": ["orders"], "filters": {"side": ["A"]}}

Book Updates Stream

Track order book changes including price level updates and size modifications for bid and ask sides.

Field
coin
Type
string
Description
Trading pair
Example Filter
{"coin": ["BTC"]}
Field
side
Type
string
Description
"A" (ask) or "B" (bid)
Example Filter
{"side": ["B"]}
Field
px
Type
string
Description
Price level
Example Filter
Field
sz
Type
string
Description
Size at level
Example Filter
Book Updates Filter Examples
// Get BTC bid updates only
{"streams": ["book_updates"], "filters": {"coin": ["BTC"], "side": ["B"]}}

// Get updates for multiple coins
{"streams": ["book_updates"], "filters": {"coin": ["BTC", "ETH", "SOL"]}}

Events Stream

Filter ledger updates including deposits, withdrawals, transfers, vault operations, and funding events.

Note: Events have nested structure with various types.

Field
users
Type
array
Description
Affected users
Example Filter
{"users": ["0x..."]}
Field
type
Type
string
Description
Event type
Example Filter
{"type": ["deposit", "withdraw"]}
Field
usdc
Type
string
Description
USDC amount
Example Filter
Field
token
Type
number
Description
Token ID
Example Filter
{"token": ["124"]}

Common Event Types:

  • deposit - USDC deposit
  • withdraw - USDC withdrawal
  • internalTransfer - Internal transfer
  • spotTransfer - Spot transfer
  • liquidation - Liquidation event
  • funding - Funding payment
  • vaultDeposit / vaultWithdraw - Vault operations
Events Filter Examples
// Get deposits only
{"streams": ["events"], "filters": {"type": ["deposit"]}}

// Get all events for a user
{"streams": ["events"], "filters": {"users": ["0xabc..."]}}

// Get vault operations
{"streams": ["events"], "filters": {"type": ["vaultDeposit", "vaultWithdraw"]}}

Writer Actions Stream

Monitor system actions including spot token transfers, perps operations, and core system activities.

Field
user
Type
string
Description
User address
Example Filter
{"user": ["0x200..."]}
Field
nonce
Type
number
Description
Action nonce
Example Filter
Field
evm_tx_hash
Type
string
Description
EVM transaction hash
Example Filter
{"evm_tx_hash": ["0x..."]}
Field
action.type
Type
string
Description
Action type
Example Filter
{"type": ["SystemSpotSendAction"]}
Field
action.destination
Type
string
Description
Destination address
Example Filter
{"destination": ["0x..."]}
Field
action.token
Type
number
Description
Token ID
Example Filter
{"token": ["124"]}
Field
action.wei
Type
number
Description
Amount in wei
Example Filter

Common Action Types:

  • SystemSpotSendAction - Spot token transfer
  • SystemPerpsAction - Perps system action
  • CoreWriterAction - Core writer action
Writer Actions Filter Examples
// Get spot sends only
{"streams": ["writer_actions"], "filters": {"type": ["SystemSpotSendAction"]}}

// Get actions for specific token
{"streams": ["writer_actions"], "filters": {"token": ["124"]}}

// Get actions for specific user
{"streams": ["writer_actions"], "filters": {"user": ["0x200..."]}}

TWAP Orders Stream

Track Time-Weighted Average Price order status updates including running, completed, and cancelled TWAP orders.

Field
user
Type
string
Description
User address
Example Filter
{"user": ["0x..."]}
Field
coin
Type
string
Description
Trading pair
Example Filter
{"coin": ["BTC"]}
Field
side
Type
string
Description
"A" or "B"
Example Filter
{"side": ["B"]}
Field
status
Type
string
Description
TWAP status
Example Filter
{"status": ["running", "completed"]}

Filter Limits

To ensure optimal performance and prevent abuse, Hyperliquid enforces limits on the number of filter values per field and total filter complexity:

Limit
Max values per user/address field
Default
100
Description
Max addresses in one filter
Limit
Max values per coin field
Default
50
Description
Max coins in one filter
Limit
Max values per type field
Default
20
Description
Max types in one filter
Limit
Max total values
Default
500
Description
Sum of all filter values
Limit
Unknown fields
Default
Allowed
Description
Any field can be filtered (uses highest limit)
Limit Error Response
{
"error": {
"code": -32602,
"message": "Filter validation failed: Too many values for field 'user': 150 (max: 100)"
}
}

Complete Examples

WebSocket Examples

Basic Subscription
// Subscribe to multiple streams
{"jsonrpc":"2.0","method":"hl_subscribe","params":{"streams":["trades","events"]},"id":1}

// Response
{"jsonrpc":"2.0","result":{"subscribed":["trades","events"]},"id":1}
Filtered Subscriptions
// Filter trades by coin and side
{
"jsonrpc": "2.0",
"method": "hl_subscribe",
"params": {
"streams": ["trades"],
"filters": {
"coin": ["BTC", "ETH"],
"side": ["B"]
}
},
"id": 1
}

// Get all liquidations
{
"jsonrpc": "2.0",
"method": "hl_subscribe",
"params": {
"streams": ["trades"],
"filters": {
"liquidation": ["*"]
}
},
"id": 1
}

// Get deposits for specific user
{
"jsonrpc": "2.0",
"method": "hl_subscribe",
"params": {
"streams": ["events"],
"filters": {
"type": ["deposit"],
"users": ["0xabc..."]
}
},
"id": 1
}

// Get SystemSpotSendAction events
{
"jsonrpc": "2.0",
"method": "hl_subscribe",
"params": {
"streams": ["writer_actions"],
"filters": {
"type": ["SystemSpotSendAction"]
}
},
"id": 1
}
Unsubscribe
// Unsubscribe from streams
{"jsonrpc":"2.0","method":"hl_unsubscribe","params":{"streams":["trades"]},"id":2}

wscat One-Liners

Quick Testing Commands
# All trades (no filter)
wscat -c wss://endpoint/ws -w 9999
{"jsonrpc":"2.0","method":"hl_subscribe","params":{"streams":["trades"]},"id":1}

# BTC trades only
wscat -c wss://endpoint/ws -w 9999
{"jsonrpc":"2.0","method":"hl_subscribe","params":{"streams":["trades"],"filters":{"coin":["BTC"]}},"id":1}

# Liquidations only
wscat -c wss://endpoint/ws -w 9999
{"jsonrpc":"2.0","method":"hl_subscribe","params":{"streams":["trades"],"filters":{"liquidation":["*"]}},"id":1}

# Specific user's trades
wscat -c wss://endpoint/ws -w 9999
{"jsonrpc":"2.0","method":"hl_subscribe","params":{"streams":["trades"],"filters":{"user":["0x123..."]}},"id":1}

gRPC Examples

gRPC Filter Examples
// JavaScript gRPC example
const request = {
subscribe: {
stream_type: 'TRADES',
start_block: 0,
filters: {
"coin": { values: ["BTC", "ETH"] },
"side": { values: ["B"] }
}
}
};

// Python gRPC example
request = {
"subscribe": {
"stream_type": "TRADES",
"filters": {
"liquidation": {"values": ["*"]},
"coin": {"values": ["BTC"]}
}
}
}

// Go gRPC example
request := &pb.SubscribeRequest{
Subscribe: &pb.Subscribe{
StreamType: pb.StreamType_TRADES,
Filters: map[string]*pb.FilterValues{
"coin": {Values: []string{"BTC", "ETH"}},
"user": {Values: []string{"0x123..."}},
},
},
}

Response Format

Subscription Confirmation

{"jsonrpc":"2.0","result":{"subscribed":["trades"]},"id":1}

Stream Data

{
"stream": "trades",
"block_number": 817824278,
"data": {
"block_number": 817824278,
"block_time": "2025-12-04T17:00:15.929034389",
"local_time": "2025-12-04T17:00:16.076556955",
"events": [
["0x727956612a8700627451204a3ae26268bd1a1525", {"coin": "HYPE", "side": "B", ...}]
]
}
}

Important Notes


  • Case Sensitivity: Field names and values are case-insensitive ("Coin" = "coin" = "COIN", "btc" = "BTC")
  • Address Matching: Addresses are case-insensitive ("0xABC" = "0xabc")
  • Empty Filters: No filters = receive all events (no filtering applied)
  • Whitespace: Values are automatically trimmed of whitespace
  • Per-Stream Filters: Each stream can have independent filters
  • Recursive Matching: Filters search through nested JSON structures automatically
  • Tuple Format: TRADES stream uses [user, data] format; user filter matches the first element
  • Blocks Stream: The blocks stream does NOT support filtering (gRPC only, raw data)

Share this doc