POST
/
getProgramAccountsV2
curl --request POST \
  --url https://mainnet.helius-rpc.com/ \
  --header 'Content-Type: application/json' \
  --data '{
  "jsonrpc": "2.0",
  "id": "1",
  "method": "getProgramAccountsV2",
  "params": [
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    {
      "encoding": "base64",
      "limit": 1000
    }
  ]
}'
{
  "jsonrpc": "2.0",
  "id": "1",
  "result": {
    "accounts": [
      {
        "pubkey": "CxELquR1gPP8wHe33gZ4QxqGB3sZ9RSwsJ2KshVewkFY",
        "account": {
          "lamports": 15298080,
          "owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
          "data": [
            "2R9jLfiAQ9bgdcw6h8s44439",
            "base64"
          ],
          "executable": false,
          "rentEpoch": 28,
          "space": 165
        }
      }
    ],
    "paginationKey": "8WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
    "totalResults": 25000
  }
}
Beta release: Please note getProgramAccountsV2 is available for early use. Contact support to report any issues you experience.

Overview

getProgramAccountsV2 is an enhanced version of the standard getProgramAccounts method, designed for applications that need to efficiently query large sets of accounts owned by specific Solana programs. This method introduces cursor-based pagination and incremental update capabilities.
New Features in V2:
  • Cursor-based pagination: Configure limits from 1 to 10,000 accounts per request
  • Incremental updates: Use changedSinceSlot to fetch only recently modified accounts
  • Better performance: Prevents timeouts and reduces memory usage for large datasets
  • Backward compatibility: Supports all existing getProgramAccounts parameters

Key Benefits

Scalable Queries

Handle programs with millions of accounts by paginating through results efficiently

Real-time Sync

Use changedSinceSlot for incremental updates and real-time data synchronization

Prevent Timeouts

Large queries that previously timed out now work reliably with pagination

Memory Efficient

Process data in chunks instead of loading everything into memory at once

Pagination Best Practices

Important Pagination Behavior: End of pagination is only indicated when no accounts are returned. The API may return fewer accounts than your limit due to filtering - always continue pagination until paginationKey is null.

Basic Pagination Pattern

let allAccounts = [];
let paginationKey = null;

do {
  const response = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: '1',
      method: 'getProgramAccountsV2',
      params: [
        "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
        {
          encoding: 'base64',
          filters: [{ dataSize: 165 }],
          limit: 5000,
          ...(paginationKey && { paginationKey })
        }
      ]
    })
  });
  
  const data = await response.json();
  allAccounts.push(...data.result.accounts);
  paginationKey = data.result.paginationKey;
} while (paginationKey);

Incremental Updates

// Get only accounts modified since slot 150000000
const incrementalUpdate = await fetch(`https://mainnet.helius-rpc.com/?api-key=${API_KEY}`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: '1',
    method: 'getProgramAccountsV2',
    params: [
      programId,
      {
        encoding: 'jsonParsed',
        limit: 1000,
        changedSinceSlot: 150000000
      }
    ]
  })
});

Performance Tips

Optimal Limit Size: For most use cases, a limit of 1,000-5,000 accounts per request provides the best balance of performance and reliability.
  • Start with smaller limits (1000) and increase based on your network performance
  • Use appropriate encoding: jsonParsed for convenience, base64 for performance
  • Apply filters to reduce the dataset size before pagination
  • Store paginationKey to resume queries if interrupted
  • Monitor response times and adjust limits accordingly

Migration from getProgramAccounts

Migrating from the original method is straightforward - simply replace the method name and add pagination parameters:
{
  "jsonrpc": "2.0",
  "id": "1",
- "method": "getProgramAccounts",
+ "method": "getProgramAccountsV2",
  "params": [
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    {
      "encoding": "base64",
      "filters": [{ "dataSize": 165 }],
+     "limit": 5000
    }
  ]
}

Authorizations

api-key
string
query
required

Your Helius API key. You can get one for free in the dashboard.

Body

application/json
jsonrpc
enum<string>
default:2.0
required

The JSON-RPC protocol version.

Available options:
2.0
Example:

"2.0"

id
string
default:1
required

A unique identifier for the request.

Example:

"1"

method
enum<string>
default:getProgramAccountsV2
required

The name of the RPC method to invoke.

Available options:
getProgramAccountsV2
Example:

"getProgramAccountsV2"

params
array
required

Parameters for the enhanced paginated method.

Response

Successfully retrieved paginated program accounts.

jsonrpc
enum<string>

The JSON-RPC protocol version.

Available options:
2.0
Example:

"2.0"

id
string

Identifier matching the request.

Example:

"1"

result
object

Paginated program accounts with navigation metadata.