What this tool does
The ERC-721 Inspector reads any ERC-721 NFT contract and returns the name, symbol, tokenURI, and current owner from one expression. It is built for developers and collectors who need to inspect a specific token without writing ABI files or chasing IPFS gateways by hand.
How to use it
- Paste the ERC-721 contract address into the form above.
- Enter the token ID you want to inspect, then pick a chain.
- Run the query and read the name, symbol, owner, tokenURI, and metadata in the result panel.
The result panel shows the collection name and symbol, the current owner address, the raw tokenURI(id) returned by the contract, the resolved metadata URL, and the read block number. Everything happens in one round trip to the contract.
What is happening under the hood
ERC-721 is simpler to query than ERC-1155: every token ID has its own owner and its own tokenURI, already resolved by the contract with no {id} placeholder to substitute. evmquery handles the contract reads in one expression. The frontend handles the gateway fetch for the metadata JSON.
{
"name": dyn(nft.name()),
"symbol": dyn(nft.symbol()),
"tokenURI": dyn(nft.tokenURI(id)),
"owner": dyn(nft.ownerOf(id))
}
name()andsymbol()read the collection-level metadata exposed by the ERC-721 Metadata extension.tokenURI(id)returns the final metadata URL for that specific token. evmquery resolves the contract ABI from verified source and decodes the typed result.ownerOf(id)returns anaddress, while the other fields are strings. CEL maps need a single value type, so every field is wrapped indyn(...)— this yields amap<string, dyn>and each value serializes as its natural type (the owner comes back as a hex address).- Multiple reads are auto-batched by Multicall3, so the cost is one round trip regardless of how many fields you ask for.
Build this yourself
Each of the snippets below makes the same POST call to the evmquery REST API. The expression is the one shown above, with your contract address and inputs filled in.
REST (curl)
curl -X POST https://api.evmquery.com/api/v1/query \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"chain": "evm_ethereum",
"schema": {
"contracts": { "nft": { "address": "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" } },
"context": { "id": "sol_int" }
},
"expression": "{ \"name\": dyn(nft.name()), \"symbol\": dyn(nft.symbol()), \"tokenURI\": dyn(nft.tokenURI(id)), \"owner\": dyn(nft.ownerOf(id)) }",
"context": { "id": 1 }
}'
Python
import requests
resp = requests.post(
"https://api.evmquery.com/api/v1/query",
headers={"Authorization": "Bearer YOUR_API_KEY"},
json={
"chain": "evm_ethereum",
"schema": {
"contracts": {"nft": {"address": "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D"}},
"context": {"id": "sol_int"},
},
"expression": (
'{ "name": dyn(nft.name()), "symbol": dyn(nft.symbol()),'
' "tokenURI": dyn(nft.tokenURI(id)), "owner": dyn(nft.ownerOf(id)) }'
),
"context": {"id": 1},
},
timeout=10,
)
print(resp.json()["result"])
TypeScript
const resp = await fetch("https://api.evmquery.com/api/v1/query", {
method: "POST",
headers: {
Authorization: `Bearer ${process.env.EVMQUERY_API_KEY}`,
"Content-Type": "application/json",
},
body: JSON.stringify({
chain: "evm_ethereum",
schema: {
contracts: {
nft: { address: "0xBC4CA0EdA7647A8aB7C2061c2E118A18a936f13D" },
},
context: { id: "sol_int" },
},
expression:
'{ "name": dyn(nft.name()), "symbol": dyn(nft.symbol()), "tokenURI": dyn(nft.tokenURI(id)), "owner": dyn(nft.ownerOf(id)) }',
context: { id: 1n },
}),
});
const { result } = await resp.json();
The free tier has no monthly cap. Get a free API key to drop these snippets into your project.
When you would use this
- Verifying provenance. Confirm who currently owns a specific token before you buy, accept as collateral, or feature it.
- Auditing a new collection. Quickly verify a contract really implements ERC-721 and inspect the metadata URI before you list or integrate it.
- Debugging an indexer. Compare the on-chain
tokenURI(id)andownerOf(id)results with what your indexer cached to find where it drifted. - Writing ERC-721 docs. Show your readers a working
tokenURIandownerOfexample without making them set up a Hardhat console.
FAQ
What is ERC-721?
ERC-721 is the standard for non-fungible tokens. Each token ID on a contract is unique, has its own owner tracked by ownerOf(id), and typically points to its own metadata URI via tokenURI(id).
What is the difference between ERC-721 and ERC-1155?
ERC-721 gives every token ID its own owner and its own tokenURI, with no placeholder substitution needed. ERC-1155 lets one contract hold many token IDs that can be fungible or non-fungible, and its uri(id) returns a template with a literal {id} placeholder the client must substitute.
Why does tokenURI have no {id} placeholder to substitute?
The EIP-721 metadata extension defines tokenURI(uint256) as returning the final URL for that specific token, already resolved server-side by the contract. There is no client-side substitution step like the {id} template in EIP-1155.
Which chains are supported?
The Inspector currently runs against Ethereum, Base, and BNB Smart Chain. Additional EVM chains are being added on the evmquery backend. If you need a specific chain prioritized, contact support.
Does evmquery work with proxy contracts?
Yes. evmquery automatically resolves EIP-1967 transparent and beacon proxies to their implementation, so you call nft.tokenURI(id) against the proxy address and it works. Roughly a third of production contracts use proxies, including most upgradeable ERC-721 collections.
What if the metadata URI uses an IPFS gateway that times out?
The Inspector tries the URI as returned by the contract first. For ipfs:// URIs it falls back through a small list of public gateways. If none respond, the resolved URL is shown so you can open it directly or point your own application at a gateway you control.
Can I use this tool from my own application?
Yes. The same expression and contract address work against the public REST API. The free tier has no monthly cap, and a single inspection counts as one read because Multicall3 batches all the underlying calls into one round trip. Bring your own API key and the rate limit applied to this page no longer applies.
Limits and accuracy
- The result reflects the latest block at the time of the read. There is no historical replay.
- The metadata fetch runs from your browser. Some collections gate metadata behind authenticated origins, in which case only the on-chain values are shown.
- The demo is rate limited per browser. If you hit the limit, grab a free API key and the limit goes away.
- Image previews are loaded directly from the metadata image URL. If the gateway throttles or the image is missing, the preview is silently hidden.
- USD pricing, marketplace floor data, and royalty configuration are out of scope. evmquery returns raw on-chain values, not aggregated marketplace data.
Related
- Multicall3 batching for EVM contract reads — why one expression can replace dozens of
eth_callround trips - Read smart contracts in n8n — wire the same query into a no-code workflow
- Building an EVM blockchain MCP server — let Claude or Cursor inspect ERC-721 collections in chat
- evmquery for developers — the full integration story