Thirdweb Insight

Insight is a powerful tool that lets you retrieve blockchain data from any EVM chain, enrich it with metadata, and transform it using custom logic. Whether you're building a gaming inventory system, tracking DeFi metrics, or analyzing NFT collections, Insight makes it easy to get the data you need with simple API calls.

Things to Keep in Mind

  • Rate Limiting: The API has rate limits based on your authentication tier. Monitor your usage and implement appropriate retry logic.

  • Pagination: When retrieving large datasets, use pagination parameters (page and limit) to avoid timeouts and manage response sizes effectively.

  • Chain Selection: Always verify you're querying the correct chain ID. Using an incorrect chain ID will return a 404 error.

  • Data Freshness: There may be a slight delay between on-chain events and their availability in the API due to block confirmation times.

  • Error Handling: Implement proper error handling for both HTTP errors (400/500) and network issues. Consider implementing retries for transient failures.

  • Query Optimization:

    • Use specific filters to reduce response size and improve performance
    • Avoid overly broad date ranges when possible
    • Consider using aggregations for large datasets
  • Authentication: Keep your authentication credentials secure and don't expose them in client-side code.

  • Response Processing: Some numeric values are returned as strings to maintain precision. Convert them appropriately in your application.

Aggregation Examples

Insight supports various aggregation functions that can be used to analyze blockchain data. Here are some common examples:

Basic Aggregations

// Count all transactions
const count = await fetch(
"https://10.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count",
);
// Get total value transferred (in wei)
const totalValue = await fetch(
"https://10.insight.thirdweb.com/v1/transactions?aggregate=sum(value) AS total_value_wei",
);
// Get average gas used
const avgGas = await fetch(
"https://10.insight.thirdweb.com/v1/transactions?aggregate=avg(gas_used) AS avg_gas_used",
);

Wallet-Specific Aggregations

// Get wallet transaction count and total value
const walletStats = await fetch(
"https://10.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei",
);
// Calculate total fees paid by a wallet
const walletFees = await fetch(
"https://10.insight.thirdweb.com/v1/wallets/0x123.../transactions?aggregate=sum(gas_used * gas_price) AS total_fees_wei",
);

Block Data Aggregations

// Get block statistics
const blockStats = await fetch(
"https://10.insight.thirdweb.com/v1/blocks?aggregate=sum(transaction_count) AS total_transactions&aggregate=avg(transaction_count) AS avg_transactions_per_block",
);
// Get block range
const blockRange = await fetch(
"https://10.insight.thirdweb.com/v1/blocks?aggregate=min(number) AS min_block_number&aggregate=max(number) AS max_block_number",
);

Filtering with Aggregations

// Get transaction stats for a specific time period
const txStats = await fetch(
"https://10.insight.thirdweb.com/v1/transactions?aggregate=count() AS transaction_count&aggregate=sum(value) AS total_value_wei&filter_timestamp_gte=2024-01-01&filter_timestamp_lte=2024-01-31",
);
// Get block metrics for recent blocks
const recentBlocks = await fetch(
"https://10.insight.thirdweb.com/v1/blocks?aggregate=sum(transaction_count) AS total_transactions&filter_number_gte=18000000",
);

API URL

const baseUrl = `https://{{chainId}}.insight.thirdweb.com`;

Authentication

The API supports three authentication methods:

// 1. Header Authentication
const headers = {
"x-client-id": "{{clientId}}", // thirdweb Client ID
};
// 2. Query Parameter
const url = `https://{{chainId}}.insight.thirdweb.com/v1/events?clientId={{clientId}}`;
// 3. Bearer Token
const headers = {
Authorization: "Bearer {{jwtToken}}",
};
// Example using fetch with header auth
async function getEvents() {
const response = await fetch(
`https://{{chainId}}.insight.thirdweb.com/v1/events`,
{
headers: {
"x-client-id": "{{clientId}}",
},
},
);
return await response.json();
}

Core Concepts

Chain IDs

The API supports chain IDs in the following formats:

  • As a subdomain:
// Example
const baseUrl = `https://{{chainId}}.insight.thirdweb.com`;
  • As a query parameter (this is useful if you want to query multiple chains):
// Example for a single chain
const url = `https://insight.thirdweb.com/v1/events?chain={{chainId}}`;
// Example for multiple chains
const url = `https://insight.thirdweb.com/v1/events?chain=1&chain=137`;

We won't duplicate multichain examples for each endpoint, but you can pass multiple chains in the query parameters pretty much everywhere!

Base Response Structure

interface BaseResponse<T> {
data: T[];
meta: {
chain_id: number; // Required
page: number; // Required
limit: number; // Required
total_items: number; // Required
total_pages: number; // Required
address?: string; // Optional
signature?: string; // Optional
}
}
// Example response from getting events
{
"data": [
{
"chain_id": 1,
"block_number": "17859301",
"transaction_hash": "0x123...",
"address": "0x456...",
"data": "0x789...",
"topics": ["0xabc..."]
}
],
"meta": {
"chain_id": 1,
"page": 0,
"limit": 20,
"total_items": 150,
"total_pages": 8
}
}

API Examples

Events API

