# Get a wallet's holdings and PnL on Robinhood Chain

> Get a Robinhood Chain wallet's tokens with USD value, ETH balance, realized and unrealized PnL, win rate, gas spent and wallet tags in one call. Real example.

Source: https://docs.crius.sh/guides/get-wallet-pnl-and-holdings/ · Updated 2026-10-28

Short answer

Call `GET /v1/robinhood/wallet/{address}?window=30d` (Starter plan, 5 credits). It returns `holdings[]` (token, `balance`, `value_usd`, `price_confidence`, per-token `pnl`), `native_balance` in ETH, and a `pnl` summary over the window (`realized_usd`, `unrealized_usd`, `total_usd`, `win_rate_pct`, `trades`, `volume_usd`, `gas_spent_usd`), plus `account_type` and `profile.tags`.

[GET `/wallet/{address}`](https://docs.crius.sh/reference/wallets/wallet-profile/) [GET `/wallet/{address}/trades`](https://docs.crius.sh/reference/wallets/wallet-trades/) [GET `/wallet/{address}/connections`](https://docs.crius.sh/reference/wallets/wallet-connections/)

A wallet profile is everything a Robinhood Chain address holds and has earned: its tokens with their USD value, its ETH balance, its realized and unrealized PnL over a window, its win rate and gas spent, and what kind of account it is. Crius reads the balances on-chain at one block and computes PnL from every trade attributed to the wallet, so a portfolio app or a wallet-scoring tool gets the whole picture in one call.

## Get the profile in one call

Example [Starter plan · 5 credits](https://docs.crius.sh/reference/wallets/wallet-profile/)

### CHARGE's creator: 0.71 ETH, two fake USDG tokens, no trades

What does the wallet that launched Charge AI (0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca) hold, and has it traded in the last 30 days?

GET/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca

 

**cURL**

```bash
curl "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca" \
  -H "x-api-key: $CRIUS_API_KEY"
```

**JavaScript**

```js
const res = await fetch("https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca", {
  headers: { "x-api-key": process.env.CRIUS_API_KEY },
});
const { data, meta } = await res.json();
```

**Python**

```python
import os, requests

r = requests.get(
    "https://api.crius.sh/v1/robinhood/wallet/0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca",
    headers={"x-api-key": os.environ["CRIUS_API_KEY"]},
)
body = r.json()
print(body["data"])
```

**Real response 200 Captured Oct 28, 2026 · 84 lines (arrays trimmed)**

```json
{
  "data": {
    "account_type": "smart_account",
    "address": "0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca",
    "delegate": "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b",
    "holdings": [
      {
        "balance": 25,
        "pnl": null,
        "price_confidence": "low",
        "token": {
          "address": "0xfaaf8ffa8a29ceb6c85aff8d3961f65ae1bfc775",
          "logo": null,
          "symbol": "USDG"
        },
        "value_eth": 0.00000500064,
        "value_usd": 0.0117789
      },
      {
        "balance": 25,
        "pnl": null,
        "price_confidence": "low",
        "token": {
          "address": "0x06993ae1230d3755b54f25022028daa66772bc3d",
          "logo": null,
          "symbol": "USDG"
        },
        "value_eth": 0.00000500061,
        "value_usd": 0.0117789
      }
    ],
    "holdings_truncated": false,
    "holdings_value_usd": 0.0235578,
    "is_contract": false,
    "label": null,
    "native_balance": 0.71473787532832551,
    "native_value_usd": 1683.56,
    "pnl": {
      "avg_hold_time_s": null,
      "best_trade": null,
      "gas_scope": "all transactions sent by the wallet in the window",
      "gas_spent_usd": 0.198772,
      "realized_usd": 0,
      "tokens_traded": 0,
      "tokens_with_known_cost": 0,
      "total_usd": 0,
      "trades": 0,
      "unrealized_usd": 0,
      "volume_usd": 0,
      "win_rate_pct": null,
      "window": "30d",
      "worst_trade": null
    },
    "profile": {
      "first_seen_block": 91351250,
      "first_seen_ts": 1792283372000,
      "fresh": false,
      "funded_by": {
        "address": "0xd782268f600403843484b70710daee6846fc0db8",
        "amount_eth": 0.008148386337868892,
        "block": 87601233,
        "label": "bridge:Relay solver",
        "ts": 1791903516300
      },
      "history": "complete",
      "tags": [
        "dev",
        "smart_account"
      ],
      "tx_count": 14,
      "wallet_age_days": 10.8994
    }
  },
  "meta": {
    "balances_block": 100406864,
    "block": 100406864,
    "block_age_ms": 1301,
    "block_ts": 1793225084000,
    "chain": "robinhood",
    "finalized_block": 100397649,
    "lag_ms": 59,
    "safe_block": 100401329
  }
}
```

What this tells you

-   `account_type: "smart_account"` with `delegate: "0x63c0c19a282a1b52b07dd5a65b58948a07dae32b"`: an EIP-7702 wallet whose code delegates to that contract. `is_contract` is `false` and `profile.tags` is `["dev", "smart_account"]`: it created a launchpad token.
-   `native_balance: 0.71473787532832551` ETH, worth `native_value_usd: 1683.56`. That’s nearly all of its value.
-   Both holdings say `symbol: "USDG"`, but neither is USDG. Real USDG is `0x5fc5360d0400a0fd4f2af552add042d716f1d168`; these are `0xfaaf8ffa8a29ceb6c85aff8d3961f65ae1bfc775` and `0x06993ae1230d3755b54f25022028daa66772bc3d`. 25 of each are worth `value_usd: 0.0117789` at `price_confidence: "low"`, and `pnl` is `null`: they were sent to the wallet, not bought. Always identify tokens by address.
-   `pnl.window: "30d"` (the default): `trades: 0`, `tokens_traded: 0`, `total_usd: 0` and `win_rate_pct: null`. It still paid `gas_spent_usd: 0.198772`, because `gas_scope` is “all transactions sent by the wallet in the window”, not only trades.
-   `profile.funded_by` is `0xd782268f600403843484b70710daee6846fc0db8`, labeled `bridge:Relay solver`, with 0.008148386337868892 ETH: the wallet’s first ETH came over the Relay bridge. `profile.tx_count: 14`.
-   `meta.balances_block: 100406864`: the ETH and token balances were read on-chain at that block.

[Wallet profile reference](https://docs.crius.sh/reference/wallets/wallet-profile/) [Data looks wrong? Report it](mailto:support@crius.sh?subject=Wrong%20data%20in%20docs%20example%3A%20CHARGE's%20creator%3A%200.71%20ETH%2C%20two%20fake%20USDG%20tokens%2C%20no%20trades&body=Page%3A%20https%3A%2F%2Fdocs.crius.sh%2Fguides%2Fget-wallet-pnl-and-holdings%2F%23creator-wallet%0ARequest%3A%20GET%20%2Fv1%2Frobinhood%2Fwallet%2F0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca%0A%0AWhat's%20wrong%20or%20missing%3F%0A%0A)

## How PnL is calculated

Per token, using the USD value of each trade when it happened (average cost):

-   **Realized** = USD received from sells − tokens sold × average buy price.
-   **Unrealized** = balance × current price − cost of the balance at the average buy price.
-   The `pnl` summary adds both over every token traded in the `window` (`1d`, `7d`, `30d` by default, or `all`).

An unrealized loss in practice, from the [holder snapshot](https://docs.crius.sh/guides/get-historical-holders/): `0xe683eb5c66b0c55c54ce45d46a3bf0a69d809c8f` held 29,879,481 CHARGE that cost it `cost_basis_usd: 515.975` and were worth `value_usd: 180.252` at that moment: an unrealized PnL of −$335.724.

Tokens a wallet sold more of than it bought (some arrived by transfer) have no known cost: they’re left out of the totals and the win rate, and `tokens_with_known_cost` says how many were counted. The details and edge cases are in [How PnL works](https://docs.crius.sh/concepts/pnl/).

## What the fields mean

| Field | Meaning |
| --- | --- |
| `account_type`, `delegate` | `eoa`, `smart_account` (EIP-7702, with the contract it delegates to) or `contract`. |
| `label` | Known name of the address (an exchange, a bridge, an app wallet), or `null`. |
| `native_balance`, `native_value_usd` | ETH balance and its USD value. |
| `holdings[]` | Tokens with a balance, most valuable first (up to 200): `token` (address, symbol, logo), `balance`, `value_usd`, `value_eth`, `price_confidence`, `pnl`. |
| `holdings[].price_confidence` | How far to trust `value_usd`: `high`, `medium` (price pool under $10k liquidity), `low` (thin pool) or `none` (no price). |
| `holdings_value_usd`, `holdings_truncated` | Total value of the token holdings; `true` when the address touched too many tokens to price them all. |
| `pnl.realized_usd`, `unrealized_usd`, `total_usd` | PnL over the window. |
| `pnl.win_rate_pct` | Share of tokens with known cost that ended in profit. |
| `pnl.trades`, `tokens_traded`, `tokens_with_known_cost`, `volume_usd` | Activity in the window. |
| `pnl.best_trade`, `worst_trade`, `avg_hold_time_s` | The tokens with the highest and lowest PnL, and the average time from first to last trade per token. |
| `pnl.gas_spent_usd`, `gas_scope` | Gas paid in the window, for every transaction the wallet sent. |
| `profile.tags` | `dev` (created a launchpad token), `fresh` (under a day old), `smart_account`, `contract`, or the app for app wallets (`fomo`). |
| `profile.funded_by` | The wallet's first funder: `address`, `label`, `amount_eth`, `block`, `ts`. |
| `profile.tx_count`, `history` | Transactions sent, and whether the whole history is indexed. |

## Use it in your app

1.  **Get a Starter key.** `/wallet/{address}` needs the Starter plan and costs 5 credits per call. Send it in the `x-api-key` header.
    
2.  **Hide spam.** Add `min_value_usd=1` (or more) so airdropped lookalike tokens don’t clutter the portfolio, and match tokens by `token.address`, never by symbol.
    
3.  **Pick the window your users expect.** `window=7d` for a weekly card, `all` for lifetime PnL. Show `tokens_with_known_cost` next to the win rate so readers know what it’s based on.
    
4.  **Go deeper when needed.** Each trade is in [wallet trades](https://docs.crius.sh/guides/get-wallet-trade-history/), and who funded the wallet in [connected wallets](https://docs.crius.sh/guides/find-connected-wallets/).
    

```python
import os, requests

wallet = "0x3ac82d45ff9e4963cefbc3f74dbe293f34c927ca"
r = requests.get(
    f"https://api.crius.sh/v1/robinhood/wallet/{wallet}",
    params={"window": "7d", "min_value_usd": 1},
    headers={"x-api-key": os.environ["CRIUS_API_KEY"]},
)
d = r.json()["data"]
p = d["pnl"]
print(f"{d['account_type']} {d['profile']['tags']}: {d['native_balance']} ETH (${d['native_value_usd']})")
print(f"{p['window']} PnL ${p['total_usd']} on {p['trades']} trades, win rate {p['win_rate_pct']}%")
for h in d["holdings"]:
    print(h["token"]["symbol"], h["token"]["address"], h["balance"], f"${h['value_usd']}", h["price_confidence"])
```

## Frequently asked questions

**How is wallet PnL calculated?**

Per token, with average cost in USD at the time of each trade. Realized PnL is what the sells returned minus the cost of the tokens sold at the wallet's average buy price; unrealized PnL is the current value of what it still holds minus its cost. The `pnl` summary adds these up over the tokens traded in the `window`. Gas is reported separately in `gas_spent_usd`, not subtracted.

**How do I get every token a wallet holds?**

`/wallet/{address}` lists up to 200 holdings with a balance, most valuable first, each checked against the token's `balanceOf`. Add `min_value_usd=1` to hide dust and spam tokens. The ETH balance is separate, in `native_balance` and `native_value_usd`.

**What does \`win\_rate\_pct\` mean?**

The share of tokens traded in the window that ended in profit (realized plus unrealized PnL above zero), counting only tokens whose cost is known (`tokens_with_known_cost`). It's per token, not per trade. It's `null` when the wallet traded nothing in the window.

**Why does a holding have \`pnl: null\`?**

The wallet never bought that token, or sold more than it bought: it arrived by transfer or airdrop, so there is no cost to measure against. That's typical of spam tokens sent to active wallets.

**Which plan does the wallet profile need?**

The Starter plan or higher, 5 credits per call. See [Plans & limits](https://docs.crius.sh/plans-and-limits/).

## Related

[Guide **Wallet trade history** List every trade a Robinhood Chain wallet made across all tokens, with USD value at trade time, market cap, DEX and gas. Filter by token, side, size, time. Read](https://docs.crius.sh/guides/get-wallet-trade-history/) [Guide **Top traders & PnL** Rank the traders of any Robinhood Chain token by PnL, volume, buys or ROI, with wallet tags, gas and hold time. A real example with the PnL math explained. Read](https://docs.crius.sh/guides/get-top-traders-pnl/) [Guide **Wallet token balances** Get every token balance of a Robinhood Chain wallet (USDG, tokenized stocks, ETH) in USD in one call, one token's balances across wallets, and batch prices. Read](https://docs.crius.sh/guides/get-wallet-token-balances/) [Concept **PnL** How the Crius API computes realized and unrealized PnL, ROI, cost basis and win rate for Robinhood Chain traders and wallets, worked through on real trades. Read](https://docs.crius.sh/concepts/pnl/) [Use case **Wallets & portfolios** What a Robinhood Chain wallet or portfolio app needs from the Crius API: holdings, USD values, PnL, trade history and warnings about spam tokens. Read](https://docs.crius.sh/use-cases/wallets-and-portfolio-apps/) [API reference **Wallet profile API** Holdings with USD value, realized and unrealized PnL over a window (1d, 7d, 30d, all), win rate and wallet tags. Read](https://docs.crius.sh/reference/wallets/wallet-profile/)
