Hyperliquid gRPC API Reference
Hyperliquid L1 Gateway provides a gRPC-based API for accessing blockchain and trading data. The API is defined using Protocol Buffers (proto3).
Complete working examples in Go, Python, and Node.js are available in our gRPC Code Examples Repository. Clone the repo to get started quickly.
Service Definition#
syntax = "proto3";
package hyperliquid_l1_gateway.v2;
option go_package = "internal/api/v2";
service HyperliquidL1Gateway {
// Start a blocks stream from the given Position
rpc StreamBlocks(Position) returns (stream Block) {}
// Start a fills stream from the given Position
rpc StreamFills(Position) returns (stream BlockFills) {}
// Start an order book snapshots stream from the given Position
rpc StreamOrderbookSnapshots(Position)
returns (stream OrderBookSnapshot) {}
// Return an order book snapshot at the requested Timestamp
rpc GetOrderBookSnapshot(Timestamp) returns (OrderBookSnapshot) {}
}
message Position {
// Leave all fields unset or zero to target the latest data.
oneof position {
int64 timestamp_ms = 1; // ms since Unix epoch, inclusive
int64 block_height = 2; // block height, inclusive
}
}
message Timestamp {
int64 timestamp_ms = 1;
}
message Block {
// JSON-encoded Hyperliquid block from "replica_cmds".
bytes data = 1;
}
message OrderBookSnapshot {
// JSON-encoded Hyperliquid order book snapshot.
bytes data = 1;
}
message BlockFills {
// JSON-encoded object from "node_fills" or "node_fills_by_block".
bytes data = 1;
}
Message Types#
- Position
- Timestamp
- Block
- OrderBookSnapshot
- BlockFills
message Position {
// Leave all fields unset or zero to target the latest data.
oneof position {
int64 timestamp_ms = 1; // ms since Unix epoch, inclusive
int64 block_height = 2; // block height, inclusive
}
}
The Position message allows flexible positioning for streams. You can specify either:
- timestamp_ms: Milliseconds since Unix epoch to start from that time
- block_height: Specific block number to start from
Leave all fields unset or zero to target the latest data.
message Timestamp {
int64 timestamp_ms = 1;
}
Used specifically for GetOrderBookSnapshot to request a snapshot at a specific time.
message Block {
// JSON-encoded Hyperliquid block from "replica_cmds".
bytes data = 1;
}
The data field contains a JSON-encoded object with block information.
message OrderBookSnapshot {
// JSON-encoded Hyperliquid order book snapshot.
bytes data = 1;
}
The data field contains a complete order book snapshot in JSON format.
message BlockFills {
// JSON-encoded object from "node_fills" or "node_fills_by_block".
bytes data = 1;
}
The data field contains fill data for executed orders.
Available Methods#
Streaming Methods#
1. StreamBlocks#
Stream continuous block data starting from a position.
Request: Position
Response: stream Block
Use Case: Monitor blockchain state changes in real-time
2. StreamFills#
Stream fill data for executed orders.
Request: Position
Response: stream BlockFills
Use Case: Track order execution and settlement
3. StreamOrderbookSnapshots#
Stream continuous order book snapshots from a position.
Request: Position
Response: stream OrderBookSnapshot
Use Case: Monitor real-time order book changes and market depth
Unary Methods#
4. GetOrderBookSnapshot#
Retrieve a single order book snapshot at a specific point in time.
Request: Timestamp
Response: OrderBookSnapshot
Use Case: Get current market depth and liquidity
Implementation Examples#
- Go
- Python
- Node.js
package main
import (
"context"
"log"
"os"
pb "your-project/hyperliquid_l1_gateway/v2"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials"
"google.golang.org/grpc/metadata"
)
func main() {
endpoint := os.Getenv("HYPERLIQUID_ENDPOINT")
apiKey := os.Getenv("API_KEY")
// Set up TLS credentials
creds := credentials.NewTLS(nil)
// Connect with TLS
conn, err := grpc.NewClient(endpoint, grpc.WithTransportCredentials(creds))
if err != nil {
log.Fatalf("Failed to connect: %v", err)
}
defer conn.Close()
client := pb.NewHyperliquidL1GatewayClient(conn)
// Add API key to context
ctx := metadata.AppendToOutgoingContext(context.Background(), "x-api-key", apiKey)
// Stream blocks from latest (empty Position)
stream, err := client.StreamBlocks(ctx, &pb.Position{})
if err != nil {
log.Fatalf("Failed to stream: %v", err)
}
for {
block, err := stream.Recv()
if err != nil {
log.Fatalf("Stream error: %v", err)
}
// Process JSON data
log.Printf("Received block: %s", block.Data)
}
}
import grpc
import json
import os
from dotenv import load_dotenv
import hyperliquid_pb2
import hyperliquid_pb2_grpc
# Load environment variables
load_dotenv()
def stream_blocks():
endpoint = os.getenv('HYPERLIQUID_ENDPOINT')
api_key = os.getenv('API_KEY')
# Create SSL credentials
credentials = grpc.ssl_channel_credentials()
# Create secure channel with API key metadata
metadata = [('x-api-key', api_key)]
with grpc.secure_channel(endpoint, credentials) as channel:
client = hyperliquid_pb2_grpc.HyperliquidL1GatewayStub(channel)
# Start streaming from latest (empty Position)
request = hyperliquid_pb2.Position()
# Stream blocks
for block in client.StreamBlocks(request, metadata=metadata):
# Parse JSON data
data = json.loads(block.data)
print(f"Block update: {data}")
if __name__ == '__main__':
stream_blocks()
const grpc = require('@grpc/grpc-js');
const protoLoader = require('@grpc/proto-loader');
require('dotenv').config();
// Load proto file
const packageDefinition = protoLoader.loadSync(
'v2.proto',
{
keepCase: true,
longs: String,
enums: String,
defaults: true,
oneofs: true
}
);
const proto = grpc.loadPackageDefinition(packageDefinition);
// Load environment variables
const endpoint = process.env.HYPERLIQUID_ENDPOINT;
const apiKey = process.env.API_KEY;
// Create metadata with API key
const metadata = new grpc.Metadata();
metadata.add('x-api-key', apiKey);
// Create client with SSL credentials
const client = new proto.hyperliquid_l1_gateway.v2.HyperliquidL1Gateway(
endpoint,
grpc.credentials.createSsl()
);
// Stream blocks from latest (empty Position)
const stream = client.StreamBlocks({}, metadata);
stream.on('data', (block) => {
const data = JSON.parse(block.data.toString());
console.log('Block received:', data);
});
stream.on('error', (err) => {
console.error('Stream error:', err);
});
Network Information#
Protocol
gRPC
Binary ProtocolData Format
JSON
In Protocol BuffersData Retention
24 Hours
Rolling WindowStreaming
Real-time
From Current TimeImportant Notes#
⚠️ Current Limitations#
-
Position Parameter: The Position parameter supports both
timestamp_msandblock_heightfor flexible stream positioning. -
Data Retention: The node currently maintains only 24 hours of historical data.
-
Historical Queries: Historical data within the retention window can be queried using the Position message.
🛠️ Testing Tools#
A Go testing application is available for customers who want to test the streaming functionality. This is a 16MB binary that prints stream data to the terminal. Contact our support team to obtain this testing tool.
Best Practices#
1. Connection Management#
Maintain persistent gRPC connections for streaming:
// Implement reconnection logic with TLS
func connectWithRetry(addr string, maxRetries int) (*grpc.ClientConn, error) {
var conn *grpc.ClientConn
var err error
creds := credentials.NewTLS(nil)
for i := 0; i < maxRetries; i++ {
conn, err = grpc.NewClient(addr, grpc.WithTransportCredentials(creds))
if err == nil {
return conn, nil
}
time.Sleep(time.Second * time.Duration(i+1))
}
return nil, err
}
2. Error Handling#
Implement robust error handling for stream interruptions:
def stream_with_retry(stub, max_retries=5):
retries = 0
while retries < max_retries:
try:
position = Position() # Empty for latest
for data in stub.StreamBlocks(position):
yield data
except grpc.RpcError as e:
retries += 1
time.sleep(2 ** retries)
raise Exception("Max retries exceeded")
3. Data Processing#
Process JSON data efficiently:
// Use streaming JSON parser for large datasets
const JSONStream = require('jsonstream');
stream.on('data', (chunk) => {
const parser = JSONStream.parse('*');
parser.on('data', (data) => {
// Process individual JSON objects
processOrderBook(data);
});
parser.write(chunk.data);
});
Proto File Package Information#
syntax = "proto3";
package hyperliquid_l1_gateway.v2;
option go_package = "internal/api/v2";
When generating client code, use the appropriate package name for your language:
- Go:
internal/api/v2 - Python:
hyperliquid_l1_gateway.v2 - Node.js:
hyperliquid_l1_gateway.v2
Resources & Support#
Developer Resources#
- GitHub: gRPC Code Examples - Complete working examples in Go, Python, and Node.js
- Copy Trading Bot Example - Production-ready copy trading implementation
- Proto definition files available upon request
- Testing binary (16MB Go application) available for streaming verification
Need Help?#
- 📧 Email: support@dwellir.com
- 📚 Documentation: You're here!
- 🎯 Dashboard: dashboard.dwellir.com
- 💻 GitHub: dwellir-public/gRPC-code-examples
- 🔧 Testing Tool: Contact support for the Go testing binary
Start building on Hyperliquid with Dwellir's enterprise-grade gRPC infrastructure. Get your API key →