Skip to main content

NEAR Data Examples

Examples​

NEAR Data returns each block fully hydrated as one JSON document — header plus per-shard chunks, receipts, execution outcomes, and state changes — so a single curl gives you everything you need to filter for a specific contract without a second call.

The shell examples below run against the NEAR Data hosts and pass FASTNEAR_API_KEY from your shell as an apiKey query parameter, so set it first. Bearer auth with Authorization: Bearer ${FASTNEAR_API_KEY} is also supported when headers fit your client better.

What block is NEAR on right now?​

/v0/last_block/final 302-redirects to the current finalized block. Before filtering for a specific contract, it's worth seeing what one block looks like at the protocol level: transactions arrive sharded, so the tx count for a block is a sum across shards — not a single top-level number.


curl -sL "https://mainnet.neardata.xyz/v0/last_block/final?apiKey=${FASTNEAR_API_KEY:-}" \
  | jq '{
      height: .block.header.height,
      timestamp_nanosec: .block.header.timestamp_nanosec,
      txs_per_shard: [.shards[] | {shard_id, tx_count: (.chunk.transactions | length)}],
      total_txs: ([.shards[].chunk.transactions[]?] | length)
    }'

A live block shows 9 shards and a handful of transactions scattered across them — most shards are empty in any given block, and activity tends to cluster on whichever shards host the busy contracts. timestamp_nanosec is a Unix time in nanoseconds (divide by 1e9 for seconds). With this one call you already have everything needed to dig deeper — the filtering examples below are just jq over this same response.

Did my contract get touched in the latest finalized block?​

/v0/last_block/final 302-redirects to the current finalized block. Contracts can show up in a chunk's transactions (when they are the receiver_id) or in its receipts (when a cross-shard call lands), so one jq pass over the shards covers both.

TARGET_CONTRACT=intents.near

curl -sL "https://mainnet.neardata.xyz/v0/last_block/final?apiKey=${FASTNEAR_API_KEY:-}" \
  | jq --arg contract "$TARGET_CONTRACT" '{
      height: .block.header.height,
      contract: $contract,
      touched_shards: [
        .shards[] | {
          shard_id,
          txs:      [.chunk.transactions[]? | select(.transaction.receiver_id == $contract) | .transaction.hash],
          receipts: [.chunk.receipts[]?     | select(.receiver_id == $contract)             | .receipt_id]
        } | select((.txs | length) + (.receipts | length) > 0)
      ]
    }'

touched_shards: [] is a complete answer for a quiet block. A non-empty list names the shards where the contract showed up and gives you the concrete tx hashes or receipt_ids — pipe a hash into the Transactions API when you want the human-readable story. Receipts without matching txs are normal: a cross-contract call shows up as an incoming receipt in this block even if the originating transaction landed earlier.

Did activity show up optimistically, and did finality catch up?​

Optimistic blocks ship at /v0/block_opt/{height} about a second ahead of /v0/block/{height}. A monitoring loop can act on the optimistic signal and expect the same answer to arrive at the finalized endpoint one block later — unless network stress widens the gap, in which case the finalized fetch returns null and you wait.

TARGET_CONTRACT=intents.near

count_touches() {
  jq --arg contract "$1" '
    [.shards[]
     | ([.chunk.transactions[]? | select(.transaction.receiver_id == $contract)] | length)
     + ([.chunk.receipts[]?     | select(.receiver_id == $contract)]             | length)]
    | add // 0'
}

OPT_LOCATION="$(
  curl -s -D - -o /dev/null "https://mainnet.neardata.xyz/v0/last_block/optimistic?apiKey=${FASTNEAR_API_KEY:-}" \
    | awk 'tolower($1) == "location:" {print $2}' | tr -d '\r'
)"
OPT_PATH="${OPT_LOCATION%%\?*}"
OPT_HEIGHT="${OPT_PATH##*/}"

echo "optimistic @ $OPT_HEIGHT: $(curl -s "https://mainnet.neardata.xyz$OPT_PATH?apiKey=${FASTNEAR_API_KEY:-}" | count_touches "$TARGET_CONTRACT") touches"
FINAL="$(curl -s "https://mainnet.neardata.xyz/v0/block/$OPT_HEIGHT?apiKey=${FASTNEAR_API_KEY:-}")"
if [ "$(printf '%s' "$FINAL" | jq 'type')" = '"null"' ]; then
  echo "finalized @ $OPT_HEIGHT: not caught up yet"
else
  echo "finalized @ $OPT_HEIGHT: $(printf '%s' "$FINAL" | count_touches "$TARGET_CONTRACT") touches"
fi

On a healthy mainnet the two counts match within a second. The value is in the pattern — the optimistic stream gives you an answer you can act on immediately, with the finalized stream arriving a block later as durable confirmation.

Which shard actually changed my contract's state?​

Most finalized blocks show no state mutation for any given contract — activity is sparse and shard-local. Walk back from the finalized head until the contract's state actually changes, then open that shard for the mutation payload. The block-level call tells you which shard; the shard-level call tells you how.

TARGET_CONTRACT=intents.near

HEAD="$(curl -sL "https://mainnet.neardata.xyz/v0/last_block/final?apiKey=${FASTNEAR_API_KEY:-}" | jq '.block.header.height')"
FOUND_HEIGHT=""
FOUND_SHARD=""

for OFFSET in $(seq 0 15); do
  H=$((HEAD - OFFSET))
  SHARD="$(curl -s "https://mainnet.neardata.xyz/v0/block/$H?apiKey=${FASTNEAR_API_KEY:-}" \
    | jq -r --arg contract "$TARGET_CONTRACT" '
        .shards[]
        | select([.state_changes[]? | select(.change.account_id? == $contract)] | length > 0)
        | .shard_id
      ' | head -1)"
  if [ -n "$SHARD" ]; then
    FOUND_HEIGHT=$H; FOUND_SHARD=$SHARD
    break
  fi
done

if [ -z "$FOUND_HEIGHT" ]; then
  echo "no state mutation for $TARGET_CONTRACT in the last 16 finalized blocks"
else
  curl -s "https://mainnet.neardata.xyz/v0/block/$FOUND_HEIGHT/shard/$FOUND_SHARD?apiKey=${FASTNEAR_API_KEY:-}" \
    | jq --arg contract "$TARGET_CONTRACT" --argjson height "$FOUND_HEIGHT" --argjson shard_id "$FOUND_SHARD" '{
        height: $height,
        shard_id: $shard_id,
        state_changes:      [.state_changes[]              | select(.change.account_id?                        == $contract) | {type, cause: (.cause | keys[0])}][0:3],
        execution_outcomes: [.receipt_execution_outcomes[] | select(.execution_outcome.outcome.executor_id     == $contract) | {receipt_id: .execution_outcome.id, status: (.execution_outcome.outcome.status | keys[0])}][0:3]
      }'
fi

On mainnet, intents.near lives on shard 7, so the walk typically lands within a handful of blocks. The shard payload names the actual state-change types (account_update, data_update, etc.) and the receipt outcomes that caused them — shard-local proof without guessing. Widen the offset range for contracts with lighter traffic.

When to widen​

  • Use the Transactions API once you have a tx_hash and want the human-readable transaction story.
  • Use the RPC Reference when the next question is about exact protocol-native receipt or block semantics.
  • Use Block Headers when you only need head progression or finality lag, not contract-touch inspection.