getTokenAccountsByOwner
Returns all SPL Token accounts by token owner.
Common use cases
| Display Wallet Token Portfolio | Fetch all SPL token accounts for a wallet to show token holdings in dApp UI. Use programId: TOKEN_PROGRAM_ID filter with jsonParsed encoding for automatic parsing. Returns account data including mint address, balance (amount and decimals), and owner for each token held. |
| Check Specific Token Balance | Query token accounts filtered by mint address to verify balance before swap or transfer. Common in trading bots and DeFi integrations that need to confirm sufficient token holdings. Faster than filtering all accounts client-side when you know the mint. |
| Track Token 2022 Holdings Separately | Use programId: TOKEN_2022_PROGRAM_ID filter to get Token Extensions Program accounts separately from legacy SPL tokens. Essential for dApps that need to handle Token 2022 features (transfer hooks, confidential transfers) differently from standard SPL tokens. |
| Wallet Cleanup and Migration | List all token accounts for wallet cleanup, dust removal, or account consolidation. Iterate results to identify empty accounts (zero balance) that can be closed to reclaim rent (0.00203928 SOL per account). Common in wallet migration tools and portfolio optimizers. |
Parameters
pubkey (string, required)
Pubkey of account owner to query, as base-58 encoded string
config (object, required)
A JSON object with one of the following fields:
Fields:
mint(string): Pubkey of the specific token Mint to limit accounts to, as base-58 encoded string
options (object, optional)
Configuration object containing the following fields:
Fields:
commitment(string): The commitment describes how finalized a block is at that point in time. See Configuring State Commitment.minContextSlot(number): The minimum slot that the request can be evaluated atdataSlice(object): Request a slice of the account's data.length: <usize>- number of bytes to returnoffset: <usize>- byte offset from which to start reading Data slicing is only available forbase58,base64, orbase64+zstdencodings.
encoding(string): Encoding format for Account database58is slow and limited to less than 129 bytes of Account data.base64will return base64 encoded data for Account data of any size.base64+zstdcompresses the Account data using Zstandard and base64-encodes the result.binary(⚠️ deprecated) is similar tobase58, except data will be a base58-encoded string and not an array that includes the encoding.jsonParsedencoding attempts to use program-specific state parsers to return more human-readable and explicit account state data.- If
jsonParsedis requested but a parser cannot be found, the field falls back tobase64encoding, detectable when thedatafield is typestring.
Request
- cURL
- JavaScript
- Python
curl https://solana-mainnet.api.syndica.io/api-key/YOUR_API_KEY \
-X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getTokenAccountsByOwner",
"params": [
"A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd",
{
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
},
{
"commitment": "finalized",
"encoding": "jsonParsed"
}
]
}'
// Using fetch
const response = await fetch('https://solana-mainnet.api.syndica.io/api-key/YOUR_API_KEY', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
"jsonrpc": "2.0",
"id": 1,
"method": "getTokenAccountsByOwner",
"params": [
"A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd",
{
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
},
{
"commitment": "finalized",
"encoding": "jsonParsed"
}
]
})
});
const data = await response.json();
console.log(data);
import requests
import json
url = 'https://solana-mainnet.api.syndica.io/api-key/YOUR_API_KEY'
headers = {'Content-Type': 'application/json'}
data = {
"jsonrpc": "2.0",
"id": 1,
"method": "getTokenAccountsByOwner",
"params": [
"A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd",
{
"programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"
},
{
"commitment": "finalized",
"encoding": "jsonParsed"
}
]
}
response = requests.post(url, headers=headers, data=json.dumps(data))
print(response.json())
Replace mainnet with devnet in the URL to query devnet instead.
Response
{
"jsonrpc": "2.0",
"result": {
"context": { "apiVersion": "2.0.15", "slot": 341197933 },
"value": [
{
"pubkey": "BGocb4GEpbTFm8UFV2VsDSaBXHELPfAXrvd4vtt8QWrA",
"account": {
"data": {
"program": "spl-token",
"parsed": {
"info": {
"isNative": false,
"mint": "2cHr7QS3xfuSV8wdxo3ztuF4xbiarF6Nrgx3qpx3HzXR",
"owner": "A1TMhSGzQxMr1TboBKtgixKz1sS6REASMxPo1qsyTSJd",
"state": "initialized",
"tokenAmount": {
"amount": "420000000000000",
"decimals": 6,
"uiAmount": 420000000.0,
"uiAmountString": "420000000"
}
},
"type": "account"
},
"space": 165
},
"executable": false,
"lamports": 2039280,
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"rentEpoch": 18446744073709551615,
"space": 165
}
}
]
},
"id": 1
}
Response Fields
Return value: array
An array of JSON objects containing:
FAQ and Troubleshooting
Why does getTokenAccountsByOwner hang or timeout?
Requires --account-index spl-token-owner flag on the RPC node. Without this index (which needs >100GB RAM), requests scan the entire ledger and hang. Not all RPC providers enable this index. Switch to a provider with account indexing enabled if experiencing timeouts.
What's the difference between mint and programId filter?
mint filter returns accounts for ONE specific token (e.g., USDC mint). programId filter (TOKEN_PROGRAM_ID or TOKEN_2022_PROGRAM_ID) returns ALL token accounts for the owner. You must provide exactly one filter - cannot use both simultaneously, and cannot omit both.
Does jsonParsed encoding always work for token accounts?
Yes. The RPC node always knows how to parse SPL token account structures, so jsonParsed never falls back to base64 encoding like it might for custom program accounts. Use jsonParsed for automatic parsing of mint, owner, amount, and delegate fields.
How do I get balances for all tokens in a wallet?
Call getTokenAccountsByOwner with programId: TOKEN_PROGRAM_ID filter and jsonParsed encoding. Each result includes uiAmount (human-readable with decimals) and amount (raw integer) fields. For Token 2022 accounts, make separate call with programId: TOKEN_2022_PROGRAM_ID.
What's the difference from getTokenAccountsByDelegate?
getTokenAccountsByOwner returns accounts owned by a wallet. getTokenAccountsByDelegate returns accounts where a wallet has been delegated authority (like for staking or escrow). Use getTokenAccountsByDelegate when checking delegated permissions, not ownership. Same filter and encoding options apply to both.
Related Methods
getTokenAccountBalance
Returns balance for a single token account. Use after getTokenAccountsByOwner identifies specific account pubkeys to refresh individual balances without rescanning all accounts. Both methods require same --account-index spl-token-owner flag on RPC node.
getProgramAccounts
Returns all accounts for a program with filtering. Alternative to getTokenAccountsByOwner when you need accounts matching complex filters beyond owner (e.g., filtering by specific delegate). Slower and requires account-index flags, but more flexible filtering options.
getAccountInfo
Returns raw account data for any account type. Use when you need non-token account details or want to manually parse token account data instead of using jsonParsed encoding. Requires knowing specific account pubkey (can get from getTokenAccountsByOwner).
getTokenAccountsByDelegate
Returns token accounts by delegate authority instead of owner. Related method for checking delegated token accounts (like staked tokens, escrow accounts) rather than owned accounts. Same filter types (mint or programId) and encoding options as getTokenAccountsByOwner.
getTokenSupply
Returns total supply for a token mint. Pair with getTokenAccountsByOwner when analyzing holder distribution or calculating percentage ownership. Essential for token concentration metrics and whale tracking analysis.
External Resources
- Solana Official Documentation
- SPL Token Program Documentation - Comprehensive guide to SPL Token Program including account structure and token account relationships. Essential for understanding parsed token account data fields (mint, owner, amount, delegate, closeAuthority) returned by getTokenAccountsByOwner with jsonParsed encoding.
- Setup an RPC Node: Account Indexing - Official documentation on
--account-indexflags includingspl-token-ownerrequirement for getTokenAccountsByOwner. Critical for self-hosted RPC nodes - explains RAM requirements (>100GB) and performance implications. Without this index, method hangs or times out.