eth_getLogs — Ethereum JSON-RPC

Status: Available

Returns the array of event logs matching a filter — by block range or block hash, contract address, and indexed topics.

POSThttps://triport.io/eth
Network
Ethereum
Scope
eth_read_rpc
Auth
x-token: $TRIPORT_API_KEY (or Authorization: Bearer)
Rate limit
free+ — 10 / 20 / 100 / 250 RPS sustained · short burst 20 / 40 / 200 / 500 (free / basic / pro / business); Burst capacity

Endpoint and plans: Ethereum RPC endpoint.

eth_getLogs returns all event logs emitted on-chain that match a single filter object. It is the workhorse for indexing contract activity: ERC-20 Transfers, swaps, mints, governance events — anything emitted with LOG0–LOG4.

You select logs in one of two mutually exclusive ways:

  • By block range — set fromBlock and toBlock (tags or hex block numbers). The range is inclusive on both ends.
  • By a single block — set blockHash to pin the query to exactly one block. blockHash cannot be combined with fromBlock/toBlock.

Within that window you narrow further by address (one or many contracts) and by topics (the indexed event signature and arguments). The result is a flat, chronologically ordered array of log objects; an empty array means nothing matched (this is not an error).

This is a read method available from the Free trial. For very large historic sweeps, page through the chain in bounded block windows rather than requesting the full history in one call (see Notes).

Parameters

JSON-RPC params is a positional array with a single element: [filter].

filterobjectrequired
The filter selecting which logs to return (see below).
fromBlockstringoptional
Start of the block range (inclusive). Hex block number ("0x10d4f00") or a tag: latest, earliest, pending, safe, finalized. Defaults to latest.
toBlockstringoptional
End of the block range (inclusive). Same format as fromBlock. Defaults to latest.
addressstring | string[]optional
A contract address, or an array of addresses, to restrict logs to. When omitted, logs from any contract match.
topics(string | string[] | null)[]optional
Ordered topic filters (up to 4). See AND/OR semantics below.
blockHashstringoptional
Restrict the query to the single block with this 32-byte hash. Mutually exclusive with fromBlock/toBlock.
Topic AND/OR semanticsobject

Response

Response fields

result is an array of log objects. Each object has:

FieldTypeDescription
addressstringContract that emitted the log.
topicsstring[]Indexed topics; topics[0] is the event signature hash, the rest are indexed arguments.
datastringABI-encoded non-indexed event arguments (0x-prefixed hex). 0x if there are none.
blockNumberstringBlock number the log was included in (0x-prefixed hex).
blockHashstringHash of the block containing the log.
transactionHashstringHash of the transaction that produced the log.
transactionIndexstringIndex of that transaction within the block (hex).
logIndexstringIndex of this log within the block (hex).
removedbooleantrue if the log was removed by a chain reorganization; false for a canonical log.

Errors

Errors are returned in the standard JSON-RPC error envelope. See the shared errors reference for the full envelope shape and shared codes.

CodeMeaningWhen it happens
401trial_expiredThe API key's trial period has ended; upgrade to a paid tier to continue.
429rate_limitedMore than your tier's RPS for eth_read_rpc (10 / 20 / 100 / 250). The body carries limit_rps, retry_after_sec and upgrade_url at the top level.
401unauthorizedMissing or invalid API key.
-32602Invalid paramsThe filter is malformed — e.g. blockHash combined with fromBlock/toBlock, or a badly formatted address/topic.

Examples

JavaScript (fetch)

const res = await fetch("https://triport.io/eth", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "eth_getLogs",
    params: [{
      fromBlock: "0x10d4f00",
      toBlock: "0x10d4f10",
      address: "0xdAC17F958D2ee523a2206206994597C13D831ec7",
      topics: [
        "0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
      ],
    }],
  }),
});


const { result } = await res.json();
console.log(`Matched ${result.length} logs`);
for (const log of result) {
  console.log(`${log.blockNumber} ${log.transactionHash} logIndex=${log.logIndex}`);
}

Notes

  • Block range vs. block hash: supply either fromBlock/toBlock or blockHash, never both. blockHash is the precise way to read all logs from one specific block regardless of reorgs.
  • Bound your ranges: very wide block windows (or unfiltered address + topics) can return large result sets and are slow. For historic indexing, walk the chain in fixed-size windows (e.g. a few thousand blocks per call) and accumulate results. There is no daily quota — pacing is RPS-per-tier with burst.
  • Reorgs: logs from recent, non-finalized blocks may later be reorged out; such logs reappear in a subsequent query with removed: true. Query against the finalized tag when you need stability.
  • Empty result: a filter that matches nothing returns "result": [], which is a success, not an error.
  • Related methods: use eth_getBlockReceipts to pull every receipt (and its logs) for a block, eth_getTransactionReceipt for the logs of a single transaction, and eth_blockNumber to discover the current head before paging.
  • Empty result? An empty result array is not an error — see why eth_getLogs returns an empty array for the default block range, topic hashing and proxy-address mismatches.