Choose Substreams when
- The consumer must process every relevant block or event in order.
- You need a historical backfill that continues as a live stream.
- Cursor recovery forms part of the production design.
Feed your database, analytics pipeline, or event processor with standard Substreams package output over gRPC.
filtered_events
Request parameters
ethereum-common@v0.4.0 · USDC Transfer
Request excerpt. See the service quickstart for authentication and a complete example.
Package and stream parameters
{
"package": "ethereum-common@v0.4.0",
"output_module": "filtered_events",
"params": "evt_addr:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 && evt_sig:0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef",
"start_block_num": -1,
"final_blocks_only": false
}Substreams delivers package output over gRPC, and your consumer turns it into state. These patterns cover the decisions that keep that state complete and correct.
01 start block · stop block · cursor
Load a protocol's event history into your database, then keep it current from the same consumer. Backfills and live streaming use the same stream protocol: start at the block your history needs, leave the stop block open, and the stream continues as new blocks arrive. Historical ranges can use parallel package execution within your organization's worker concurrency.
02 BlockScopedData · cursor
Every block-scoped message carries output and a cursor. Write both in one database transaction where you can, so the stored cursor always matches committed data. After a disconnect, reconnect with backoff and resume from the latest committed cursor. Replays from that point must be safe, so make writes idempotent.
BlockScopedData output to your tables.03 BlockUndoSignal · last valid block
Near the chain head, a block can be replaced. Substreams then sends a BlockUndoSignal with the last valid block and its cursor. Your consumer reverts what it wrote after that block, saves the new cursor, and continues with the replacement blocks.
BlockUndoSignal, revert rows above the last valid block.final_blocks_only, so output trails the chain head. The stream example at the top of this page follows live blocks and applies undo signals.04 .spkg · db_out · substreams sink
Reuse a package from the Substreams registry or run your own .spkg, then choose the output module your pipeline needs. Standard sinks write it to Postgres, ClickHouse, files, or Pub/Sub, or your application consumes the stream directly. The database stays yours to query, join, and retain.
.spkg, and pin its version.db_out for the SQL sink.GraphOps runs the package against chain data and streams its output. Everything after the stream, from cursors to tables, belongs to your consumer.
Each network has its own endpoint, listed below from the live catalog. Package compatibility depends on the chain data model.
See supported networksx-api-key header or SUBSTREAMS_API_KEY. Route-token authentication is not supported.Each network has its own endpoint, listed below from the live catalog. Package compatibility depends on the chain data model.
Go from a new organization to a first response, then prepare for production traffic.
Choose your monthly credits or buy a top-up. Streams consume credits by the current billable components.
The CLI reads SUBSTREAMS_API_KEY. Raw gRPC clients send an x-api-key header.
Pick a package and output module, then the endpoint for the chain it supports.
Run the pinned Ethereum package over six blocks to inspect USDC Transfer events.
Pin package versions, persist cursors durably, handle undo signals, and test recovery before processing a larger range.
https://<CHAIN_ID>.evm.substreams.graphops.xyz Use standard Substreams tooling with this endpoint. Its hostname starts with the decimal EVM chain ID of a supported network.
Prerequisites
Install the Substreams CLI.
Set GRAPHOPS_API_KEY to your GraphOps API key.
CLI · Substreams CLI
# The CLI sends SUBSTREAMS_API_KEY to GraphOps in the x-api-key header.
export SUBSTREAMS_API_KEY="${GRAPHOPS_API_KEY}"
# Stream USDC Transfer events (--params) for six blocks from 18000002 as JSON lines.
substreams run \
-e "https://1.evm.substreams.graphops.xyz" \
"https://spkg.io/v1/packages/ethereum-common/v0.4.0" \
"filtered_events" \
--params "filtered_events=evt_addr:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48 && evt_sig:0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef" \
--start-block 18000002 \
--stop-block +6 \
-o jsonl
Add credits and follow the quickstart, then test cursor recovery and undo handling before processing a larger range.