The queryEvents method is available only on RPC nodes that enable it's new storage engine, which is currently in beta. Standard Stellar RPC nodes do not support this method. To use it, run RPC from the archive-node-beta tag or connect to a provider that offers one.
This method is in beta and may change before general availability.
queryEvents
Returns contract and system events that match the specified filters within a ledger range. Results are paginated; each response contains a page of events and, when the scan is not complete, a cursor for continuing the query.
Set order to asc to scan forward from minLedger, or to desc to scan backward from maxLedger. If omitted, maxLedger defaults to the latest ledger.
To start a query, specify the applicable ledger bounds, scan order, and optional filters. To retrieve the next page, send the cursor returned in the previous response without repeating minLedger, maxLedger, order, or filters. The cursor preserves those query parameters. limit and xdrFormat are not stored in the cursor and may be specified on each request.
Use scanStatus to determine whether to request another page, wait for additional ledgers, or stop. An empty events array does not necessarily mean the scan is complete.
Params
(7)Please note that parameter structure within the request must contain named parameters as a by-name object, and not as positional arguments in a by-position array
1. minLedger
The first ledger in the range (inclusive). Required for ascending scans (order: asc) and optional for descending scans. Specify this parameter only when starting a query, not when continuing with a cursor.
Sequence number of the ledger.
2. maxLedger
The last ledger in the range (inclusive). Optional. Without maxLedger, an ascending scan continues toward newly closed ledgers and reports WAITING_FOR_LEDGERS when it catches up to the chain. A descending scan starts at the latest ledger. Specify this parameter only when starting a query.
Sequence number of the ledger.
3. order
The direction of the scan. asc (default) scans forward from minLedger; desc scans backward from maxLedger. Specify this parameter only when starting a query.
4. filters
An array of 1 to 256 event filters. An event matches if it satisfies at least one filter; within a filter, all specified fields must match. Omit filters to match all events. Specify this parameter only when starting a query.
For example, to match either transfer or mint events from one contract, send two filters with the same contractId and a different topic0. The first example below does this.
Topic values are Base64-encoded XDR ScVals, not plain strings. Use the JSON to XDR page in the Lab to encode a value.
A query may use at most 15 distinct index terms by default; node operators can configure this limit. Each distinct contractId is one term, each distinct type is one term, and each distinct value at a given topic position is one term. The same value at the same position counts once no matter how many filters repeat it. The same value at two different positions counts twice. For example, [{ topic0: transfer, topic1: me }, { topic0: transfer, topic2: me }] uses 3 terms. A query over the budget returns invalid_params with termsUsed and termBudget in error.data.
The type of emitted event.
The emitting contract address in StrKey format (C...).
The Base64-encoded XDR ScVal that the first event topic must match.
The Base64-encoded XDR ScVal that the second event topic must match.
The Base64-encoded XDR ScVal that the third event topic must match.
The Base64-encoded XDR ScVal that the fourth event topic must match.
5. cursor
The cursor returned by the previous response, used to continue a query. It preserves the ledger bounds, scan order, and filters. Do not combine cursor with minLedger, maxLedger, order, or filters; doing so returns an error.
6. limit
The maximum number of events to return per page, from 1 to 1,000. Defaults to 100. This setting is not stored in the cursor; include it on each request to retain a nondefault value.
7. xdrFormat
Controls how XDR values are represented in the response: decoded JSON or Base64-encoded XDR. Do not depend on a fixed schema for the JSON representation, as it may change with the underlying XDR.
Specifies whether XDR should be encoded as Base64 (default or 'base64') or JSON ('json').
Result
(queryEventsResult)Events returned on this page, up to the configured limit. The array may be empty even when more pages remain; check scanStatus.
The type of emitted event.
The sequence number of the ledger in which the event was emitted.
The ledger close time, formatted as an ISO 8601 timestamp.
The address of the contract that emitted the event, in StrKey format.
A unique event identifier consisting of a 19-character TOID and a 10-character, zero-padded event index, separated by a hyphen.
The index of the event's transaction within the ledger.
The index of the operation that emitted the event within its transaction.
The event topics, each represented as a Base64-encoded XDR ScVal.
The event data, represented as a Base64-encoded XDR ScVal.
The hash of the transaction that triggered the event.
An opaque cursor for retrieving the next page. It preserves the original ledger bounds, scan order, and filters and does not expire. The cursor is absent only when scanStatus is COMPLETE.
Indicates the state of the scan and the next action.Show all...
A scan checkpoint indicating that all matching events from the scan's starting bound through this ledger have been delivered. If a page ends partway through a ledger, this field identifies the last fully scanned ledger; the cursor resumes within the partially scanned ledger. Before any ledger has been fully scanned, the value is minLedger - 1 for ascending scans or maxLedger + 1 for descending scans.
The sequence number of the oldest ledger available to the RPC node when it processed the request.
The sequence number of the latest ledger known to the RPC node when it processed the request.
Examples
Starts a query for the newest transfer or mint events from one contract, two per page. With order: desc and no ledger bounds, the scan starts at the latest ledger and walks back. The two filters share a contractId and differ in topic0, so an event matches either. Ledger numbers and hashes are illustrative.
Request
- cURL
- JavaScript
- Python
- JSON
curl -X POST \
-H 'Content-Type: application/json' \
-d '{
"jsonrpc": "2.0",
"id": 8675309,
"method": "queryEvents",
"params": {
"order": "desc",
"filters": [
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAAh0cmFuc2Zlcg=="
},
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAARtaW50"
}
],
"limit": 2
}
}' \
https://soroban-testnet.stellar.org | jq
let requestBody = {
"jsonrpc": "2.0",
"id": 8675309,
"method": "queryEvents",
"params": {
"order": "desc",
"filters": [
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAAh0cmFuc2Zlcg=="
},
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAARtaW50"
}
],
"limit": 2
}
}
let res = await fetch('https://soroban-testnet.stellar.org', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
},
body: JSON.stringify(requestBody),
})
let json = await res.json()
console.log(json)
import json, requests
res = requests.post(https://soroban-testnet.stellar.org, json={
"jsonrpc": "2.0",
"id": 8675309,
"method": "queryEvents",
"params": {
"order": "desc",
"filters": [
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAAh0cmFuc2Zlcg=="
},
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAARtaW50"
}
],
"limit": 2
}
})
print(json.dumps(res.json(), indent=4))
{
"jsonrpc": "2.0",
"id": 8675309,
"method": "queryEvents",
"params": {
"order": "desc",
"filters": [
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAAh0cmFuc2Zlcg=="
},
{
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"topic0": "AAAADwAAAARtaW50"
}
],
"limit": 2
}
}
Result
{
"jsonrpc": "2.0",
"id": 8675309,
"result": {
"events": [
{
"type": "contract",
"ledger": 1189981,
"ledgerClosedAt": "2024-04-25T17:52:46Z",
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"id": "0005110929477865472-0000000000",
"transactionIndex": 1,
"operationIndex": 0,
"txHash": "5bd25a1a8fd1fe8ec99ab1fdd57af9a6f0e4c7c8a3c1b7d2e9f0a1b2c3d4e5f6",
"topic": [
"AAAADwAAAAh0cmFuc2Zlcg==",
"AAAAEgAAAAAAAAAAeo0X4ISuIjuArAyYXR0z8qyj0x0MHpv92CTtN4PONek=",
"AAAAEgAAAAAAAAAAfn3koV5C+Z6q8U1LfPwlofeZ3jnWI6Iudfg5NOEmOtg="
],
"value": "AAAACgAAAAAAAAAAAAAAAAX14QA="
},
{
"type": "contract",
"ledger": 1189977,
"ledgerClosedAt": "2024-04-25T17:52:26Z",
"contractId": "CDLZFC3SYJYDZT7K67VZ75HPJVIEUVNIXF47ZG2FB2RMQQVU2HHGCYSC",
"id": "0005110912298004480-0000000000",
"transactionIndex": 3,
"operationIndex": 0,
"txHash": "e1f2a3b4c5d6e7f8091a2b3c4d5e6f708192a3b4c5d6e7f8091a2b3c4d5e6f70",
"topic": [
"AAAADwAAAAh0cmFuc2Zlcg==",
"AAAAEgAAAAAAAAAAfn3koV5C+Z6q8U1LfPwlofeZ3jnWI6Iudfg5NOEmOtg=",
"AAAAEgAAAAAAAAAAeo0X4ISuIjuArAyYXR0z8qyj0x0MHpv92CTtN4PONek="
],
"value": "AAAACgAAAAAAAAAAAAAAAACYloA="
}
],
"cursor": "gec1_AQEAAAASJnIAAAASJm0AAAAB...",
"scanStatus": "HAS_MORE",
"scannedLedger": 1189978,
"oldestLedger": 2,
"latestLedger": 1190004
}
}
Errors
Invalid requests return JSON-RPC error code -32602. Because the human-readable error message may vary, use error.data.reason to identify the cause. Additional fields in error.data depend on the reason.
error.data.reason | Other fields in error.data | Cause |
|---|---|---|
invalid_params | termsUsed and termBudget when the filter term budget is exceeded | An unknown field, invalid value, combination of initial-query and cursor parameters, or too many filter terms. |
ledger_out_of_range | missingLedger, oldestLedger, latestLedger | A requested range boundary or cursor position is outside the ledgers available on this node. If below oldestLedger, restart from the oldest available ledger or use a node with deeper history. If above latestLedger, retry when that ledger becomes available. |
cursor_malformed | oldestLedger, latestLedger | The cursor is invalid or cannot be parsed. Start a new query. |
Other failures return a JSON-RPC internal error without additional error data.