---
title: ListEventsRequest
description: ListEventsRequest lists events with CEL filtering and pagination.
source_url:
  html: https://thru.org/docs/api-ref/grpc/messages/thru/services/v1/list-events-request/
  md: https://thru.org/docs/api-ref/grpc/messages/thru/services/v1/list-events-request.md
---

# ListEventsRequest

ListEventsRequest lists events with CEL filtering and pagination.

Returns events ordered from most recent to older (slot DESC, block\_offset DESC, call\_idx DESC). Supports filtering on event metadata and payload using CEL expressions with specialized byte functions.

Available fields for filtering:

- event.event\_id (string): Unique event identifier (format: “ts{slot}*{block\_offset}*{call\_idx}”)
- event.transaction\_signature.value (bytes): Transaction signature that emitted the event
- event.slot (uint64): Block slot number where event was emitted
- event.call\_idx (uint32): Instruction call index within transaction
- event.block\_offset (uint32): Transaction’s position within the block
- event.timestamp (google.protobuf.Timestamp): Event emission timestamp
- event.program.value (bytes): Program public key that emitted the event
- event.program\_idx (uint32): Program index within transaction
- event.payload (bytes): Event payload data
- event.payload\_size (uint32): Size of event payload in bytes
- event.fee\_payer.value (bytes): Fee payer’s public key for the transaction

Available CEL functions:

- has(field): Check if optional field exists
- startsWith(string, prefix): Check if string starts with prefix (string fields only)
- first1Byte(bytes): Extract first byte as uint8
- first4Bytes(bytes): Extract first 4 bytes as uint32 (little-endian)
- first8Bytes(bytes): Extract first 8 bytes as uint64 (little-endian)
- bytesPrefix(bytes, prefix): Check if bytes start with prefix
- uint(value): Convert to uint type
- int(value): Convert to int type
- string(value): Convert to string type
- bytes(value): Convert to bytes type
- double(value): Convert to double type
- timestamp(value): Convert to timestamp type
- duration(value): Convert to duration type

Available filter parameters (accessible via params.\* in expressions):

- params.slot (uint64): Slot number for filtering
- params.u64 (uint64): Generic uint64 parameter for payload matching
- params.signature (Signature): Transaction signature for filtering
- params.signature.value (bytes): Transaction signature bytes for filtering
- params.address (Pubkey): Program address for filtering
- params.address.value (bytes): Program address bytes for filtering
- params.prefix (bytes): Byte prefix for payload filtering
- params.timestamp (Timestamp): Timestamp parameter for filtering

Filter examples:

1. Filter by slot: filter.expression = “event.slot > uint(1000)” filter.expression = “event.slot >= uint(100) && event.slot <= uint(200)”

2. Filter by slot using parameter: filter.expression = “event.slot >= params.slot” filter.params\[“slot”].int\_value = 1234

3. Filter by call index: filter.expression = “event.call\_idx == uint(0)” // First instruction filter.expression = “event.call\_idx > uint(0)” // Nested instructions

4. Filter by block offset: filter.expression = “event.block\_offset >= uint(0)” filter.expression = “event.block\_offset == uint(5)”

5. Filter by transaction signature (using parameter): filter.expression = “event.transaction\_signature.value == params.signature” filter.params\[“signature”].signature\_value.value = <64-byte signature>

6. Filter by program address (using parameter): filter.expression = “has(event.program) && event.program.value == params.address” filter.params\[“address”].pubkey\_value.value = <32-byte program pubkey>

7. Filter by event ID prefix using startsWith: filter.expression = “event.event\_id.startsWith(“ts”)” filter.expression = “event.event\_id.startsWith(“ts1000\_”)”

8. Check for payload existence: filter.expression = “has(event.payload)”

9. Check for program existence: filter.expression = “has(event.program)”

10. Filter by payload first byte (event type): filter.expression = “has(event.payload) && first1Byte(event.payload) == uint(1)” // MESSAGE events filter.expression = “has(event.payload) && first1Byte(event.payload) == uint(2)” // Other type

11. Filter by payload first 4 bytes (uint32 event type): filter.expression = “has(event.payload) && first4Bytes(event.payload) == uint(2)” // COUNTER events filter.expression = “has(event.payload) && first4Bytes(event.payload) == params.u64” filter.params\[“u64”].int\_value = 2

