Skip to main content
This page provides a quick reference for the Portal API. For the complete OpenAPI specification with all fields and options:

Complete EVM API Specification

View the full OpenAPI documentation with all available fields, filters, and detailed schemas →

Base URL

All Portal requests are made to:
Replace {network} with your target blockchain (e.g., ethereum-mainnet, polygon-mainnet, arbitrum-one).

Core Endpoints

POST /stream

Stream blockchain data with filters. Includes unfinalized blocks.

POST /finalized-stream

Stream only finalized blocks. Use for production pipelines requiring certainty.

GET /metadata

Get dataset information: block range, finality rules, and network details.

GET /timestamps/{timestamp}/block

Resolve a Unix timestamp to the first block at or after it.

Installation

Quick Start Examples

Available Fields

Block Fields

Select which block header fields to retrieve:

Transaction Fields

Select transaction data fields:

Log Fields

Select event log fields:

Trace Fields

Select call trace fields. The selectors are prefixed by trace kind (call*, create*, suicide*, reward*); there are no bare from/to/value selectors:
The response nests these fields, and transactionHash is not a trace field.
  • Requested call*/create* selectors come back grouped under action and result sub-objects, not flat. For example callFrom/callTo/callValue are returned as action.{from,to,value}, and callResultGasUsed as result.gasUsed. Numeric values such as action.value are hex wei (e.g. "0x0").
  • transactionHash is not a valid fields.trace.* selector. To get a trace’s transaction hash, join the parent transaction: set "transaction": true in the traces filter and request fields.transaction.hash.
  • The @subsquid/portal-client typed client flattens the action/result nesting back to the callFrom/callResultGasUsed field names; the nesting above describes the raw HTTP (curl) response.

State Diff Fields

Select state change fields:

Filtering Options

Log Filters

Filter logs by contract address and event topics:
Filter logic:
  • Multiple addresses in one object = OR
  • Multiple topics in one object = AND
  • Multiple filter objects = OR

Transaction Filters

Filter transactions by sender, recipient, or function signature:

Trace Filters

Filter traces by type, caller, or callee:

State Diff Filters

Filter state changes by contract address:

Network Selection

Specify the EVM network when creating the data source:

View All Networks

See complete list of 100+ supported EVM networks

Query Patterns

Pattern 1: Range Query

Query a specific block range:

Pattern 2: Batch Processing

Process large ranges in batches:

Pattern 3: Multi-Contract Query

Query multiple contracts simultaneously:

Performance Optimization

1. Request Only Needed Fields

2. Use Specific Filters

3. Optimal Batch Sizes

4. Parallel Queries

Resolve a timestamp to a block

GET /datasets/{dataset}/timestamps/{timestamp}/block returns the number of the first block whose timestamp is greater than or equal to the given Unix timestamp (in seconds). Use it to turn a wall-clock time into a fromBlock for a stream query.
Resolution prefers archival data and falls back to the real-time source when available; the x-sqd-data-source response header reports which one served the result (network or real_time). The endpoint returns 404 if no block at or after the timestamp exists yet.

Stream continuation

A single /stream response is a batch, not the complete range. The server may close the connection at any point: when a worker’s range ends, when a connection is recycled, or at the current dataset head. Clients that treat one HTTP response as the whole query will silently drop blocks. To stream a range to completion, loop:
Key points:
  • Read the last block’s header.number, issue the next request with fromBlock = lastNumber + 1.
  • Keep toBlock, fields, and filters identical across retries.
  • A 204 No Content response means the range is above the dataset head. For historical queries, you’re done; for open-ended queries, wait and retry.

Handling reorgs near the chain head

When a request starts at or near the chain tip, the block you asked for may no longer be on the canonical chain by the time Portal processes the query. To detect this, pass parentBlockHash with each request (the hash of the block immediately before fromBlock):
If the chain has reorged away from parentBlockHash, Portal returns HTTP 409 with a list of blocks that are on the current canonical chain:
Client recovery:
  1. Find a block in your local state whose (number, hash) matches one of previousBlocks.
  2. Roll back your pipeline to that block.
  3. Resume the stream with fromBlock = matched.number + 1 and parentBlockHash = matched.hash.
Streams opened against /finalized-stream (instead of /stream) never return 409: only finalized blocks are served, so there’s nothing to reorg. Use that endpoint when you don’t need real-time data.

Error Handling

Common Use Cases

Use Case 1: Event Monitoring

Monitor specific smart contract events:

Use Case 2: Transaction Tracking

Track transactions to/from specific addresses:

Use Case 3: Analytics Pipeline

Build analytics on blockchain data:

Request Structure Reference

Every Portal request follows this structure:

Response Format

Portal returns newline-delimited JSON (NDJSON), with one block per line:
This format enables constant-memory streaming of arbitrary ranges.

Common Patterns

Process large block ranges by splitting into manageable chunks:
Stream new blocks as they arrive using /finalized-stream:
Handle rate limits and network errors gracefully:

Complete API Specification

For the complete OpenAPI specification with all available fields, options, and detailed schemas:

Full EVM API Specification

View complete OpenAPI documentation with all endpoints, fields, and options →

Next Steps

View Examples

Explore practical Portal examples for common use cases

Supported Networks

See complete list of 100+ supported EVM networks

Quickstart Guide

Make your first Portal request in 5 minutes