Build an enriched NFT profile feed
An enriched profile is a composition, not a single endpoint:
- Load current holdings with
GET /v1/owners/{address}/nfts. - Deduplicate
collection_address, then fetch each collection once. - Fetch transfer history only for the visible tokens that need a timeline.
- Prefer
media_url, then fall back toimage_url.
OWNER=0x0000000000000000000000000000000000000002curl -sS -H "Authorization: Bearer $ARADIA_API_TOKEN" \ "https://api.aradia.app/v1/owners/$OWNER/nfts?limit=100"const base = "https://api.aradia.app/v1";const headers = { Authorization: `Bearer ${process.env.ARADIA_API_TOKEN}` };
async function enrichedProfile(owner) { const holdingsResponse = await fetch(`${base}/owners/${owner}/nfts?limit=100`, { headers }); if (!holdingsResponse.ok) throw new Error(`Holdings failed: ${holdingsResponse.status}`); const holdings = await holdingsResponse.json();
const addresses = [...new Set(holdings.data.map((nft) => nft.collection_address))]; const collections = await Promise.all(addresses.map(async (address) => { const response = await fetch(`${base}/collections/${address}`, { headers }); if (!response.ok) throw new Error(`Collection failed: ${response.status}`); return (await response.json()).data; })); const byAddress = new Map(collections.map((item) => [item.contract_address, item]));
const items = holdings.data.map((nft) => ({ ...nft, artwork: nft.media_url ?? nft.image_url, collection: byAddress.get(nft.collection_address), })); return { items, coverage: holdings.coverage };}import osimport requests
base = "https://api.aradia.app/v1"headers = {"Authorization": f"Bearer {os.environ['ARADIA_API_TOKEN']}"}
def enriched_profile(owner): holdings = requests.get(f"{base}/owners/{owner}/nfts", params={"limit": 100}, headers=headers, timeout=30) holdings.raise_for_status() page = holdings.json() addresses = sorted({nft["collection_address"] for nft in page["data"]}) collections = {} for address in addresses: response = requests.get(f"{base}/collections/{address}", headers=headers, timeout=30) response.raise_for_status() collections[address] = response.json()["data"] return [ {**nft, "artwork": nft.get("media_url") or nft.get("image_url"), "collection": collections[nft["collection_address"]]} for nft in page["data"] ]Keep the request count bounded
Section titled “Keep the request count bounded”Do not request collection details once per NFT. Forty NFTs from six collections require six detail requests, not forty. Fetch transfer history only when a token is visible or its timeline is opened.
For a chronological profile feed, merge the selected transfer arrays by block_timestamp and deduplicate with transaction_hash plus log_index.
