Every verification API asks the same thing of its users: trust us. You send a query, you get a result, and you believe it because the server said so. For many use cases that is fine. For high-value decisions, custody proofs, and autonomous agent workflows, it is not enough. Merkle storage proofs change the equation. They let you verify the result yourself, against the blockchain's own state root, without running a node.

The trust problem with verification APIs

When you call a blockchain API to check if a wallet holds a token, you are trusting three things: that the API connected to the right chain, that it read the correct contract, and that it reported the result honestly. Most APIs handle this well. But "most of the time" is not a cryptographic guarantee.

ECDSA signatures help. InsumerAPI signs every attestation response with a P-256 key, proving the result came from Insumer and was not tampered with in transit. But the signature proves who said it. It does not prove what is actually on-chain.

This is the gap Merkle proofs fill.

What is a Merkle storage proof?

Every Ethereum block header contains a state root. This is the root hash of a Merkle Patricia Trie that encodes the entire state of every account and contract on the chain. If you have a proof (a sequence of hashes from a leaf to the root), you can verify that a specific piece of data exists in the trie without downloading the full state.

EIP-1186 standardized this. The eth_getProof RPC method returns the proof data for any account and any storage slot at any block. Given the proof and the block header's state root (which is public, available from any block explorer or light client), anyone can independently verify the storage value.

For ERC-20 token balances, the storage slot is determined by the contract's balanceOf mapping. The key is computed as keccak256(abi.encode(walletAddress, mappingSlot)), where the mapping slot varies by contract implementation.

How InsumerAPI uses Merkle proofs

InsumerAPI now offers two levels of trust for its attestation endpoint:

The trade-off is explicit. Standard mode is privacy-maximizing: you get a yes or no, nothing more. Merkle proof mode is trust-minimizing: you get the cryptographic evidence to verify the answer yourself, but the raw balance is part of that evidence.

What comes back in the response

When you call the attestation endpoint with proof: "merkle", each result in the response includes a proof object with these fields:

For conditions where Merkle proofs are not available (Taiko, Ronin, Moonriver, Viction, Solana, XRPL, or NFT ownership checks), the proof object returns available: false with a reason string. The boolean result is still computed and signed normally.

Verifying a proof yourself

Verification does not require InsumerAPI at all. Once you have the proof, the process is entirely local:

  1. Get the block header for the returned blockNumber from any Ethereum node, light client, or block explorer API. Extract the stateRoot.
  2. Walk the accountProof trie nodes from the leaf to the root. Confirm the computed root matches the block header's stateRoot.
  3. From the account node, extract the storageHash.
  4. Walk the storageProof trie nodes. Confirm the computed storage root matches the storageHash.
  5. Decode the leaf value from the storage proof. This is the raw balance. Compare it against your expected threshold.

Libraries for this exist in every major language. In JavaScript, @ethereumjs/trie handles the RLP decoding and trie traversal. In Python, pyethash or web3.py can verify Merkle Patricia proofs. In Go, Geth's own trie package works natively.

Which chains support proofs

Merkle proofs require access to a node that supports eth_getProof. InsumerAPI currently supports Merkle proofs on 26 of 30 EVM chains:

The remaining 4 EVM chains (Taiko, Ronin, Moonriver, Viction) use a different data path that does not expose raw storage proofs. Solana uses a different state model entirely (account-based, not Merkle Patricia) and XRPL uses its own ledger structure. Bitcoin uses a UTXO model that is structurally incompatible with EIP-1186. For these chains, the boolean result and ECDSA signature are the trust anchors.

Storage slot resolution

A subtle challenge with eth_getProof is that it requires the exact storage key. For ERC-20 contracts, the key depends on which slot the balanceOf mapping occupies, and that varies by contract implementation.

InsumerAPI handles this automatically. The correct mapping slot is resolved internally for each contract, so callers never need to know or specify it. The response includes the mappingSlot used, so proof verifiers can recompute the storage key independently.

Why this matters for AI agents

Autonomous AI agents making financial decisions need verifiable inputs. An agent operating in a multi-agent workflow cannot simply trust that another agent's claim about a wallet's holdings is accurate. Merkle proofs give agents a way to verify claims independently.

Consider a lending agent that needs to confirm collateral before extending credit. With standard attestation, it trusts the API. With Merkle proofs, it can verify the collateral claim against the block header, confirm the proof cryptographically, and proceed with mathematical certainty rather than API trust.

The MCP server and LangChain toolkit both support the proof parameter. Any agent built on these frameworks can request Merkle proofs with a single parameter change.

Two levels of trust, one API

InsumerAPI does not force a choice between privacy and verifiability. Standard mode gives you privacy-preserving boolean results with ECDSA signatures, suitable for gating any API on wallet state. Merkle proof mode gives you cryptographic evidence tied to the blockchain's own state. Both modes return in a single API call, across the same 33 chains, using the same API key.

For most use cases, the ECDSA-signed boolean is sufficient. It proves who verified the condition and when. For high-stakes verification, custody attestation, or agent-to-agent trust where you need to eliminate API trust entirely, Merkle proofs close the gap.

The verification chain becomes: blockchain state root (in the public block header) proves the storage proof, the storage proof proves the balance, and the balance proves whether the condition was met. No trust in any intermediary required.

For the full API surface, including the proof: "merkle" parameter and all attestation options, see the AI Agent Verification API overview and the complete OpenAPI 3.1 specification.

Get a free API key and try Merkle proofs

InsumerAPI is free to start. 10 verification credits, 33 chains. Add proof: "merkle" to any attestation call and see the cryptographic evidence for yourself.

View Developer Portal