Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.sqd.dev/llms.txt

Use this file to discover all available pages before exploring further.

Make your first Portal request to access raw EVM blockchain data in under 5 minutes. No setup required, just HTTP requests.

What You’ll Build

In this quickstart, you’ll:
  1. Make a simple Portal request using curl (no installation required)
  2. Query recent Ethereum blocks
  3. Filter event logs from a smart contract
This guide uses the Public Portal endpoint, which is free and rate-limited. Perfect for getting started.

Step 1: Your First Request

Let’s query the last 1,000 blocks from Ethereum mainnet. Copy and paste this command:
curl --compressed -X POST 'https://portal.sqd.dev/datasets/ethereum-mainnet/stream' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "evm",
    "fromBlock": 18000000,
    "toBlock": 18001000,
    "includeAllBlocks": true,
    "fields": {
      "block": {
        "number": true,
        "timestamp": true,
        "gasUsed": true
      }
    }
  }'
You should see a stream of JSON objects, one per block, showing block numbers, timestamps, and gas usage.
includeAllBlocks: true tells Portal to return every block in the range. Without it (the default on EVM), Portal returns only blocks matching your data filters (logs, transactions, traces, stateDiffs). This request has no filters, so without includeAllBlocks it would return just the boundary blocks of the underlying workers, not the full range. See Stream semantics below.
Try it yourself with the interactive query interface below:

Step 2: Understanding the Request

Let’s break down what you just sent:
{
  "type": "evm",              // Chain type (EVM, Solana, etc.)
  "fromBlock": 18000000,      // Starting block (inclusive)
  "toBlock": 18001000,        // Ending block (inclusive)
  "fields": {                 // What data to return
    "block": {
      "number": true,         // Block number
      "timestamp": true,      // Block timestamp
      "gasUsed": true         // Total gas used in block
    }
  }
}
Portal only returns the fields you request. This keeps responses fast and bandwidth-efficient.

Step 3: Understanding the Response

Portal returns newline-delimited JSON (NDJSON). Each line is a complete JSON object representing one block. With includeAllBlocks: true the request above returns 1001 blocks (one per line). The first and last look like this:
{"header": {"number": 18000000, "timestamp": 1693066895, "gasUsed": "0xf7e9ab"}}
{"header": {"number": 18000001, "timestamp": 1693066907, "gasUsed": "0x1068c5a"}}
...
{"header": {"number": 18001000, "timestamp": 1693078967, "gasUsed": "0xae0606"}}
This format enables constant-memory streaming of massive ranges. You can process millions of blocks without loading everything into RAM.

Stream semantics

Two behaviors are easy to miss on your first Portal request. Both are enforced by the API, and clients that ignore them will silently drop data.

includeAllBlocks

Portal returns only blocks that match your data filters (logs, transactions, traces, stateDiffs).
  • If you set filters (e.g. logs: [{ address: [...] }]), Portal returns only blocks containing matching items. You rarely need includeAllBlocks.
  • If you want every block in the range regardless of filters (for analytics, backfilling a full block table, etc.), set "includeAllBlocks": true.
  • Defaults differ by chain: false on EVM, Solana, and Substrate; true on Bitcoin. Check the dataset’s API spec if in doubt.
Without filters and without includeAllBlocks, Portal returns just the worker-range boundary blocks. On EVM that’s typically 2–4 blocks per query. If you see far fewer blocks than expected, this is why.

The stream can end before toBlock

A single HTTP response can be cut short at any point: when a worker’s range ends, when a connection is recycled, or at the dataset’s current head. Clients must treat one response as a batch, not the entire range. To continue:
  1. Read the last block number (N) in the response.
  2. Issue a new request with fromBlock = N + 1 (and the same toBlock, filters, and fields).
  3. Loop until you receive HTTP 204 (range is above dataset height) or you reach your toBlock.
If you’re streaming near the chain head, also set parentBlockHash on each subsequent request and handle HTTP 409 (reorg). See the full API reference.

Step 4: Filter Event Logs

Track USDC Transfer events:
curl --compressed -X POST 'https://portal.sqd.dev/datasets/ethereum-mainnet/stream' \
  -H 'Content-Type: application/json' \
  -d '{
    "type": "evm",
    "fromBlock": 18000000,
    "toBlock": 18010000,
    "fields": {
      "log": {
        "address": true,
        "topics": true,
        "data": true,
        "transactionHash": true
      }
    },
    "logs": [{
      "address": ["0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48"],
      "topic0": ["0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef"]
    }]
  }'
You should see Transfer events from the USDC contract. Portal filtered the data before sending, saving bandwidth.

What You Learned

In 5 minutes, you:
  • ✓ Made HTTP requests to Portal
  • ✓ Queried arbitrary block ranges
  • ✓ Filtered smart contract events
  • ✓ Processed newline-delimited JSON responses

Rate Limits

The Public Portal is rate-limited:
  • 20 requests per 10 seconds
  • Perfect for development and testing

Cloud Portal

Production-ready managed access with higher limits

Self-Host Portal

Run your own Portal instance with no rate limits

Next Steps

API Reference

Complete reference with all fields and filters

View Examples

Practical examples for common use cases

Use with SDK

Build type-safe indexers with Portal as the data source

Query Event Logs

Track smart contract events

Query Transactions

Monitor wallet activity

Track NFT Transfers

Index NFT collection activity

Index DEX Swaps

Build DEX analytics