---
title: "One wallet's swaps and PnL"
method: GET
path: "/chains/{chain}/wallet/{address}"
tags: ["Avalanche, Base, BNB Chain"]
---

# One wallet's swaps and PnL

`GET /chains/{chain}/wallet/{address}`

## Request

- Base URL: `https://api.getchord.xyz/v1`
- URL: `https://api.getchord.xyz/v1/chains/{chain}/wallet/{address}`
- Auth: none declared

A wallet's swaps on the chain and an average-cost PnL over them. **The window is short**: the database keeps the raw tape for a few days on these chains (about 3 on BNB Chain and Base, 7 on Avalanche today), and older days come from Chord's data lake only where its days run without a gap up to that window. `window` says how far back the numbers go and `history` where they came from (`raw`, `raw+lake`, or `raw (lake unavailable)`). Say so when you show the number.

- A buy adds tokens and cost; a sell realizes proceeds minus the average cost of the part the window saw bought.
- A sell with nothing bought in the window has no cost basis: it is counted in `soldWithoutBasisUsd`, never as profit.
- `holdsTokens` is bought minus sold inside the window, priced at the token's last hourly print. It is not the on-chain balance (transfers are not swaps).
- Trades under the chain's ingest floor are not in the tape (BNB Chain: $100).
- Past 5,000 swaps in the window the newest 5,000 are kept and `truncated` is true (a bot or a router).

Chain-keyed data for Avalanche C-Chain, Base and BNB Chain, served from Chord's rollup tables for the chain (every swap summed by hour, token and venue). Only the trade tape, the prints ticker and the wallet read raw rows, scoped to one token or one wallet and bounded.

- **Access.** No key needed while the chain is public (all three are today). A chain whose tape is off, or that is not public yet, answers `400 UNSUPPORTED_CHAIN` ("chain N is not served yet") unless the request carries an `X-API-Key`; those answers are sent `Cache-Control: private`.
- **Ingest floor.** Every count, volume and print covers trades at or above the chain's floor, returned as `ingestFloor`. BNB Chain runs at $100 today; Avalanche and Base at 0.
- **Readiness.** `503 NOT_READY` until the chain's rollup has run on this deployment; `503 CHAIN_DATA_UNAVAILABLE` when the store cannot be read. Never treat either as "no trades".

## Path parameters

- `chain` 'avalanche' | 'base' | 'bnb' | 'arbitrum' | 'ethereum' | '43114' | '8453' | '56' | '42161' | '1', required
- `address` string, required: EVM address, hex, case-insensitive.

## Response `200`

- object
  - `chain` integer
  - `wallet` string: EVM address, hex, case-insensitive.
  - `window` object: The span the numbers cover. `fromTs` null = no trades indexed for the wallet.
    - `fromTs` integer, nullable: Unix time, seconds, UTC.
    - `toTs` integer: Unix time, seconds, UTC.
    - `days` integer, nullable
  - `history` 'raw' | 'raw+lake' | 'raw (lake unavailable)': Where the window's rows came from.
  - `trades` integer: Swaps in the window.
  - `truncated` boolean: More than 5,000 swaps in the window: only the newest 5,000 are counted.
  - `realizedUsd` number
  - `unrealizedUsd` number
  - `totalUsd` number
  - `volumeUsd` number
  - `soldWithoutBasisUsd` number: Sell proceeds with no buy in the window to match. Not profit.
  - `tokens` object[]: Largest absolute PnL first.
    - `token` string: EVM address, hex, case-insensitive.
    - `symbol` string, nullable
    - `buys` integer
    - `sells` integer
    - `boughtUsd` number
    - `soldUsd` number
    - `realizedUsd` number
    - `unrealizedUsd` number
    - `totalUsd` number
    - `holdsTokens` number: Bought minus sold in the window, whole tokens.
    - `holdsUsd` number
    - `avgCostUsd` number, nullable: Average cost per token of what is still held.
    - `lastPriceUsd` number, nullable: Last hourly print within 7 days.
    - `soldWithoutBasisUsd` number
  - `recent` object[]: Last 25 swaps, newest first.
    - `ts` integer: Unix time, seconds, UTC.
    - `tx` string: Transaction hash.
    - `logIndex` integer
    - `token` string: EVM address, hex, case-insensitive.
    - `side` 'buy' | 'sell'
    - `tokenAmt` number
    - `usd` number
    - `priceUsd` number
    - `dex` string
    - `symbol` string, nullable
  - `ingestFloor` IngestFloor: The tape's ingest floor. BNB Chain runs at $100 today; Avalanche and Base at 0.
    - `minTradeUsd` number: Trades under this USD value (at index time) are not in the index, so every count, volume and candle covers trades at or above it. 0 = every priced trade.
    - `history` object[]: Floors in force over time, oldest first. Empty when the chain was never floored. Raising a floor does not remove older, smaller rows.
      - `usd` number: Floor in force.
      - `fromTs` integer: Unix time, seconds, UTC.
  - `updatedAt` integer: Unix time, milliseconds — when the server built this answer.

## Other responses

- `400`: `UNSUPPORTED_CHAIN` (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or `BAD_ADDRESS`.
- `429`: Over the per-minute limit (`RATE_LIMIT_EXCEEDED`). Read `X-RateLimit-Reset` and back off.
- `503`: `CHAIN_DATA_UNAVAILABLE`: the store could not be read. Retry later; do not treat it as an empty answer.

---

[API](https://skmtc.dev/getchord/apis/chord-api.md) · [All operations](https://skmtc.dev/getchord/apis/chord-api/llms.txt) · [OpenAPI document](https://skmtc.dev/getchord/apis/chord-api/revisions/d3bc4640fea0?raw)
