Get ERC-20 token balances
https://api.triport.io/v1/eth/wallet/tokens/0x742d35Cc6634C0532925a3b844Bc9e7595f06b8b?include_zero=falseReturns every ERC-20 token balance held by an Ethereum address, with raw + UI-scaled amounts and token metadata.
Returns the list of ERC-20 tokens held by address, each entry carrying the
token's contract address, the raw on-chain balance (a u256 rendered as a decimal
string), its decimals, a convenience ui_balance already scaled by decimals,
and metadata (name, symbol, logo_uri) where known.
Use this to render a wallet's token portfolio in one request instead of issuing
an eth_call to balanceOf per contract. Balances reflect the latest observed
block at the time of the request.
By default, tokens with a zero balance are omitted. Pass include_zero=true to
include contracts the address has interacted with but currently holds none of —
useful for showing a full historical token set or for allowance UIs.
Gotcha:
balanceis a string because ERC-20 amounts are u256 and overflow JavaScript'sNumber. Do arithmetic onbalancewith a big-integer library; treatui_balance(adouble) as display-only and lossy for large values.
Parameters
Path parameters
addressstringrequired0x-prefixed, 40 hex chars (^0x[0-9a-fA-F]{40}$).Query parametersobjectinclude_zerobooleanoptionalfalse.Response
Response fields
| Field | Type | Description |
|---|---|---|
address | string | The queried address, echoed back. |
tokens | array | List of ERC-20 balance entries (see below). |
tokens[].contract | string | Token contract address. Required. |
tokens[].balance | string | Raw balance as a u256 decimal string. Required. |
tokens[].decimals | integer | Token decimals (0–36). Required. |
tokens[].ui_balance | number (double) | balance scaled by decimals; display-only, may lose precision. |
tokens[].name | string | Token name, where resolvable. |
tokens[].symbol | string | Token symbol, where resolvable. |
tokens[].logo_uri | string (uri) | Token logo URL, where available. |
Errors
| Code | error | Meaning | When it happens |
|---|---|---|---|
| 401 | unauthorized / trial_expired / subscription_expired | Auth failure | Missing/invalid key, ended trial, or lapsed subscription. |
| 403 | tier_insufficient | Tier too low | Key's tier is below basic. Response carries current_tier, required_tier, and the X-Required-Tier header. |
| 403 | method_unknown | Method not in product | The key's product does not include this endpoint. |
| 429 | rate_limited | RPS exceeded | Sustained request rate above the tier limit. Response carries retry_after_sec, limit_rps, current_tier, and the Retry-After / X-RateLimit-* headers. |
All errors share the standard envelope (error, message, request_id). See
errors.md for the full schema and per-code response shapes.
Example 403 (tier too low):
{
"error": "tier_insufficient",
"message": "This endpoint requires the basic tier or higher.",
"request_id": "req_8f3c2a1e",
"current_tier": "free",
"required_tier": "basic",
"category": "eth_wallet",
"method": "ethWalletTokens",
"upgrade_url": "https://triport.io/billing/upgrade"
}Examples
JavaScript (fetch)
const address = "0x742d35Cc6634C0532925a3b844Bc9e7595f06b8b";
const res = await fetch(
`https://api.triport.io/v1/eth/wallet/tokens/${address}?include_zero=false`,
{ headers: { Authorization: `Bearer ${process.env.TRIPORT_API_KEY}` } }
);
if (!res.ok) throw new Error(`${res.status} ${(await res.json()).error}`);
const { tokens } = await res.json();
for (const t of tokens) {
console.log(`${t.symbol}: ${t.ui_balance}`);
}TypeScript SDK (@triport/sdk)
import { Triport } from "@triport/sdk";
const client = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });
const { tokens } = await client.eth.wallet.tokens(
"0x742d35Cc6634C0532925a3b844Bc9e7595f06b8b",
{ includeZero: false }
);
tokens.forEach((t) => console.log(t.symbol, t.balance, t.decimals));Python (triport-sdk)
import os
from triport import Triport
client = Triport(api_key=os.environ["TRIPORT_API_KEY"])
result = client.eth.wallet.tokens(
"0x742d35Cc6634C0532925a3b844Bc9e7595f06b8b",
include_zero=False,
)
for t in result.tokens:
print(t.symbol, t.balance, t.decimals)Notes
- Zero balances: omitted unless
include_zero=true. With it set, entries withbalance == "0"are returned for every contract the address has touched. - Big numbers: compute against
balancewith a big-integer type (BigInt,int,decimal.Decimal);ui_balanceis convenience-only. - Metadata gaps:
name,symbol, andlogo_uriare best-effort and may be absent for obscure or unverified tokens; onlycontract,balance, anddecimalsare guaranteed. - Related endpoints: ETH balance for native ETH, NFT holdings for ERC-721/ERC-1155 (pro+), and transaction history.