Holdings and PnL on every chain
What one wallet holds on Chord's eight EVM chains, and on Solana when you pass its Solana address, with its PnL over the last 24 hours, 7 days and 30 days. One rule for every chain, per token and window: the USD from its sales minus the USD of its buys inside the window, plus what is held now at today's price, minus what was held at the window's start at that hour's close. No cost basis is involved, and transfers are neutral: a token that arrived by transfer only adds its price move, and a quantity bought in the window that left with no sale on the tape (sent, bridged out) counts as sold at the window's average buy price, neither a gain nor a loss. Stablecoins are left out of PnL and counted in cashUsd.
Use it for: a wallet or portfolio page, "how did this wallet do this week", an agent sizing a trade against what the wallet already holds.
Notes
- Coverage first. A window is complete only when the chain's swap tape covers all of it. When it does not (the tape starts later, a hole in the history), usd, pct and fromTs are null: show a dash, never a partial number as a whole one. A total window is complete only when every chain in the answer is, chains that could not be read included. BNB Chain does not record swaps under $100: its windows still count as complete, and coverage.ingestFloorUsd says so.
- Holdings = the chain's token list plus every token the wallet swapped in the last 30 days, read on-chain (Solana: its 50 largest holdings). A token with no price Chord trusts (no measured liquidity, not on the chain's board) has priceUsd: null, comes last and is in no total. Priced holdings under $0.01 are folded into dust.
- Each chain answers on its own deadline. One that cannot be read is status: "unavailable" with a reason inside the 200 and is left out of the totals' value; partial = the balances were read, part of the rest was not.
- Times are milliseconds in this answer (asOf, fromTs, tapeFromTs), unlike most of this API.
- Cache: kept 45 seconds per wallet, Solana address and chain set (10 seconds when a chain could not be read); a copy up to 10 minutes old may be served once while a refresh runs (asOf says when it was computed). fresh=1 recomputes, only for a request with an X-API-Key or an Ask session; otherwise it is ignored.
- Without an API key (or an Ask session): a cached answer is served to anyone. One IP may start at most 10 new reads every 10 minutes (this route and /activity together), and every such caller together a limited number a minute; past either the answer is 429 RATE_LIMITED or 503 BUSY with Retry-After, and nothing is read. Send an X-API-Key for more.
Request
- Base URL: https://api.getchord.xyz/v1
- URL: https://api.getchord.xyz/v1/portfolio/{wallet}
- Auth: none declared
Path parameters
EVM address, hex, case-insensitive.
Query parameters
Solana address, base58, case-sensitive. Never lower-case it.
The wallet's Solana address. Adds Solana to the default scope.
all = the eight EVM chains, plus Solana when sol is given. Or a comma list of chain ids (143, 4663, 5042, 43114, 8453, 56, 42161, 1) and solana (which needs sol). Answered in registry order, Solana last. This route does not read chain: chain=5042 on its own still answers for every chain, so send chains=5042 for Arc alone.
Recompute instead of serving the cached answer. Honoured only with an X-API-Key or an Ask session.
Response
Changes
No recorded changes to this operation across all 2 revisions of this API.