Logo
New RPC users get 35% off their first monthView the offer
RPC Assistant

What is a Base NFT API and how do you query NFT data on Base?

Summary

A Base NFT API is the set of RPC methods and indexed data services you use to read NFT ownership, metadata, and transfer history on the Base network. Standard JSON-RPC calls like eth_call, eth_getLogs, and eth_getBalance cover on-chain reads, while indexer-style APIs add pre-aggregated ownership and collection data. This article explains which approach fits which workload and how to connect reliably.

You will see how to query ERC-721 and ERC-1155 contracts directly over Base RPC, when an indexer is the better tool, and how to configure a production endpoint. OnFinality provides Base RPC API access and dedicated node infrastructure if you need consistent throughput for NFT-heavy read traffic.

If you searched for a Base NFT API, you probably need to read NFT data on Base: who owns a token, what a collection contains, or how a token moved between wallets. There is no single "NFT API" on Base. Instead you combine standard JSON-RPC calls to the Base network with optional indexer services that pre-aggregate ownership and metadata. This page shows what each layer does, how to connect, and how to keep NFT read traffic stable in production.

Which approach fits your NFT workload

Before writing code, decide whether you need raw on-chain reads or pre-indexed data. The right choice depends on how much aggregation you want to do yourself and how fresh the data must be.

WorkloadBest fitWhy
Read one token's owner or balanceBase RPC (eth_call)Direct contract read, always current at the queried block
List all tokens owned by a walletIndexer API or your own indexerRPC alone cannot enumerate holdings without scanning logs
Fetch collection metadata and imagesIndexer API or tokenURI + off-chain fetchMetadata often lives on IPFS or HTTP, not fully on-chain
Track transfers in real timeBase RPC (eth_getLogs or WebSocket)Logs give you the raw Transfer events as they happen
Backfill full transfer historyArchive-capable RPC or indexerHistorical log queries need archive state and careful paging
Verify a mint or sale on-chainBase RPC (eth_getTransactionReceipt)Receipts confirm what actually executed

A practical pattern is to use Base RPC for authoritative, point-in-time reads and an indexer for list-style queries. Many teams run both: RPC for correctness and indexer for speed on aggregated views.

Base chain settings at a glance

Use these values when adding Base to a wallet, backend config, or test harness. They match the network configuration OnFinality publishes for Base.

SettingBase mainnetBase Sepolia testnet
Chain ID845384532
Native currencyETH (18 decimals)ETH (18 decimals)
Block explorerhttps://basescan.orghttps://sepolia.basescan.org
Public RPC (OnFinality)https://base.api.onfinality.io/publichttps://base-sepolia.api.onfinality.io/public
TransportHTTPHTTP

For a managed endpoint and network details, see the Base RPC network page and the Base Sepolia RPC network page.

Reading NFT data with JSON-RPC

Most ERC-721 and ERC-1155 reads go through eth_call with an encoded function selector. The three calls you will use most are ownerOf, balanceOf, and tokenURI for ERC-721, and balanceOf plus uri for ERC-1155.

Here is a minimal curl example that calls ownerOf(uint256) on an ERC-721 contract. The selector for ownerOf is 0x6352211e, followed by the token ID padded to 32 bytes.

curl -s https://base.api.onfinality.io/public \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "eth_call",
    "params": [
      {
        "to": "0xYOUR_NFT_CONTRACT",
        "data": "0x6352211e0000000000000000000000000000000000000000000000000000000000000001"
      },
      "latest"
    ]
  }'

The response is ABI-encoded. Decode it as an address. If the token does not exist, the call reverts and you get an error object instead of a value, so handle both cases.

In JavaScript, viem and ethers handle encoding for you. This example reads the owner and token URI of an ERC-721 token:

import { createPublicClient, http, parseAbi } from "viem";
import { base } from "viem/chains";

const client = createPublicClient({
  chain: base,
  transport: http("https://base.api.onfinality.io/public"),
});

const abi = parseAbi([
  "function ownerOf(uint256) view returns (address)",
  "function tokenURI(uint256) view returns (string)",
]);

const owner = await client.readContract({
  address: "0xYOUR_NFT_CONTRACT",
  abi,
  functionName: "ownerOf",
  args: [1n],
});

const uri = await client.readContract({
  address: "0xYOUR_NFT_CONTRACT",
  abi,
  functionName: "tokenURI",
  args: [1n],
});

console.log(owner, uri);

tokenURI usually returns an ipfs:// or https:// link. Resolving it is an off-chain fetch, not an RPC call, so plan for caching and timeouts there.

Enumerating transfers and ownership with logs

To find transfers, query eth_getLogs filtered by the ERC-721 or ERC-1155 Transfer event topic and the contract address. This is how most indexers build ownership tables.

const logs = await client.getLogs({
  address: "0xYOUR_NFT_CONTRACT",
  fromBlock: 0n,
  toBlock: "latest",
});

