Block Nodes expose gRPC APIs for querying block data, checking node status, and subscribing to the
live block stream. This guide walks through making your first API call from the command line using
grpcurl. No SDK is required.
| Service | RPC | Description |
|---|---|---|
BlockNodeService |
serverStatus |
Returns the block number range available on this node and basic version info. Start here. |
BlockNodeService |
serverStatusDetail |
Returns software version, stream proto version, and the list of installed plugins. |
BlockAccessService |
getBlock |
Retrieves a single block by block number, or the latest block. |
BlockStreamSubscribeService |
subscribeBlockStream |
Streams a range of blocks, or streams new blocks live as they arrive. |
All APIs use gRPC over HTTP/2 (h2c). TLS is terminated upstream at the load balancer - connect
with -plaintext for every public endpoint listed below.
# macOS
brew install grpcurl
# Linux
curl -sSL https://github.com/fullstorydev/grpcurl/releases/latest/download/grpcurl_linux_x86_64.tar.gz \
| tar -xz && sudo mv grpcurl /usr/local/bin/Every Block Node GitHub release
ships a block-node-protobuf-<VERSION>.tgz archive with all API proto files. Download and
extract it:
BUNDLE_URL=$(curl -s https://api.github.com/repos/hiero-ledger/hiero-block-node/releases/latest \
| grep "browser_download_url.*block-node-protobuf.*tgz" \
| head -1 | cut -d '"' -f 4)
mkdir -p ~/bn-proto && cd ~/bn-proto
curl -sL -O "$BUNDLE_URL"
tar -xzf block-node-protobuf-*.tgzAll grpcurl commands below assume you are running from ~/bn-proto.
Start with previewnet or testnet before querying mainnet.
Each Block Node service listens on its own dedicated port. Previewnet is already deployed with per-service ports; testnet and mainnet will be updated before the v0.76 release.
| Service | Port | Protocol |
|---|---|---|
BlockStreamSubscribeService (subscribeBlockStream) |
40980 | gRPC (h2c) |
BlockAccessService (getBlock) |
40981 | gRPC (h2c) |
BlockNodeService (serverStatus, serverStatusDetail) |
40982 | gRPC (h2c) |
Health (/healthz, /readyz) |
40983 | HTTP |
Connect with -plaintext for all public endpoints - TLS is terminated upstream at the load balancer.
| Endpoint | Tier |
|---|---|
lfh01.previewnet.blocknode.hashgraph-devops.com |
1 |
lfh02.previewnet.blocknode.hashgraph-devops.com |
1 |
| Endpoint | Tier |
|---|---|
s01.test.blk.ams.lat.ope.eng.hashgraph.io |
1 |
s01.test.blk.sgp.lat.ope.eng.hashgraph.io |
1 |
s01.test.blk.chi.lat.ope.eng.hashgraph.io |
1 |
lfh01.testnet.blocknode.hashgraph-devops.com |
2 |
| Endpoint | Tier |
|---|---|
91.242.214.237 |
1 |
46.21.97.212 |
1 |
162.43.189.97 |
1 |
163.114.159.114 |
1 |
82.223.201.227 |
1 |
Additional mainnet operators are being onboarded; the list will grow as more come online. Once
HIP-1137 is live, the full roster will be queryable
on-chain via the Mirror Node REST API at /api/v1/network/registered-nodes.
No API key or authentication token is required for the public endpoints listed above.
The examples below use s01.test.blk.sgp.lat.ope.eng.hashgraph.io (testnet) with the
per-service ports listed above. Substitute any endpoint from the tables above. Replace example
block numbers with values from the firstAvailableBlock–lastAvailableBlock range returned by
serverStatus - the available range differs across previewnet, testnet, and mainnet.
serverStatus returns the range of blocks available on this node. Call it first to determine valid
block numbers for subsequent requests.
grpcurl -plaintext -emit-defaults \
-import-path . \
-proto block-node/api/node_service.proto \
-d '{}' \
s01.test.blk.sgp.lat.ope.eng.hashgraph.io:40982 \
org.hiero.block.api.BlockNodeService/serverStatusThe response includes firstAvailableBlock and lastAvailableBlock.
serverStatusDetail returns the Block Node software version, stream proto version, and the
list of installed plugins with their versions.
grpcurl -plaintext -emit-defaults \
-import-path . \
-proto block-node/api/node_service.proto \
-d '{}' \
s01.test.blk.sgp.lat.ope.eng.hashgraph.io:40982 \
org.hiero.block.api.BlockNodeService/serverStatusDetailgetBlock returns a single block. The easiest starting point is to request the latest available
block:
grpcurl -plaintext -emit-defaults \
-import-path . \
-proto block-node/api/block_access_service.proto \
-d '{"retrieve_latest": true}' \
s01.test.blk.sgp.lat.ope.eng.hashgraph.io:40981 \
org.hiero.block.api.BlockAccessService/getBlockTo retrieve a specific block by number, use a block number within the range returned by
serverStatus:
grpcurl -plaintext -emit-defaults \
-import-path . \
-proto block-node/api/block_access_service.proto \
-d '{"block_number": 38000000}' \
s01.test.blk.sgp.lat.ope.eng.hashgraph.io:40981 \
org.hiero.block.api.BlockAccessService/getBlockNote: Blocks can be several megabytes. Pipe to
jqor redirect to a file if you need to inspect the full content.
subscribeBlockStream streams a range of blocks. Set end_block_number to a specific block
number for a finite range, or to "18446744073709551615" (uint64 max) to stream new blocks live
as they arrive.
Finite range - 10 blocks starting at a known block number:
grpcurl -plaintext -emit-defaults \
-import-path . \
-proto block-node/api/block_stream_subscribe_service.proto \
-d '{"start_block_number": 38000000, "end_block_number": 38000009}' \
s01.test.blk.sgp.lat.ope.eng.hashgraph.io:40980 \
org.hiero.block.api.BlockStreamSubscribeService/subscribeBlockStreamLive stream - all new blocks from a known block number onward:
grpcurl -plaintext -emit-defaults \
-import-path . \
-proto block-node/api/block_stream_subscribe_service.proto \
-d '{"start_block_number": 38000000, "end_block_number": "18446744073709551615"}' \
s01.test.blk.sgp.lat.ope.eng.hashgraph.io:40980 \
org.hiero.block.api.BlockStreamSubscribeService/subscribeBlockStreamTip:
end_block_numberis a uint64 field. Pass the uint64 max value as a JSON string ("18446744073709551615") rather than a number literal to avoid precision loss in JSON parsers.
Blocks currently served by Block Nodes wrap Hiero Record Stream Files - the same data Mirror Nodes have always processed, packaged in the Block format. The block content and structure will change at the block stream cutover, after which blocks will carry the full Hiero block stream: event data, state changes, and more granular transaction detail. Both forms are wire-compatible using the same proto schema, but the post-cutover form contains significantly more information. See Block Stream Cutover for the cutover schedule and migration details.