Docs

GetFills - Get Fill Data

Retrieve fills at a specific position from Hyperliquid L1 Gateway via gRPC. Get order execution data for analysis and reconciliation.

Retrieve fills at a specific position from the Hyperliquid L1 Gateway.

Full Code Examples

Clone our gRPC Code Examples Repository for complete, runnable implementations in Go, Python, and Node.js.

When to Use This Method

GetFills is essential for:

  • Trade Reconciliation - Verify fills at a specific point in time
  • Historical Analysis - Retrieve fill data for backtesting or reporting
  • Auditing - Verify trade executions at specific blocks
  • Debugging - Investigate specific fills during development

Method Signature

protobuf
rpc GetFills(Position) returns (BlockFills) {}

Request Parameters

Request
timestamp_msint64

One of `position`. ms since Unix epoch, inclusive

block_heightint64

One of `position`. block height, inclusive

Response Body

Response
local_timestring

ISO-8601 timestamp when node processed the fill

block_timestring

ISO-8601 timestamp from block consensus

block_numbernumber

Block height containing these fills

eventsarray

Array of [address, fill_data] pairs

Common Use Cases

1. PnL Reconciliation

Python
def reconcile_pnl(client, metadata, start_block, end_block):
    """Calculate total PnL between two blocks"""
    pnl_by_address = {}

    for block_height in range(start_block, end_block + 1):
        request = hyperliquid_pb2.Position(block_height=block_height)
        response = client.GetFills(request, metadata=metadata)
        fills = json.loads(response.data)

        for event in fills.get('events', []):
            if len(event) >= 2:
                address = event[0]
                fill = event[1]
                pnl = float(fill.get('closedPnl', 0))

                if address not in pnl_by_address:
                    pnl_by_address[address] = 0
                pnl_by_address[address] += pnl

    return pnl_by_address

2. Fill Verification

Go
func verifyFill(client pb.HyperliquidL1GatewayClient, ctx context.Context, blockHeight int64, traderId string) []map[string]interface{} {
    request := &pb.Position{Position: &pb.Position_BlockHeight{BlockHeight: blockHeight}}
    response, _ := client.GetFills(ctx, request)

    var fills map[string]interface{}
    json.Unmarshal(response.Data, &fills)

    var traderFills []map[string]interface{}
    events := fills["events"].([]interface{})

    for _, event := range events {
        eventArr := event.([]interface{})
        if len(eventArr) >= 2 {
            address := eventArr[0].(string)
            if address == traderId {
                fillData := eventArr[1].(map[string]interface{})
                traderFills = append(traderFills, fillData)
            }
        }
    }

    return traderFills
}

3. Volume Analysis

JavaScript
function analyzeVolume(fills) {
    const volumeByCoin = {};
    const events = fills.events || [];

    for (const event of events) {
        if (event.length >= 2) {
            const fill = event[1];
            const coin = fill.coin;
            const volume = parseFloat(fill.sz) * parseFloat(fill.px);

            if (!volumeByCoin[coin]) {
                volumeByCoin[coin] = {
                    totalVolume: 0,
                    buyVolume: 0,
                    sellVolume: 0,
                    fillCount: 0
                };
            }

            volumeByCoin[coin].totalVolume += volume;
            volumeByCoin[coin].fillCount++;

            if (fill.side === 'B') {
                volumeByCoin[coin].buyVolume += volume;
            } else {
                volumeByCoin[coin].sellVolume += volume;
            }
        }
    }

    return volumeByCoin;
}

Best Practices

  1. Position Selection: Use block height for precise queries; timestamps may return different fills across requests
  2. Data Validation: Always validate JSON structure and handle optional fields
  3. Deduplication: Use tid (trade ID) as the unique identifier for deduplication
  4. Error Recovery: Implement retry logic with exponential backoff
  5. Resource Management: Close gRPC connections properly to avoid resource leaks

Current Limitations

  • Data Retention: Historical fill data is limited to a 24-hour rolling window
  • Rate Limits: Be mindful of request frequency to avoid overwhelming the service

Resources

Need help? Contact our support team or check the Hyperliquid gRPC documentation.