Two constraints matter. First, providers cap the block range per eth_getLogs request, so you must page through history in chunks. Second, deep historical queries need archive state; a non-archive node may reject or fail them. If you are backfilling a large collection, chunk by block range and persist your progress so a failed request does not force a full restart.

For live transfer feeds, a WebSocket subscription to logs avoids polling. Not every endpoint exposes WebSocket transport, so confirm transport support before designing around it. If you need persistent subscriptions, dedicated node infrastructure is often a better fit than a shared public endpoint.

When a raw RPC endpoint is not enough

RPC gives you correctness but not convenience. It cannot answer "list every NFT this wallet owns" without you scanning logs and reconstructing state. That is the job of an indexer or an NFT data API.

Common reasons teams add an indexer layer on top of Base RPC:

  • Wallet portfolio views that must return quickly for many collections.
  • Marketplace or gallery pages that need collection-level metadata and counts.
  • Analytics that aggregate transfers across thousands of contracts.
  • Metadata caching so you are not resolving tokenURI on every page load.

You can run your own indexer against a Base RPC endpoint, or use a hosted NFT data service. Either way, the RPC endpoint underneath still needs to handle your indexing load, which is usually far heavier than a single user request.

Production readiness checklist for NFT read traffic

NFT workloads are read-heavy and bursty. A drop or a new collection can multiply request volume in minutes. Before you ship, check these items.

CheckWhat to verify
Endpoint capacityYour provider can absorb burst reads from wallets, galleries, and indexers
Archive accessHistorical log and state queries are supported if you backfill
TransportHTTP for reads, WebSocket if you subscribe to live logs
FailoverA second endpoint or provider is configured for automatic retry
CachingMetadata and tokenURI responses are cached with sensible TTLs
BatchingMultiple reads are batched with JSON-RPC batch requests where possible
MonitoringYou track error rates, latency, and rate-limit responses

If you expect steady or high NFT read volume, compare a shared public endpoint against a managed plan and dedicated nodes. OnFinality offers Base RPC API access and dedicated nodes; see RPC pricing and the full list of supported RPC networks to plan capacity.

Common failure modes and how to debug them

Most Base NFT API problems fall into a few repeatable categories.

SymptomLikely causeFix
eth_call revertsToken does not exist or wrong contractConfirm token ID and contract address
Empty log resultsWrong topic or block rangeCheck the Transfer topic hash and widen the range
Request rejected on old blocksNon-archive nodeUse an archive-capable endpoint
Rate-limit errors under loadShared endpoint limitsBatch requests, cache, or move to a managed plan
Metadata fails to loadIPFS gateway or HTTP timeoutAdd a fallback gateway and cache results
Inconsistent ownershipReading at different blocksPin a block number for consistent snapshots

A quick diagnostic is to replay the failing call against a known-good block and compare. If it succeeds there, the issue is usually state depth or range, not your ABI encoding.

Testing on Base Sepolia

Build and test against Base Sepolia before mainnet. The chain ID is 84532, and the OnFinality public endpoint is https://base-sepolia.api.onfinality.io/public. Deploy a test ERC-721, mint a few tokens, and run your ownerOf, balanceOf, and eth_getLogs paths against it. Test your paging logic here, where mistakes are cheap, rather than on mainnet where a bad backfill can be expensive.

Key Takeaways

  • A Base NFT API is a combination of Base JSON-RPC calls and, optionally, an indexer for aggregated data.
  • Use eth_call for ownerOf, balanceOf, and tokenURI; use eth_getLogs for transfers.
  • RPC cannot enumerate a wallet's holdings on its own; that needs an indexer or your own indexing job.
  • Historical log queries need archive state and block-range paging.
  • Confirm transport support before relying on WebSocket subscriptions.
  • Plan for bursty read traffic with caching, batching, and failover.
  • Test on Base Sepolia (chain ID 84532) before mainnet.

Frequently Asked Questions

Is there a single Base NFT API?

No. Base exposes standard Ethereum JSON-RPC, so NFT reads use the same methods as any EVM chain. Aggregated NFT data comes from indexers or hosted data services layered on top.

Can I list all NFTs owned by a wallet using only RPC?

Not directly. You would have to scan Transfer logs and reconstruct ownership yourself. An indexer is the practical choice for portfolio-style queries.

Do I need an archive node for NFT history?

If you query old blocks or backfill transfer history, yes. Archive-capable endpoints serve historical state that a pruned node cannot.

Does Base RPC support WebSocket subscriptions?

Transport support varies by endpoint. Check your provider's documentation before designing around live log subscriptions.

How do I avoid rate limits during a backfill?

Batch requests, page through logs in chunks, cache metadata, and consider a managed or dedicated endpoint for sustained indexing load.

Where can I find Base endpoint and chain details?

See the Base RPC network page and Base Sepolia RPC network page for chain settings and endpoints.

RPC Knowledge Base

Related RPC details

Never Worry about Infrastructure Again

OnFinality takes away the heavy lifting of DevOps so you can build smarter and faster.

Get Started