Get a portfolio for a single Ethereum address with every balance and price pinned to a specific historical block, instead of the current state.
The Portfolio at Block endpoint is an add-on , billed at a set monthly fee separate from your API credit pool, plus 1 credit per call. Contact sales to enable Portfolio at Block access for your account.
Cost: Set monthly fee under the Portfolio at Block add-on, plus 1 credit per call.
Rate limit: 100 requests/min, on a dedicated bucket (does not count against your portfolio rate limit).
Endpoint
GET https://api.octav.fi/v1/portfolio/at-block
Parameters
A single EVM wallet address to retrieve portfolio data for. Only one address is accepted per call. addresses=0x6426af179aabebe47666f345d69fd9079673f6cd
The chain the block belongs to. Currently only ethereum is supported.
The block number to value the portfolio at. Must be a positive integer.
Response
Returns the same Portfolio shape, with every asset balance and price valued as of blockNumber, plus a top-level blockNumber field. This endpoint does not accept includeImages, includeExplorerUrls, or includeNFTs — image, explorer URL, and NFT fields are never included in the response.
The block number the portfolio was valued at (echoes the blockNumber query parameter, returned as a string)
Total portfolio net worth in USD, valued at blockNumber
Available cash balance at blockNumber
Assets organized by protocol (wallet, lending, staking, etc.), keyed by protocol identifier — same structure as the Portfolio endpoint, valued at blockNumber.
Per-chain totals, keyed by chain identifier — only ethereum is present, since block-pinning is Ethereum-only.
Example Request
cURL
JavaScript
Python
TypeScript
curl -X GET "https://api.octav.fi/v1/portfolio/at-block?addresses=0x6426af179aabebe47666f345d69fd9079673f6cd&chainKey=ethereum&blockNumber=19000000" \
-H "Authorization: Bearer YOUR_API_KEY"
Example Response
{
"address" : "0x6426af179aabebe47666f345d69fd9079673f6cd" ,
"cashBalance" : "0" ,
"blockNumber" : "19000000" ,
"networth" : "24962.30" ,
"assetByProtocols" : {
"wallet" : {
"name" : "Wallet" ,
"key" : "wallet" ,
"value" : "24962.30" ,
"chains" : {
"ethereum" : {
"name" : "Ethereum" ,
"key" : "ethereum" ,
"value" : "24962.30" ,
"protocolPositions" : {
"WALLET" : {
"name" : "wallet" ,
"assets" : [
{
"balance" : "5.5" ,
"symbol" : "eth" ,
"name" : "ethereum" ,
"price" : "3200.50" ,
"value" : "17602.75" ,
"decimal" : "18" ,
"contract" : "0x0000000000000000000000000000000000000000" ,
"chainKey" : "ethereum" ,
"chainContract" : "ethereum:0x0000000000000000000000000000000000000000"
},
{
"balance" : "7359.55" ,
"symbol" : "usdc" ,
"name" : "usd coin" ,
"price" : "1.00" ,
"value" : "7359.55" ,
"decimal" : "6" ,
"contract" : "0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48" ,
"chainKey" : "ethereum" ,
"chainContract" : "ethereum:0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48"
}
],
"protocolPositions" : [],
"totalValue" : "24962.30" ,
"unlockAt" : "0"
}
}
}
}
}
},
"chains" : {
"ethereum" : {
"name" : "Ethereum" ,
"key" : "ethereum" ,
"chainId" : "1" ,
"value" : "24962.30" ,
"valuePercentile" : "100" ,
"totalCostBasis" : "N/A" ,
"totalClosedPnl" : "N/A" ,
"totalOpenPnl" : "N/A"
}
}
}
Use Cases
Point-in-Time Valuation
Compare Blocks
Value a wallet exactly as it stood at a known block — useful for tax lot reconstruction, snapshot audits, or governance-vote eligibility checks: async function getPortfolioAtBlock ( address , blockNumber ) {
const response = await fetch (
`https://api.octav.fi/v1/portfolio/at-block?addresses= ${ address } &chainKey=ethereum&blockNumber= ${ blockNumber } ` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }
);
return response . json ();
}
const snapshot = await getPortfolioAtBlock ( '0x6426af...' , 19000000 );
console . log ( `Net worth at block ${ snapshot . blockNumber } : $ ${ snapshot . networth } ` );
Diff net worth across two blocks (e.g. before/after a known event): const [ before , after ] = await Promise . all ([
fetch ( `https://api.octav.fi/v1/portfolio/at-block?addresses= ${ address } &chainKey=ethereum&blockNumber=19000000` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }). then ( r => r . json ()),
fetch ( `https://api.octav.fi/v1/portfolio/at-block?addresses= ${ address } &chainKey=ethereum&blockNumber=19100000` ,
{ headers: { 'Authorization' : `Bearer ${ apiKey } ` } }). then ( r => r . json ())
]);
const change = parseFloat ( after . networth ) - parseFloat ( before . networth );
console . log ( `Change between blocks: $ ${ change . toFixed ( 2 ) } ` );
Error Responses
Input validation failed (Joi structured error). {
"error" : "Validation Failed" ,
"details" : {
"query" : [
{
"message" : " \" chainKey \" must be one of [ethereum]" ,
"path" : [ "chainKey" ],
"type" : "any.only"
}
]
}
}
Common causes:
Missing addresses, chainKey, or blockNumber
chainKey is not ethereum (the only currently supported chain)
blockNumber is not a positive integer
addresses is not a single valid EVM address
Missing/invalid API key, or your key does not have the Portfolio at Block add-on enabled. {
"message" : "Unauthorized"
}
Solution: Check your API key in the Authorization header. If the key is valid, contact sales to enable the Portfolio at Block add-on.
Rate limit exceeded (100 requests/min on this endpoint’s dedicated bucket). {
"error" : "Rate limit exceeded" ,
"message" : "You have exceeded your rate limit" ,
"retry_after" : 60
}
Solution: Wait for the specified time or implement retry logic.
Insufficient credits. {
"error" : "Insufficient credits" ,
"message" : "Please purchase more credits to continue"
}
Solution: Purchase more credits at data.octav.fi
500 Internal Server Error
Upstream failure fetching Portfolio at Block data. Error fetching block-pinned portfolio information
Portfolio Current portfolio state
Historical Portfolio Portfolio snapshot for a specific calendar date
Chains List all supported blockchain networks
Status Check when portfolio was last synced