Skip to content

One wallet's swaps and PnL

GET
/chains/{chain}/wallet/{address}
curl --request GET \
--url https://api.getchord.xyz/v1/chains/avalanche/wallet/example

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”.
chain
required
string
Allowed values: avalanche base bnb arbitrum ethereum 43114 8453 56 42161 1

The chain, by key or id: avalanche or 43114, base or 8453, bnb or 56, arbitrum or 42161, ethereum or 1 (case-insensitive). Arc, Robinhood Chain and Monad are refused with 400 UNSUPPORTED_CHAIN and a pointer to their own routes.

address
required

EVM address, hex, case-insensitive.

string
/^0x[a-fA-F0-9]{40}$/

Wallet address.

Media typeapplication/json
object
chain
integer
wallet

EVM address, hex, case-insensitive.

string
/^0x[a-fA-F0-9]{40}$/
window

The span the numbers cover. fromTs null = no trades indexed for the wallet.

object
fromTs

Unix time, seconds, UTC.

integer | null
toTs

Unix time, seconds, UTC.

integer
days
integer | null
history

Where the window’s rows came from.

string
Allowed values: raw raw+lake raw (lake unavailable)
trades

Swaps in the window.

integer
truncated

More than 5,000 swaps in the window: only the newest 5,000 are counted.

boolean
realizedUsd
number
unrealizedUsd
number
totalUsd
number
volumeUsd
number
soldWithoutBasisUsd

Sell proceeds with no buy in the window to match. Not profit.

number
tokens

Largest absolute PnL first.

Array<object>
object
token

EVM address, hex, case-insensitive.

string
/^0x[a-fA-F0-9]{40}$/
symbol
string | null
buys
integer
sells
integer
boughtUsd
number
soldUsd
number
realizedUsd
number
unrealizedUsd
number
totalUsd
number
holdsTokens

Bought minus sold in the window, whole tokens.

number
holdsUsd
number
avgCostUsd

Average cost per token of what is still held.

number | null
lastPriceUsd

Last hourly print within 7 days.

number | null
soldWithoutBasisUsd
number
recent

Last 25 swaps, newest first.

Array<object>
object
ts

Unix time, seconds, UTC.

integer
tx

Transaction hash.

string
/^0x[a-fA-F0-9]{64}$/
logIndex
integer
token

EVM address, hex, case-insensitive.

string
/^0x[a-fA-F0-9]{40}$/
side
string
Allowed values: buy sell
tokenAmt
number
usd
number
priceUsd
number
dex
string
symbol
string | null
ingestFloor

The tape’s ingest floor. BNB Chain runs at $100 today; Avalanche and Base at 0.

object
minTradeUsd

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.

number
history

Floors in force over time, oldest first. Empty when the chain was never floored. Raising a floor does not remove older, smaller rows.

Array<object>
object
usd

Floor in force.

number
fromTs

Unix time, seconds, UTC.

integer
updatedAt

Unix time, milliseconds — when the server built this answer.

integer
Example
{
"chain": 56,
"wallet": "0x34135a8b5cc02d1b579789fb09dd9cec4f8d7c13",
"window": {
"fromTs": 1790726400,
"toTs": 1791021452,
"days": 3
},
"history": "raw",
"trades": 438,
"truncated": false,
"realizedUsd": -52.50256178614943,
"unrealizedUsd": 264.3511103300407,
"totalUsd": 211.84854854389124,
"volumeUsd": 1074760.992352269,
"soldWithoutBasisUsd": 142196.1744304485,
"tokens": [
{
"token": "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c",
"symbol": "BTCB",
"buys": 82,
"sells": 88,
"boughtUsd": 232801.99929077973,
"soldUsd": 268637.2602480728,
"realizedUsd": 332.35056120683566,
"unrealizedUsd": 322.78762778211967,
"totalUsd": 655.1381889889553,
"holdsTokens": 0.48237177905003725,
"holdsUsd": 40925.42133609123,
"avgCostUsd": 84172.90453490094,
"lastPriceUsd": 84842.07226361385,
"soldWithoutBasisUsd": 76105.54410439507
},
{
"token": "0x2170ed0880ac9a755fd29b2688956bd959f933f8",
"symbol": "ETH",
"buys": 92,
"sells": 96,
"boughtUsd": 179038.3807585184,
"soldUsd": 167683.46997452437,
"realizedUsd": -421.56179009490035,
"unrealizedUsd": -58.43651745207899,
"totalUsd": -479.99830754697933,
"holdsTokens": 14.799424875074559,
"holdsUsd": 39691.36613138376,
"avgCostUsd": 2685.901849860607,
"lastPriceUsd": 2681.9532830787653,
"soldWithoutBasisUsd": 28816.45365493667
}
],
"recent": [
{
"ts": 1791021243,
"tx": "0xfacfd422253d675c6f886afffeb849d5a4f50c38cb0a3a5979b73473dd5b4273",
"logIndex": 31,
"token": "0x7130d2a12b9bcbfae4f2634d864a1ee1ce3ead9c",
"side": "buy",
"tokenAmt": 0.007796979293366881,
"usd": 661.4196898072091,
"priceUsd": 84830.24834629204,
"dex": "pancake_v3",
"symbol": "BTCB"
},
{
"ts": 1791016125,
"tx": "0x06ac8ef3af4d007c08c7a9ca9e7ab666a724e1393c21865fe1d70d7c5825c19b",
"logIndex": 76,
"token": "0x2170ed0880ac9a755fd29b2688956bd959f933f8",
"side": "sell",
"tokenAmt": 0.1525057769098823,
"usd": 408.73262726748277,
"priceUsd": 2680.1124229478096,
"dex": "pancake_v3",
"symbol": "ETH"
}
],
"ingestFloor": {
"minTradeUsd": 100,
"history": [
{
"usd": 100,
"fromTs": 1790789196
}
]
},
"updatedAt": 1791021452229
}

UNSUPPORTED_CHAIN (unknown chain, a chain with its own routes, or a chain not served to this caller yet), or BAD_ADDRESS.

Media typeapplication/json

Every non-2xx body.

object
error
required

Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.

string
message

For humans.

string
statusCode

HTTP status, when included.

integer
Example
{
"error": "INVALID_PARAMS",
"message": "amount must be an integer string in the token's smallest unit"
}

Over the per-minute limit (RATE_LIMIT_EXCEEDED). Read X-RateLimit-Reset and back off.

Media typeapplication/json

Every non-2xx body.

object
error
required

Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.

string
message

For humans.

string
statusCode

HTTP status, when included.

integer
Example
{
"error": "INVALID_PARAMS",
"message": "amount must be an integer string in the token's smallest unit"
}

CHAIN_DATA_UNAVAILABLE: the store could not be read. Retry later; do not treat it as an empty answer.

Media typeapplication/json

Every non-2xx body.

object
error
required

Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.

string
message

For humans.

string
statusCode

HTTP status, when included.

integer
Example
{
"error": "INVALID_PARAMS",
"message": "amount must be an integer string in the token's smallest unit"
}