// 1. Get All Events
async function getAllEvents(): Promise<BaseResponse<Event>> {
const response = await fetch(
`https://{{chainId}}.insight.thirdweb.com/v1/events`,
{
headers: { "x-client-id": "{{clientId}}" },
},
);
return await response.json();
}
// 2. Get Contract Events with Filtering
async function getContractEvents(
contractAddress: string,
): Promise<BaseResponse<Event>> {
const params = new URLSearchParams({
filter_block_number_gte: "{{blockNumber}}",
sort_by: "block_timestamp",
sort_order: "desc",
limit: "50",
});
const url = `https://{{chainId}}.insight.thirdweb.com/v1/events/${contractAddress}?${params}`;
const response = await fetch(url, {
headers: { "x-client-id": "{{clientId}}" },
});
return await response.json();
}

Token Balance API

// 1. Get ERC20 Balances
async function getERC20Balances(
ownerAddress: string,
): Promise<ERC20Response> {
const response = await fetch(
`https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc20/${ownerAddress}`,
{ headers: { "x-client-id": "{{clientId}}" } },
);
const data = await response.json();
// Example response:
// {
// "data": [
// {
// "tokenAddress": "0x123...",
// "balance": "1000000000000000000"
// }
// ]
// }
return data;
}
// 2. Get NFT Balances
async function getNFTBalances(ownerAddress: string) {
const response = await fetch(
`https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc721/${ownerAddress}`,
{ headers: { "x-client-id": "{{clientId}}" } },
);
const data = await response.json();
// Example response:
// {
// "data": [
// {
// "collectionAddress": "0x456...",
// "tokenId": "1",
// "balance": "1"
// }
// ]
// }
return data;
}

Using Filters

// Example: Get events with complex filtering
async function getFilteredEvents() {
const params = new URLSearchParams({
// Block filters
filter_block_number_gte: "{{startBlock}}",
filter_block_number_lte: "{{endBlock}}",
// Time filters
filter_block_timestamp_gte: "{{startTimestamp}}",
// Transaction filters
filter_from_address: "{{fromAddress}}",
filter_value_gte: "{{minValue}}", // 1 ETH
// Pagination
page: "0",
limit: "20",
// Sorting
sort_by: "block_timestamp",
sort_order: "desc",
});
const response = await fetch(
`https://{{chainId}}.insight.thirdweb.com/v1/events?${params}`,
{ headers: { "x-client-id": "{{clientId}}" } },
);
return await response.json();
}

Error Handling

async function safeApiCall() {
try {
const response = await fetch(
`https://{{chainId}}.insight.thirdweb.com/v1/events`,
{
headers: { "x-client-id": "{{clientId}}" },
},
);
if (!response.ok) {
const errorData = await response.json();
// Example error response:
// { "error": "Invalid client ID" }
throw new Error(errorData.error);
}
return await response.json();
} catch (error) {
console.error("API Error:", error.message);
throw error;
}
}

API Reference

Events API

  • Get All Events
GET https://{{chainId}}.insight.thirdweb.com/v1/events

or

GET https://insight.thirdweb.com/v1/events?chainId={{chainId1}}&chainId={{chainId2}}
  • Get Contract Events
GET https://{{chainId}}.insight.thirdweb.com/v1/events/:contractAddress
  • Get Specific Event Type
GET https://{{chainId}}.insight.thirdweb.com/v1/events/:contractAddress/:signature

Transactions API

  • Get All Transactions
GET https://{{chainId}}.insight.thirdweb.com/v1/transactions
  • Get Contract Transactions
GET https://{{chainId}}.insight.thirdweb.com/v1/transactions/:contractAddress
  • Get Specific Transaction Type
GET https://{{chainId}}.insight.thirdweb.com/v1/transactions/:contractAddress/:signature

Token Balance API

  • ERC20 Balances
GET https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc20/:ownerAddress
interface ERC20Response {
data: ERC20Balance[];
}
interface ERC20Balance {
tokenAddress: string;
balance: string;
}
  • ERC721 & ERC1155 Balances
GET https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc721/:ownerAddress
GET https://{{chainId}}.insight.thirdweb.com/v1/tokens/erc1155/:ownerAddress
interface TokenBalance {
data: NFTBalance[];
}
interface NFTBalance {
collectionAddress: string;
tokenId: string;
balance: string;
}

Query Parameters

Common Parameters

interface CommonQueryParams {
page?: number; // Default: 0
limit?: number; // Default: 20, must be > 0
sort_by?: "block_number" | "block_timestamp" | "transaction_index";
sort_order?: "asc" | "desc";
group_by?: string;
aggregate?: string[];
}

Filter Types

  • Block Filters
interface BlockFilters {
filter_block_number?: number; // Example: 1000000
filter_block_number_gte?: number; // Example: 1000000
filter_block_number_gt?: number; // Example: 1000000
filter_block_number_lte?: number; // Example: 1000000
filter_block_number_lt?: number; // Example: 1000000
filter_block_hash?: string; // Example: "0x3a1fba5..."
}
  • Time Filters
interface TimeFilters {
filter_block_timestamp?: number; // Example: 1715222400
filter_block_timestamp_gte?: number; // Example: 1715222400
filter_block_timestamp_gt?: number; // Example: 1715222400
filter_block_timestamp_lte?: number; // Example: 1715222400
filter_block_timestamp_lt?: number; // Example: 1715222400
}
  • Transaction Filters
interface TransactionFilters {
filter_transaction_index?: number;
filter_transaction_hash?: string;
filter_from_address?: string;
filter_value?: number;
filter_gas_price?: number;
filter_gas?: number;
// Additional gte, gt, lte, lt variants for numeric fields
}

Error Handling

All endpoints return standard error responses for 400 and 500 status codes:

// 400 Bad Request
// 500 Internal Server Error
interface ErrorResponse {
error: string; // Required
}