12. Filter by payload first 8 bytes (uint64 event type): filter.expression = “has(event.payload) && first8Bytes(event.payload) == uint(6)” // PATTERN events filter.expression = “has(event.payload) && first8Bytes(event.payload) == params.u64” filter.params\[“u64”].int\_value = 6

13. Filter by payload byte prefix: filter.expression = “bytesPrefix(event.payload, params.prefix)” filter.params\[“prefix”].bytes\_value = \<byte prefix to match>

14. Combine slot and call\_idx filters: filter.expression = “event.slot > uint(1000) && event.call\_idx == uint(0)”

15. Combine slot, call\_idx, and payload existence: filter.expression = “event.slot > uint(1000) && event.call\_idx == uint(0) && has(event.payload)”

16. Filter by program and payload type: filter.expression = “has(event.program) && event.program.value == params.address && first1Byte(event.payload) == uint(1)” filter.params\[“address”].pubkey\_value.value = <32-byte program pubkey>

17. Filter MESSAGE events (type 1) with specific program: filter.expression = “has(event.payload) && first1Byte(event.payload) == uint(1) && event.program.value == params.address” filter.params\[“address”].pubkey\_value.value = <32-byte program pubkey>

18. Filter COUNTER events (type 2) in slot range: filter.expression = “has(event.payload) && first4Bytes(event.payload) == uint(2) && event.slot >= uint(100) && event.slot <= uint(200)”

19. Filter PATTERN events (type 6) with payload prefix: filter.expression = “has(event.payload) && first8Bytes(event.payload) == uint(6) && bytesPrefix(event.payload, params.prefix)” filter.params\[“prefix”].bytes\_value = \<pattern prefix bytes>

20. Complex combined filter: filter.expression = “(event.slot > uint(1000) && event.call\_idx == uint(0)) || first1Byte(event.payload) == uint(1)”

21. Filter events from specific transaction: filter.expression = “event.transaction\_signature.value == params.signature && has(event.payload)” filter.params\[“signature”].signature\_value.value = <64-byte signature>

22. Filter by multiple payload type options: filter.expression = “has(event.payload) && (first1Byte(event.payload) == uint(1) || first1Byte(event.payload) == uint(2))”

23. Filter nested instruction events: filter.expression = “event.call\_idx > uint(0) && has(event.program)”

24. Filter first instruction events only: filter.expression = “event.call\_idx == uint(0)”

25. Filter events with payload longer than specific size (using bytesPrefix with empty prefix): filter.expression = “has(event.payload)”

26. Combine has() checks: filter.expression = “has(event.program) && has(event.payload) && has(event.timestamp)”

27. Use inequality operators: filter.expression = “event.slot < uint(10000)” filter.expression = “event.slot <= uint(10000)” filter.expression = “event.call\_idx >= uint(0)” filter.expression = “event.block\_offset != uint(0)”

28. Filter by timestamp (if available): filter.expression = “has(event.timestamp)”

29. Match specific event ID pattern: filter.expression = “event.event\_id.startsWith(“ts1234\_0\_”)”

30. Complex payload and metadata filter: filter.expression = “event.slot >= params.slot && has(event.payload) && first8Bytes(event.payload) == params.u64 && event.program.value == params.address” filter.params\[“slot”].int\_value = 1000 filter.params\[“u64”].int\_value = 6 filter.params\[“address”].pubkey\_value.value = <32-byte program pubkey>

Note: Filters on slot, call\_idx, block\_offset, transaction\_signature, and program are pushed down to SQL for optimal performance. Payload filters (first1Byte, first4Bytes, first8Bytes, bytesPrefix) are evaluated in-memory on fetched results.

**Package:** `thru.services.v1`

## Fields

| Field | Type | # | Description |
| - | - | - | - |
| `filter` | [`thru.common.v1.Filter`](https://thru.org/docs/api-ref/grpc/messages/thru/common/v1/filter.md) | 1 · optional | CEL filter expression (OPTIONAL). See message documentation for examples. |
| `page` | [`thru.common.v1.PageRequest`](https://thru.org/docs/api-ref/grpc/messages/thru/common/v1/page-request.md) | 2 · optional | |
| `version_context` | [`thru.common.v1.VersionContext`](https://thru.org/docs/api-ref/grpc/messages/thru/common/v1/version-context.md) | 3 · optional | |
| `min_consensus` | [`thru.common.v1.ConsensusStatus`](https://thru.org/docs/api-ref/grpc/messages/thru/common/v1/consensus-status.md) | 4 · optional | |
