getProgramAccounts
Returns all accounts owned by the provided program Pubkey
Common use cases
| Enumerate token holders | Query SPL Token program with mint filter to find all holders of a specific token. Use filters: [{"dataSize": 165}, {"memcmp": {"offset": 0, "bytes": "mintAddress"}}] to narrow results to accounts matching the token mint. Combine with dataSlice for efficient counting without fetching full data. |
| Index custom program accounts | Retrieve all accounts owned by your custom program for monitoring and discovery. Essential for building indexers, explorers, or dashboards showing program state. Use dataSize filter matching your account structure, plus memcmp on discriminator fields to isolate specific account types. |
| Count without fetching data | Use dataSlice {"offset": 0, "length": 0} to get only account pubkeys without data, drastically reducing response size and bandwidth. Perfect for counting token holders, active accounts, or program usage without processing full account contents. |
| Structure-based account filtering | Combine dataSize + memcmp filters to find accounts matching specific data layout or discriminator values. Example: find all token accounts owned by specific wallet with dataSize: 165 and memcmp: {"offset": 32, "bytes": "walletAddress"} (owner is at offset 32). |
| Scan large account sets | Paginate through large account collections by varying filter combinations since getProgramAccounts lacks native pagination. Split queries by mint ranges, owner prefixes, or discriminator values to chunk results under 10MB response limit. |
Parameters
pubkey (string, required)
Pubkey of program, as base-58 encoded string
config (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 atwithContext(bool): Wrap the result in an RpcResponse JSON objectencoding(string): Encoding format for the returned 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 type<string>.
dataSlice(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.
filters(array): Filter results using up to 4 filter objects. See Filtering. The resultant account(s) must meet ALL filter criteria to be included in the returned results
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": "getProgramAccounts",
"params": [
"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T",
{
"commitment": "finalized",
"filters": [
{ "dataSize": 17 },
{
"memcmp": {
"offset": 4,
"bytes": "3Mc6vR"
}
}
]
}
]
}'
// 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": "getProgramAccounts",
"params": [
"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T",
{
"commitment": "finalized",
"filters": [
{ "dataSize": 17 },
{
"memcmp": {
"offset": 4,
"bytes": "3Mc6vR"
}
}
]
}
]
})
});
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": "getProgramAccounts",
"params": [
"4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T",
{
"commitment": "finalized",
"filters": [
{ "dataSize": 17 },
{
"memcmp": {
"offset": 4,
"bytes": "3Mc6vR"
}
}
]
}
]
}
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": [
{
"pubkey": "CxELquR1gPP8wHe33gZ4QxqGB3sZ9RSwsJ2KshVewkFY",
"account": {
"data": "2R9jLfiAQ9bgdcw6h8s44439",
"executable": false,
"lamports": 15298080,
"owner": "4Nd1mBQtrMJVYVfKf2PJy9NZUZdTAsp7D4xWLs4gDB4T",
"rentEpoch": 28,
"space": 42
}
}
],
"id": 1
}
Response Fields
Return value: array
By default, returns an array of JSON objects. If withContext flag is set, the array will be wrapped in an RpcResponse JSON object. Each object contains:
FAQ and Troubleshooting
Why does my getProgramAccounts call timeout or return incomplete data?
Response exceeds 10MB limit or query scans too many accounts. Solution: Add filters (dataSize + memcmp) to narrow scope, use dataSlice to limit returned data per account, or chunk queries by different filter combinations. Avoid calling without filters on programs with thousands of accounts.
How do I find all token accounts for a specific mint?
Use filters: [{"dataSize": 165}, {"memcmp": {"offset": 0, "bytes": "mintAddress"}}]. Token accounts are always 165 bytes. The mint field is the first 32 bytes (offset 0). For owner-based queries, use offset 32 instead. Requires --account-index spl-token-owner and --account-index spl-token-mint flags on RPC node.
What's the difference between offset in memcmp vs dataSlice?
memcmp offset is where to compare bytes in account data for filtering which accounts to return. dataSlice offset is where to start returning data from each account to reduce response size. Different purposes: memcmp filters which accounts match, dataSlice limits how much data per account is sent back.
Does getProgramAccounts support pagination?
No native pagination support. Workarounds: (1) Use different filter combinations to chunk results (query by different mints, owner ranges), (2) Use dataSlice {"length": 0} to get all pubkeys first, then batch fetch with getMultipleAccounts, (3) Consider using an indexer service for large-scale pagination needs.
When is --account-index required on RPC nodes?
Required when filtering SPL Token accounts by owner (memcmp offset 32) or mint (memcmp offset 0). Specifically needs --account-index spl-token-owner and/or --account-index spl-token-mint flags. Not needed for dataSize-only filters or non-token programs. Public RPC providers may not have these indexes enabled.
Related Methods
getMultipleAccounts
Fetch specific accounts by pubkey array. Common pattern: use getProgramAccounts with dataSlice {"length": 0} to get all addresses first, then batch fetch full data with getMultipleAccounts (100 per call) to avoid getProgramAccounts response size limits.
getAccountInfo
Get single account data by pubkey. Use when you know specific address; use getProgramAccounts when discovering accounts by program ownership. getProgramAccounts is for scanning/discovery, getAccountInfo is for fetching known accounts.
getTokenAccountsByOwner
Find SPL token accounts by wallet owner with simpler interface. Specialized version of getProgramAccounts pre-configured for TOKEN_PROGRAM_ID with owner filter. Use this instead of manually constructing getProgramAccounts filters for token queries.
getTokenAccountsByDelegate
Find delegated token accounts. Similar to getTokenAccountsByOwner but filters on delegate field (offset 72) instead of owner field (offset 32). Both are specialized getProgramAccounts wrappers for common token program queries.
accountSubscribe (WebSocket)
Subscribe to real-time account updates. Common pattern: use getProgramAccounts for initial account snapshot/discovery, then accountSubscribe to individual discovered accounts for live changes instead of re-polling getProgramAccounts.
External Resources
- Solana Official Documentation
- Solana Cookbook: Get Program Accounts Guide - Comprehensive tutorial with filter examples, dataSlice usage, and visual diagrams of token account layout for calculating offsets. Includes working code examples for TypeScript and Rust.