# Why Portfolio APIs Disagree About Net Worth

> Two crypto portfolio APIs can report a 600x difference for the same wallet on the same day. The cause is almost never pricing — it is what they can decode.

- **URL:** https://octav.fi/blog/why-portfolio-apis-disagree
- **Published:** 2026-06-04
- **Author:** Octav Team — Portfolio Intelligence for Digital Assets
- **Topic:** Benchmarks & Comparisons
- **Tags:** benchmark, defi, comparison
- **Source:** Octav, Practical guides on crypto NAV reporting, multi-chain portfolio management and digital asset APIs, from the team behind Octav.

---
If two portfolio APIs return different net worth for the same address, the
instinct is to blame price feeds. That is almost never the cause.

On a clean single-protocol Aave wallet, every EVM API in
[our nine-provider benchmark](/crypto-portfolio-api-benchmark) reconciles to
**within 0.2%**. Prices are a solved problem. What is not solved is knowing
what the wallet holds in the first place.

## A balance query is not a portfolio

Ask an RPC node what an address holds and you get a list of token balances.
For a wallet that only holds spot tokens, that list *is* the portfolio.

For a wallet that has done anything in DeFi, the tokens in it are receipts:

| What you hold | What a balance query sees | What it is worth |
| --- | --- | --- |
| Supplied to Aave | `aUSDC` balance | Principal + accrued interest |
| LP on Uniswap | LP token balance | A share of the pool's current composition |
| Staked SOL via Jito | `jitoSOL` balance | Staked principal + rewards |
| Perp position on Hyperliquid | Nothing in the wallet | Margin + unrealised PnL |
| Options on Derive | Collateral token | The value of the options book |

The last two are the reason the gaps get extreme. A perp position is not a
token at all — it is state inside a protocol. An API that only enumerates
tokens cannot see it, and will not tell you it cannot see it. It returns a
number that looks complete.

## How large the gap gets

From the benchmark, same wallets, same day:

| Wallet | Token-only APIs | Full-decoding APIs |
| --- | --- | --- |
| Multi-sector whale | $612.6k – $28.60M | $46.27M |
| Solana DeFi whale | ~$9.67M | $26.04M |
| Derive options book | ~$401.6k | $1.33M |
| Hyperliquid perp trader | ~$27k | $56k |



<CoverageGapChart />

Across the wallet set the spread between token-only and full-portfolio APIs
runs from **10× to 600×**.

## Four failure modes to test for

When you evaluate a provider, these are the specific things that break. Test
them with a wallet you already know the answer for.

**1. Silent omission.** The API returns 200 OK with a partial portfolio and no
indication that a sector was skipped. This is the dangerous one — an error you
can handle, a confident wrong number you cannot.

**2. Receipt tokens priced as tokens.** An LST priced from a thin market rather
than from the underlying stake. An LP token priced by its own market rather
than by pool composition.

**3. Double counting.** The same value reported twice — once as the receipt
token and once as the decoded position. Ask your provider whether it ships a
price source per asset so you can audit which is which.

**4. Chain gaps presented as zero.** A provider without Solana support does not
return "unsupported"; it returns a portfolio without the Solana half.

## What to ask a provider

- Which sectors do you decode: lending, LP, staking, perps, options?
- Which chains have DeFi decoding, not just token balances?
- Do you return a price source per asset?
- What happens when a position type is unsupported — omitted, or flagged?
- How do you avoid double-counting receipt tokens?

## The practical consequence

For a fund, this is not an academic problem. A NAV built on an API that misses
a sector is wrong in a way no amount of downstream reconciliation will catch,
because the missing positions never enter the pipeline. See
[What Is NAV Reporting for Crypto Funds?](/what-is-crypto-nav-reporting) for
how position enumeration feeds the rest of the process, and
[Tracking DeFi Positions Across Multiple Chains](/track-defi-positions-multichain)
for why the problem multiplies per chain.
