eth_getFilterLogs - Linea RPC Method
Returns all logs matching a previously created filter on Linea. Essential for initial log retrieval, backfilling event data, and one-time historical queries for enterprise DeFi (Aave, Renzo), institutional cross-border payments via SWIFT pilots, and zkEVM-native applications.
Returns an array of all logs matching the filter that was previously created with eth_newFilter on Linea. Unlike eth_getFilterChanges which returns only new logs since the last poll, this method returns the complete set of matching logs for the filter's block range.
Why Linea? Build on Consensys-backed zkEVM L2 with $1B+ TVL and 807% growth in 2025 with 15-30x lower fees than Ethereum mainnet, 6,200 TPS throughput, SWIFT integration with 12+ institutions, and $725M Consensys backing.
When to Use This Method
eth_getFilterLogs is essential for enterprise developers, DeFi builders, and teams seeking Consensys ecosystem integration:
- Initial Log Retrieval — Fetch the complete set of matching logs when you first create a filter on Linea
- Backfilling Event Data — Recover historical events after an indexer restart or gap in polling
- One-Time Queries — Retrieve all logs for a specific block range without incremental polling
- Data Reconciliation — Compare against incrementally collected data from
eth_getFilterChangesto detect missed events
Request Parameters
The filter ID returned by eth_newFilter. Only log filters are supported — block and pending transaction filters will return an error
Response Body
Address from which the log originated
Array of 0-4 indexed log arguments (32 bytes each)
Non-indexed log arguments (ABI-encoded)
Block number where the log was emitted
Hash of the transaction that generated the log
Index position of the transaction in the block
Hash of the block containing the log
Log index position in the block
true if the log was removed due to a chain reorganization
Error Responses
Code Examples
# First, create a filter
FILTER_ID=$(curl -s -X POST https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"method": "eth_newFilter",
"params": [{
"fromBlock": "0x1234500",
"toBlock": "0x1234600",
"address": "0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f"
}],
"id": 1
}' | jq -r '.result')
# Then, get all matching logs
curl -X POST https://api-linea-mainnet-archive.n.dwellir.com/YOUR_API_KEY \
-H "Content-Type: application/json" \
-d "{
\"jsonrpc\": \"2.0\",
\"method\": \"eth_getFilterLogs\",
\"params\": [\"$FILTER_ID\"],
\"id\": 2
}"Common Use Cases
1. Backfill Event Data After Indexer Restart
Recover missed events when your indexer goes down and comes back:
async function backfillEvents(provider, contractAddress, topics, lastProcessedBlock) {
const currentBlock = await provider.getBlockNumber();
// Create a filter covering the gap
const filterId = await provider.send('eth_newFilter', [{
fromBlock: '0x' + (lastProcessedBlock + 1).toString(16),
toBlock: '0x' + currentBlock.toString(16),
address: contractAddress,
topics: topics
}]);
// Retrieve all logs in the gap
const logs = await provider.send('eth_getFilterLogs', [filterId]);
console.log(`Backfilling ${logs.length} events from blocks ${lastProcessedBlock + 1} to ${currentBlock}`);
for (const log of logs) {
await processEvent(log);
}
// Clean up and switch to incremental polling
await provider.send('eth_uninstallFilter', [filterId]);
return currentBlock;
}2. Compare Filter Results with Direct Query
Verify data consistency between filter-based and direct log queries:
async function verifyFilterResults(provider, filterParams) {
// Create filter and get logs via eth_getFilterLogs
const filterId = await provider.send('eth_newFilter', [filterParams]);
const filterLogs = await provider.send('eth_getFilterLogs', [filterId]);
// Get logs directly via eth_getLogs
const directLogs = await provider.send('eth_getLogs', [filterParams]);
console.log(`Filter logs: ${filterLogs.length}, Direct logs: ${directLogs.length}`);
if (filterLogs.length !== directLogs.length) {
console.warn('Mismatch detected — investigate missing events');
}
await provider.send('eth_uninstallFilter', [filterId]);
return { filterLogs, directLogs };
}3. Paginated Historical Event Loader
Load large volumes of historical events in manageable chunks:
async function loadHistoricalEvents(provider, contractAddress, startBlock, endBlock, chunkSize = 2000) {
const allLogs = [];
for (let from = startBlock; from <= endBlock; from += chunkSize) {
const to = Math.min(from + chunkSize - 1, endBlock);
const filterId = await provider.send('eth_newFilter', [{
fromBlock: '0x' + from.toString(16),
toBlock: '0x' + to.toString(16),
address: contractAddress
}]);
const logs = await provider.send('eth_getFilterLogs', [filterId]);
allLogs.push(...logs);
console.log(`Blocks ${from}-${to}: ${logs.length} events (total: ${allLogs.length})`);
await provider.send('eth_uninstallFilter', [filterId]);
}
return allLogs;
}Error Handling
Common errors and solutions:
| Error Code | Description | Solution |
|---|---|---|
| -32000 | Filter not found | Filter expired or was uninstalled — recreate with eth_newFilter |
| -32000 | Query returned more than 10000 results | Narrow the block range in your filter — use smaller fromBlock/toBlock windows |
| -32600 | Invalid request | Verify the filter ID is a valid hex string |
| -32603 | Internal error | Node may be overloaded — retry with exponential backoff |
| -32005 | Rate limit exceeded | Reduce request frequency or implement client-side rate limiting |
async function safeGetFilterLogs(provider, filterId, maxRetries = 3) {
for (let i = 0; i < maxRetries; i++) {
try {
return await provider.send('eth_getFilterLogs', [filterId]);
} catch (error) {
if (error.message.includes('filter not found')) {
throw new Error('Filter expired — must recreate before retrying');
}
if (error.message.includes('more than 10000 results')) {
throw new Error('Too many results — narrow your block range');
}
if (i < maxRetries - 1) {
const delay = Math.pow(2, i) * 1000;
await new Promise(r => setTimeout(r, delay));
} else {
throw error;
}
}
}
}Related Methods
eth_newFilter— Create the log filter whose results this method returnseth_getFilterChanges— Poll for only new logs since the last call (incremental)eth_getLogs— Query logs directly without creating a filter firsteth_uninstallFilter— Remove a filter when no longer needed
eth_getFilterChanges
Poll a filter for new results since the last poll on Linea. Essential for event streaming, real-time monitoring, and efficient log indexing for enterprise DeFi (Aave, Renzo), institutional cross-border payments via SWIFT pilots, and zkEVM-native applications.
eth_uninstallFilter
Remove a filter on Linea created by eth_newFilter, eth_newBlockFilter, or eth_newPendingTransactionFilter. Essential for resource cleanup after event monitoring.