Realized and open PnL per token
const url = 'https://api.getchord.xyz/v1/portfolio/example/pnl?chain=5042';const options = {method: 'GET'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request GET \ --url 'https://api.getchord.xyz/v1/portfolio/example/pnl?chain=5042'Average-cost PnL for one wallet from the tape: realized on sells, unrealized on what is still held at current prices, ROI, and the untracked balance that arrived by transfer (no cost basis, excluded from PnL). Cached with stale-while-revalidate (a day-old answer beats a $0 skeleton).
Portfolio routes answer an empty 200 shape rather than a 5xx when the tape read fails — treat an empty tokens list as “nothing yet” and retry later.
Parameters
Section titled “ Parameters ”Path Parameters
Section titled “Path Parameters”EVM address, hex, case-insensitive.
Query Parameters
Section titled “Query Parameters”One chain, or all to merge chains with a byChain breakdown.
Responses
Section titled “ Responses ”object
object
EVM address, hex, case-insensitive.
Average cost per token, USD.
Balance that arrived by transfer (no cost basis).
Present when bought quantity left the wallet with no sale on the tape (a transfer out, or a sale credited to another address): {tokens, costUsd, top: [{symbol, costUsd}]}. Its result is unknown and NOT in the PnL above.
object
Only with chain=all.
object
Unix time, milliseconds — when the server built this answer.
Example
{ "tokens": [ { "token": "0xece5ca8bf9220718e5727754026757512212cb3c", "symbol": "ARGUS", "logo": "https://coin-images.coingecko.com/coins/images/102178392/large/argus-token.png?1789463380", "realizedUsd": 30462.864779627198, "unrealizedUsd": 11700.939232721703, "totalUsd": 42163.804012348905, "costRemaining": 1286.137220108177, "curValue": 12987.07645282988, "curAmount": 744055.9147763874, "avgCost": 0.0017285491514366933, "roiPct": 909.7737822825419, "untrackedAmount": 0, "untrackedValue": 0 }, { "token": "0x66927743a8a841ca09575a4ccdcd090c761adcec", "symbol": "HYCI", "logo": "https://ipfs.filebase.io/ipfs/bafybeiezh2g4uhqy2bzdq4elwkzek55q5ccs4gpyyki672a4i3olf3u224", "realizedUsd": 181.713005, "unrealizedUsd": 0, "totalUsd": 181.713005, "costRemaining": 0, "curValue": 0, "curAmount": 0, "avgCost": 0.000042576384935211256, "roiPct": null, "untrackedAmount": 0, "untrackedValue": 0 } ], "realized": 30488.101882774274, "unrealized": 11700.939232721703, "total": 42189.04111549597, "updatedAt": 1789809277093}Invalid parameters — error names the check that failed (INVALID_PARAMS, BAD_ADDRESS, BAD_LIMIT, BAD_HOURS, …).
Every non-2xx body.
object
Stable machine code, e.g. INVALID_PARAMS, NOT_READY, RATE_LIMIT_EXCEEDED.
For humans.
HTTP status, when included.
Example
{ "error": "INVALID_PARAMS", "message": "amount must be an integer string in the token's smallest unit"}