Overview
Tests your filter function with data from a specific block before deploying it to a stream. This allows you to validate your filter logic and see the transformed output without affecting any live streams.
Key use cases:
- Validate filter function syntax and logic
- Preview transformed data output
- Debug filter functions before deployment
- Test filters against historical block data
Endpoint
Send a POST request to test a filter function.
POST https://api.quicknode.com/streams/rest/v1/streams/test_filter
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
| network | string | Yes | Blockchain network (see Supported Chains) |
| dataset | string | Yes | Dataset type (see Data Sources) |
| filter_function | string | Yes | Base64-encoded JavaScript filter function |
| block | string | Yes | Block number to test against |
Example Request
- cURL
- CLI
- JavaScript
Python
- Ruby
- SDK (JS)
SDK (Python)
- SDK (Ruby)
- SDK (Rust)
curl -X POST "https://api.quicknode.com/streams/rest/v1/streams/test_filter" \
-H "accept: application/json" \
-H "Content-Type: application/json" \
-H "x-api-key: YOUR_API_KEY" \
-d '{
"network": "ethereum-mainnet",
"dataset": "block",
"filter_function": "ZnVuY3Rpb24gbWFpbihkYXRhKSB7CiAgcmV0dXJuIHsKICAgIGhhc2g6IGRhdGEuc3RyZWFtRGF0YS5oYXNoLAogICAgbnVtYmVyOiBwYXJzZUludChkYXRhLnN0cmVhbURhdGEubnVtYmVyLCAxNikKICB9Owp9",
"block": "18000000"
}'
qn stream test-filter --network ethereum-mainnet \
--dataset block \
--block 18000000 \
--filter-file ./filter.js \
--filter-language javascript \
-o json
const headers = new Headers()
headers.append('accept', 'application/json')
headers.append('Content-Type', 'application/json')
headers.append('x-api-key', 'YOUR_API_KEY')
// Encode your filter function to base64
const filterFunction = Buffer.from(`
function main(data) {
return {
hash: data.streamData.hash,
number: parseInt(data.streamData.number, 16)
};
}
`).toString('base64')
const body = JSON.stringify({
network: 'ethereum-mainnet',
dataset: 'block',
filter_function: filterFunction,
block: '18000000'
})
fetch('https://api.quicknode.com/streams/rest/v1/streams/test_filter', {
method: 'POST',
headers: headers,
body: body
})
.then(response => response.json())
.then(data => console.log(data))
.catch(error => console.error('Error:', error))
import requests
import base64
url = "https://api.quicknode.com/streams/rest/v1/streams/test_filter"
# Encode your filter function to base64
filter_code = """
function main(data) {
return {
hash: data.streamData.hash,
number: parseInt(data.streamData.number, 16)
};
}
"""
filter_function = base64.b64encode(filter_code.encode()).decode()
payload = {
"network": "ethereum-mainnet",
"dataset": "block",
"filter_function": filter_function,
"block": "18000000"
}
headers = {
"accept": "application/json",
"Content-Type": "application/json",
"x-api-key": "YOUR_API_KEY"
}
response = requests.post(url, headers=headers, json=payload)
print(response.json())
require "uri"
require "net/http"
require "json"
require "base64"
url = URI("https://api.quicknode.com/streams/rest/v1/streams/test_filter")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl = true
request = Net::HTTP::Post.new(url)
request["accept"] = "application/json"
request["Content-Type"] = "application/json"
request["x-api-key"] = "YOUR_API_KEY"
# Encode your filter function to base64
filter_code = <<~JS
function main(data) {
return {
hash: data.streamData.hash,
number: parseInt(data.streamData.number, 16)
};
}
JS
filter_function = Base64.strict_encode64(filter_code)
request.body = {
"network" => "ethereum-mainnet",
"dataset" => "block",
"filter_function" => filter_function,
"block" => "18000000"
}.to_json
response = https.request(request)
puts response.body
import { QuicknodeSdk, StreamDataset } from "@quicknode/sdk"
const qn = new QuicknodeSdk({ apiKey: "YOUR_API_KEY" })
const filterFunction = Buffer.from(`
function main(data) {
return data
}
`).toString("base64")
const result = await qn.streams.testFilter({
network: "ethereum-mainnet",
dataset: StreamDataset.Block,
block: "17811625",
filterFunction,
})
console.log("logs:", result.logs)
console.log("result:", result.result)
import asyncio
import base64
from quicknode_sdk import QuicknodeSdk, SdkFullConfig
async def main():
qn = QuicknodeSdk(SdkFullConfig(api_key="YOUR_API_KEY"))
filter_function = base64.b64encode(
b"function main(data) { return data; }"
).decode()
result = await qn.streams.test_filter(
network="ethereum-mainnet",
dataset="block",
block="17811625",
filter_function=filter_function,
)
print("logs:", result.logs)
print("result:", result.result)
asyncio.run(main())
require "base64"
require "quicknode_sdk"
qn = QuicknodeSdk::SDK.from_config(api_key: "YOUR_API_KEY")
filter_function = Base64.strict_encode64("function main(data) { return data; }")
result = qn.streams.test_filter(
network: "ethereum-mainnet",
dataset: "block",
block: "17811625",
filter_function: filter_function,
)
puts "logs: #{result["logs"]}"
puts "result: #{result["result"]}"
use quicknode_sdk::{
streams::{StreamDataset, TestFilterParams},
QuicknodeSdk,
SdkFullConfig,
};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let qn = QuicknodeSdk::new(&SdkFullConfig::builder().api_key("YOUR_API_KEY").build())?;
// Base64-encoded: function main(data) { return data; }
let filter_function = "ZnVuY3Rpb24gbWFpbihkYXRhKSB7IHJldHVybiBkYXRhOyB9".to_string();
let params = TestFilterParams {
network: "ethereum-mainnet".to_string(),
dataset: StreamDataset::Block,
block: "17811625".to_string(),
filter_function: Some(filter_function),
filter_language: None,
address_book_config: None,
};
let result = qn.streams.test_filter(¶ms).await?;
println!("logs: {:?}", result.logs);
println!("result: {}", result.result);
Ok(())
}
Response
On success, the API returns the result of applying your filter function to the specified block's data.
{
"logs": [],
"result": "{...}"
}
Response Fields
| Field | Type | Description |
|---|---|---|
| logs | array | Any console logs output by your filter function |
| result | string | The result of the filter test |
tip
If your filter function has errors, the response will contain error details to help you debug the issue.