# GetOrderStatuses - Get Order Status Data

Retrieve order status events at a specific position from the Hyperliquid L1 Gateway.

Clone our [gRPC Code Examples Repository](https://github.com/dwellir-public/gRPC-code-examples) for complete, runnable implementations in Go, Python, and Node.js.

## When to Use This Method

`GetOrderStatuses` is essential for:

- **Order Reconciliation** - Verify order lifecycle events at a specific block
- **Rejection Analysis** - Retrieve and classify rejections at a point in time
- **Auditing** - Confirm status transitions at specific blocks
- **Debugging** - Investigate specific order outcomes during development

Method signature

```protobuf
rpc GetOrderStatuses(GetRequest) returns (Record) {}
```

V3 accepts an inclusive `position.block_number` or Unix-millisecond `position.timestamp`; explicit zero is invalid. A positioned call returns the selected envelope. An empty `GetRequest` waits for the next status record written after the call begins, so set a deadline.

```protobuf
filter: {
  fields: {
    field: "coins"
    op: FILTER_OP_IN
    values: "BTC"
  }
}
```

Order statuses accept `users`, `coins` and `dexes` filters. User matching is case-insensitive, coin matching is case-sensitive and dex matching is exact on the HIP-3 dex prefix; values within a field use OR semantics and separate fields use AND semantics. A zero-match unary request returns the selected `Record` with `data` containing `events: []`. A pruned position returns `NOT_FOUND`; malformed filters return `INVALID_ARGUMENT`.

## V3 reference

### Request Parameters

- `position.timestamp` (`int64, optional`): Inclusive V3 Unix-millisecond cursor. Omit the position to wait for the next written record.
- `position.block_number` (`int64, optional`): Inclusive V3 sequential block cursor. Explicit zero is invalid.
- `filter.fields` (`FieldFilter[], optional`): V3 users/coins constraints. Fields AND together; values within one field OR together.
- `filter.fields.field` (`string, required`): Feed-advertised filter field name, either users or coins.
- `filter.fields.op` (`FilterOp, optional`): FILTER_OP_UNSPECIFIED or FILTER_OP_IN.
- `filter.fields.values` (`string[], required`): One or more accepted values; entries within the list use OR semantics.

### Request Example

```bash
grpcurl \
  -import-path content/docs/hyperliquid/grpc \
  -proto v3.proto \
  -H "x-api-key: ${DWELLIR_API_KEY}" \
  -d '{"position":{"block_number":"1058646974"},"filter":{"fields":[{"field":"coins","op":"FILTER_OP_IN","values":["BTC"]}]}}' \
  "${HYPERLIQUID_GRPC_ENDPOINT}" \
  hyperliquid_l1_gateway.v3.HyperliquidL1Gateway/GetOrderStatuses
```

### Response Fields

- `block_number` (`optional int64, optional`): Sequential Hyperliquid block cursor; never the HyperBFT consensus round.
- `timestamp` (`optional int64, optional`): Record time in Unix milliseconds.
- `data` (`bytes, required`): Bytes from the node_order_statuses_by_block, with non-matching events removed when a filter is applied.

### Successful Response

```protobuf
block_number: 1058646974
timestamp: 1785736814057
data: "{\"block_number\":1058646974,\"events\":[]}"
```

### Error Responses

#### Invalid argument

- Code: `INVALID_ARGUMENT`
- Description: A cursor is zero or malformed, or a filter has an unsupported field, duplicate field, empty name, or empty value list.

#### Not found

- Code: `NOT_FOUND`
- Description: Available replay history varies by feed and endpoint. A cursor outside retained history returns NOT_FOUND.

#### Filter operator not implemented

- Code: `UNIMPLEMENTED`
- Description: The requested filter operator is well formed but is not implemented by this gateway version.

#### Position ahead of head

- Code: `OUT_OF_RANGE`
- Description: The requested block is above the feed's current head and may become available later.

#### Unauthenticated

- Code: `UNAUTHENTICATED`
- Description: The request did not include usable authentication metadata.

#### Permission denied

- Code: `PERMISSION_DENIED`
- Description: The supplied credential is not permitted to call this service.

## V2 reference

### Request Parameters

- `timestamp_ms` (`int64, optional`): Inclusive Unix-millisecond cursor. Omit it to target the latest data.
- `block_height` (`int64, optional`): Inclusive block-height cursor. Omit it to target the latest data.

### Request Example

```bash
grpcurl \
  -import-path content/docs/hyperliquid/grpc \
  -proto v2.proto \
  -H "x-api-key: ${DWELLIR_API_KEY}" \
  -d '{"block_height":"1058646974"}' \
  "${HYPERLIQUID_GRPC_ENDPOINT}" \
  hyperliquid_l1_gateway.v2.HyperliquidL1Gateway/GetOrderStatuses
```

### Response Fields

- `data` (`bytes, required`): JSON-encoded payload returned in the V2 BlockOrderStatuses wrapper.

### Successful Response

```protobuf
message BlockOrderStatuses {
  bytes data = 1;
}
```

```protobuf
rpc GetOrderStatuses(Position) returns (BlockOrderStatuses) {}
```

V2 accepts `block_height` or Unix-millisecond `timestamp_ms` and returns the source JSON in `BlockOrderStatuses.data`.

## Common Use Cases

For V3, select each record with `GetRequest.position.block_number`, decode `Record.data`, and inspect the `events` array. This supports single-block inspection and bounded searches for rejection statuses.

### 1. Inspect a Single Block

```python
def get_block_statuses(client, metadata, block_height):
    request = hyperliquid_pb2.Position(block_height=block_height)
    response = client.GetOrderStatuses(request, metadata=metadata)
    block = json.loads(response.data)

    for event in block.get('events', []):
        print(event['status'], event['order']['coin'], event['order']['oid'])
```

### 2. Find Rejections in a Block Range

```python
REJECTIONS = {
    'badAloPxRejected', 'insufficientSpotBalanceRejected', 'iocCancelRejected',
    'minTradeNtlRejected', 'perpMarginRejected', 'reduceOnlyRejected',
}

def find_rejections(client, metadata, start_block, end_block):
    rejected = []
    for block_height in range(start_block, end_block + 1):
        request = hyperliquid_pb2.Position(block_height=block_height)
        response = client.GetOrderStatuses(request, metadata=metadata)
        block = json.loads(response.data)
        for event in block.get('events', []):
            if event['status'] in REJECTIONS:
                rejected.append(event)
    return rejected
```

`GetOrderStatuses` returns the same format as `StreamOrderStatuses`. See the [StreamOrderStatuses documentation](https://www.dwellir.com/docs/hyperliquid/stream_order_statuses) for the complete field reference, including [status values](https://www.dwellir.com/docs/hyperliquid/stream_order_statuses#status-values) and the [order object](https://www.dwellir.com/docs/hyperliquid/stream_order_statuses#order-object).

## Best Practices

1. **Position Selection**: Use the exact sequential block cursor for precise queries; timestamp lookups may resolve to different blocks across requests
2. **Stable Keys**: Index per-order state on `(coin, oid)`, never on `oid` alone
3. **Defensive Parsing**: Handle nullable `hash` and `builder` and the non-exhaustive `status` set
4. **Error Recovery**: Implement retry logic with exponential backoff
5. **Resource Management**: Close gRPC connections properly to avoid resource leaks

## Current Limitations

- **Replay History**: Available replay history varies by feed and endpoint. A cursor outside retained history returns `NOT_FOUND`
- **Rate Limits**: Be mindful of request frequency to avoid overwhelming the service

## Resources

- **[GitHub: gRPC Code Examples](https://github.com/dwellir-public/gRPC-code-examples)** - Complete working examples
- **[StreamOrderStatuses Documentation](https://www.dwellir.com/docs/hyperliquid/stream_order_statuses)** - Full order status specification and streaming examples
- **[Historical Data](https://www.dwellir.com/docs/hyperliquid/historical-data)** - Historical `node_order_statuses_by_block` downloads

*Need help? Contact our [support team](mailto:support@dwellir.com) or check the [Hyperliquid gRPC documentation](https://www.dwellir.com/docs/hyperliquid/grpc).*
