TriportRPC

List NFTs on a wallet (cNFT + Metaplex)

GEThttps://api.triport.io/v1/sol/wallet/nfts/So11111111111111111111111111111111111111112?limit=50&offset=0

Returns the NFTs held by a Solana wallet — both compressed NFTs (cNFTs) and regular Metaplex assets — as a paginated list of asset summaries.

Solanasol_dasbasic and up (RPS-per-tier with burst; see [Rate limits](../../rate-limits.md))

Lists the NFTs owned by a single Solana wallet. The endpoint resolves both compressed NFTs (cNFTs) and regular Metaplex assets in one call, so you do not need to query the two asset models separately — each item carries a compressed flag telling you which it is.

Results are paginated with limit / offset. Each entry is a lightweight asset summary (id, name, symbol, image, collection) suitable for rendering a wallet gallery; it is not the full on-chain metadata document.

This is a digital-asset-indexing call, which is more expensive than a plain balance read, so it requires the basic tier (or higher) and the sol_das scope. For native SOL balance use GET /v1/sol/wallet/balance/{address}; for SPL fungible tokens use GET /v1/sol/wallet/tokens/{address}.

Parameters

Path parameters

addressstringrequired
Solana base58 pubkey (32 bytes). Pattern ^[1-9A-HJ-NP-Za-km-z]+$, length 32–44.
Query parametersobject
limitintegeroptional
Page size. Min 1, max 1000, default 50.
offsetintegeroptional
Number of assets to skip before the page. Min 0, default 0.

Response

Response fields

FieldTypeDescription
addressstringThe wallet that was queried (echoes the path parameter).
assetsarrayPage of asset summaries owned by the wallet.
assets[].idstringAsset id — the mint for a regular Metaplex asset, or the leaf id for a cNFT.
assets[].compressedbooleantrue for a compressed NFT (cNFT), false for a regular Metaplex asset.
assets[].namestringAsset display name.
assets[].symbolstringAsset symbol.
assets[].imagestring (uri)URI of the asset image.
assets[].collectionstringCollection id the asset belongs to.
pagination.limitintegerPage size that was applied.
pagination.offsetintegerOffset that was applied.
pagination.totalintegerTotal assets available; may be absent when it is expensive to compute.

Only id is guaranteed on every asset; name, symbol, image, and collection are present when the indexer has resolved that metadata.

Errors

CodeMeaningWhen it happens
401unauthorized / trial_expired / subscription_expiredMissing or invalid key, or the account's trial/subscription has lapsed.
403tier_insufficient / method_unknownKey is below the basic tier or lacks the sol_das scope.
429rate_limitedSustained RPS for the tier exceeded; honor the Retry-After header.

All errors use the shared error envelope (error, message, request_id). A 429 also returns retry_after_sec, limit_rps, current_tier, and the Retry-After / X-RateLimit-* headers. See Errors for the full envelope and per-code fields.

Examples

JavaScript (fetch)

const address = "So11111111111111111111111111111111111111112";
const url = new URL(`https://api.triport.io/v1/sol/wallet/nfts/${address}`);
url.searchParams.set("limit", "50");
url.searchParams.set("offset", "0");


const res = await fetch(url, {
  headers: {
    Authorization: `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
});
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);


const { assets, pagination } = await res.json();
for (const a of assets) {
  console.log(a.compressed ? "cNFT" : "NFT", a.name, a.id);
}

TypeScript SDK (@triport/sdk)

import { Triport } from "@triport/sdk";


const triport = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });


const page = await triport.sol.wallet.nfts(
  "So11111111111111111111111111111111111111112",
  { limit: 50, offset: 0 }
);


console.log(`${page.assets.length} assets (total ${page.pagination.total})`);

Python (triport-sdk)

import os
from triport import Triport


client = Triport(api_key=os.environ["TRIPORT_API_KEY"])


page = client.sol.wallet.nfts(
    "So11111111111111111111111111111111111111112",
    limit=50,
    offset=0,
)


for asset in page.assets:
    kind = "cNFT" if asset.compressed else "NFT"
    print(kind, asset.name, asset.id)

Notes

  • Pagination. Walk pages by increasing offset in steps of limit until a page returns fewer than limit assets (or assets is empty). pagination.total is best-effort and may be omitted when counting is expensive — do not rely on it as the sole stop condition.
  • Compressed vs regular. Branch on assets[].compressed rather than inferring the asset model from the id; id is a mint for regular assets and a leaf id for cNFTs.
  • Related endpoints: SOL balance, SPL tokens, transaction history.