> ## Documentation Index
> Fetch the complete documentation index at: https://www.helius.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# getProgramAccountsV2

> Enhanced version of getProgramAccounts with cursor-based pagination and changedSinceSlot support for efficiently querying large sets of accounts owned by specific Solana programs with incremental updates.

## 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.

<Info>
  **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
  * **Optional `withContext`**: `true` adds `slot` and `apiVersion` under `result.context`; omit or `false` and they are not included
</Info>

## Key Benefits

<CardGroup cols={2}>
  <Card title="Scalable Queries" icon="chart-line">
    Handle programs with millions of accounts by paginating through results efficiently
  </Card>

  <Card title="Real-time Sync" icon="arrows-rotate">
    Use `changedSinceSlot` for incremental updates and real-time data synchronization
  </Card>

  <Card title="Prevent Timeouts" icon="clock">
    Large queries that previously timed out now work reliably with pagination
  </Card>

  <Card title="Memory Efficient" icon="microchip">
    Process data in chunks instead of loading everything into memory at once
  </Card>
</CardGroup>

## Pagination Best Practices

<Warning>
  **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`.
</Warning>

### Basic Pagination Pattern

```typescript theme={"system"}
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

```typescript theme={"system"}
// 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

<Tip>
  **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.
</Tip>

* **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

## `withContext` (optional)

Boolean on the program config object (`params[1]`). Only the shape of `result` changes, not filters, limits, or pagination.

```json theme={"system"}
// Omitted or false
{ "jsonrpc": "2.0", "id": "1", "result": { "accounts": [], "paginationKey": null } }

// true — snapshot metadata plus page under `result.value`
{ "jsonrpc": "2.0", "id": "1", "result": {
  "context": { "slot": 411895550, "apiVersion": "3.1.9" },
  "value": { "accounts": [], "paginationKey": null }
}}
```

## Migration from getProgramAccounts

Migrating from the original method is straightforward - simply replace the method name and add pagination parameters:

```diff theme={"system"}
{
  "jsonrpc": "2.0",
  "id": "1",
- "method": "getProgramAccounts",
+ "method": "getProgramAccountsV2",
  "params": [
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    {
      "encoding": "base64",
      "filters": [{ "dataSize": 165 }],
+     "limit": 5000
    }
  ]
}
```

## Related Methods

<CardGroup cols={2}>
  <Card title="getProgramAccounts" icon="code" href="/api-reference/rpc/http/getprogramaccounts">
    Original method without pagination
  </Card>

  <Card title="getTokenAccountsByOwnerV2" icon="wallet" href="/api-reference/rpc/http/gettokenaccountsbyownerv2">
    V2 method for token account queries
  </Card>
</CardGroup>

## Request Parameters

<ParamField body="address" type="string" required>
  The Solana program public key (address) to query accounts for, as a base-58 encoded string.
</ParamField>

<ParamField body="commitment" type="string">
  The commitment level for the request.

  * `confirmed`
  * `finalized`
  * `processed`
</ParamField>

<ParamField body="minContextSlot" type="number">
  The minimum slot that the request can be evaluated at.
</ParamField>

<ParamField body="withContext" type="boolean">
  When `true`, returns `result.context` (snapshot metadata: `slot`, `apiVersion`) and nests
  `accounts` and `paginationKey` under `result.value`. When `false` or omitted,
  those fields appear directly on `result` (for example `result.accounts`). Same filters and limits apply.
</ParamField>

<ParamField body="encoding" type="string">
  Encoding format for the returned account data.

  * `jsonParsed`
  * `base58`
  * `base64`
  * `base64+zstd`
</ParamField>

<ParamField body="dataSlice" type="object">
  Request a slice of the account's data.
</ParamField>

<ParamField body="dataSlice.length" type="number">
  Number of bytes to return.
</ParamField>

<ParamField body="dataSlice.offset" type="number">
  Byte offset from which to start reading.
</ParamField>

<ParamField body="limit" type="number">
  Maximum number of accounts to return per request (1-10,000).
</ParamField>

<ParamField body="paginationKey" type="string">
  Base-58 encoded pagination cursor for fetching subsequent pages. Use the paginationKey from previous response.
</ParamField>

<ParamField body="changedSinceSlot" type="number">
  Only return accounts that were modified at or after this slot number. Useful for incremental updates.
</ParamField>

<ParamField body="filters" type="array">
  Powerful filtering system to efficiently query specific Solana account data patterns.
</ParamField>


## OpenAPI

````yaml openapi/rpc-http/getProgramAccountsV2.yaml POST /
openapi: 3.1.0
info:
  title: Solana RPC API
  version: 1.0.0
  description: >-
    Enhanced Solana program account indexing API with cursor-based pagination
    and changedSinceSlot support for efficiently querying large sets of accounts
    owned by specific programs. Supports incremental updates via slot-based
    filtering for real-time data synchronization.
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0.html
servers:
  - url: https://mainnet.helius-rpc.com
    description: Mainnet RPC endpoint
  - url: https://devnet.helius-rpc.com
    description: Devnet RPC endpoint
security: []
paths:
  /:
    post:
      tags:
        - RPC
      summary: getProgramAccountsV2
      description: >
        Enhanced version of getProgramAccounts with cursor-based pagination and
        changedSinceSlot support for efficiently querying 

        large sets of accounts owned by specific Solana programs. Enables
        incremental data fetching with 

        configurable page sizes up to 10,000 accounts per request. The
        changedSinceSlot parameter allows retrieving 

        only accounts modified since a specific blockchain slot, perfect for
        real-time indexing and data 

        synchronization workflows. Essential for applications dealing with
        large-scale program account discovery 

        such as DeFi protocols, NFT marketplaces, and blockchain analytics
        platforms.


        Note: End of pagination is only indicated when no accounts are returned.
        The API may return fewer accounts 

        than the limit due to filtering - continue pagination until
        paginationKey is null.


        **withContext**: Optional boolean on the configuration object (alongside
        encoding, limit, and so on). When 

        `withContext` is `true`, the RPC returns the standard Solana wrapped
        shape: `result.context` (snapshot 

        metadata, including `slot` and usually `apiVersion`) and `result.value`
        holding `accounts`, `paginationKey`, 

        When `withContext` is `false` or omitted, those fields are returned
        directly on `result`

        (for example `result.accounts`). Filters, limits, and pagination
        behavior are unchanged; only the JSON shape 

        of `result` differs.
      operationId: getProgramAccountsV2
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              required:
                - jsonrpc
                - id
                - method
                - params
              properties:
                jsonrpc:
                  type: string
                  description: The JSON-RPC protocol version.
                  enum:
                    - '2.0'
                  example: '2.0'
                  default: '2.0'
                id:
                  type: string
                  description: A unique identifier for the request.
                  example: '1'
                  default: '1'
                method:
                  type: string
                  description: The name of the RPC method to invoke.
                  enum:
                    - getProgramAccountsV2
                  example: getProgramAccountsV2
                  default: getProgramAccountsV2
                params:
                  type: array
                  description: Parameters for the enhanced paginated method.
                  default:
                    - TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
                    - encoding: base64
                      limit: 1000
                  items:
                    oneOf:
                      - type: string
                        description: >-
                          The Solana program public key (address) to query
                          accounts for, as a base-58 encoded string.
                        example: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
                      - type: object
                        description: >-
                          Enhanced configuration options with pagination support
                          for optimizing program account queries.
                        properties:
                          commitment:
                            type: string
                            description: The commitment level for the request.
                            enum:
                              - confirmed
                              - finalized
                              - processed
                            example: finalized
                          minContextSlot:
                            type: integer
                            description: >-
                              The minimum slot that the request can be evaluated
                              at.
                            example: 1000
                          withContext:
                            type: boolean
                            description: >
                              When `true`, returns `result.context` (snapshot
                              metadata: `slot`, `apiVersion`) and nests

                              `accounts` and `paginationKey` under
                              `result.value`. When `false` or omitted,

                              those fields appear directly on `result` (for
                              example `result.accounts`). Same filters and
                              limits apply.
                            example: true
                          encoding:
                            type: string
                            description: Encoding format for the returned account data.
                            enum:
                              - jsonParsed
                              - base58
                              - base64
                              - base64+zstd
                            example: base64
                          dataSlice:
                            type: object
                            description: Request a slice of the account's data.
                            properties:
                              length:
                                type: integer
                                description: Number of bytes to return.
                                example: 50
                              offset:
                                type: integer
                                description: Byte offset from which to start reading.
                                example: 0
                          limit:
                            type: integer
                            description: >-
                              Maximum number of accounts to return per request
                              (1-10,000).
                            minimum: 1
                            maximum: 10000
                            example: 1000
                          paginationKey:
                            type: string
                            description: >-
                              Base-58 encoded pagination cursor for fetching
                              subsequent pages. Use the paginationKey from
                              previous response.
                            example: 9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
                          changedSinceSlot:
                            type: integer
                            description: >-
                              Only return accounts that were modified at or
                              after this slot number. Useful for incremental
                              updates.
                            example: 12345678
                          filters:
                            type: array
                            description: >-
                              Powerful filtering system to efficiently query
                              specific Solana account data patterns.
                            items:
                              oneOf:
                                - type: object
                                  description: >-
                                    Filter Solana accounts by their exact data
                                    size in bytes.
                                  properties:
                                    dataSize:
                                      type: integer
                                      description: >-
                                        The exact size of the account data in
                                        bytes for filtering.
                                      example: 165
                                - type: object
                                  description: >-
                                    Filter Solana accounts by comparing data at
                                    specific memory offsets (most powerful
                                    filter).
                                  properties:
                                    memcmp:
                                      type: object
                                      description: >-
                                        Memory comparison filter for finding
                                        accounts with specific data patterns.
                                      properties:
                                        offset:
                                          type: integer
                                          description: >-
                                            Byte offset within account data to
                                            perform the comparison.
                                          example: 4
                                        bytes:
                                          type: string
                                          description: >-
                                            Base-58 encoded data to compare at the
                                            specified offset position.
                                          example: 3Mc6vR
      responses:
        '200':
          description: Successfully retrieved paginated program accounts.
          content:
            application/json:
              schema:
                type: object
                properties:
                  jsonrpc:
                    type: string
                    description: The JSON-RPC protocol version.
                    enum:
                      - '2.0'
                    example: '2.0'
                  id:
                    type: string
                    description: Identifier matching the request.
                    example: '1'
                  result:
                    oneOf:
                      - $ref: '#/components/schemas/ProgramAccountsV2Page'
                        title: without withContext
                      - type: object
                        title: with withContext
                        description: >-
                          Wrapped result when `withContext` is `true` in the
                          request options.
                        required:
                          - context
                          - value
                        properties:
                          context:
                            type: object
                            description: >-
                              Snapshot metadata for the node response (slot
                              consistency, debugging).
                            properties:
                              slot:
                                type: integer
                                description: Slot at which the node built this response.
                                example: 411895550
                              apiVersion:
                                type: string
                                description: RPC API version when available.
                                example: 3.1.9
                          value:
                            $ref: '#/components/schemas/ProgramAccountsV2Page'
        '400':
          description: Bad Request - Invalid request parameters or malformed request.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32602
                  message: Invalid params
                  data: {}
                id: '1'
        '401':
          description: Unauthorized - Invalid or missing API key.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32001
                  message: Unauthorized
                  data: {}
                id: '1'
        '429':
          description: Too Many Requests - Rate limit exceeded.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32005
                  message: Too many requests
                  data: {}
                id: '1'
        '500':
          description: Internal Server Error - An error occurred on the server.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32603
                  message: Internal error
                  data: {}
                id: '1'
        '503':
          description: Service Unavailable - The service is temporarily unavailable.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32002
                  message: Service unavailable
                  data: {}
                id: '1'
        '504':
          description: Gateway Timeout - The request timed out.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                jsonrpc: '2.0'
                error:
                  code: -32003
                  message: Gateway timeout
                  data: {}
                id: '1'
      security:
        - ApiKeyQuery: []
components:
  schemas:
    ProgramAccountsV2Page:
      type: object
      description: >-
        Paginated program accounts. Same fields appear on result when
        withContext is false or omitted, or under result.value when withContext
        is true.
      properties:
        accounts:
          type: array
          description: List of program accounts for the current page.
          items:
            $ref: '#/components/schemas/ProgramAccountV2Entry'
        paginationKey:
          type: string
          description: >-
            Pagination cursor for the next page. Null only when no accounts are
            returned (end of pagination). Note that fewer accounts than the
            limit may be returned due to filtering, but this does not indicate
            end of pagination.
          example: 8WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM
          nullable: true
    ErrorResponse:
      type: object
      properties:
        jsonrpc:
          type: string
          description: The JSON-RPC protocol version.
          enum:
            - '2.0'
          example: '2.0'
        error:
          type: object
          properties:
            code:
              type: integer
              description: The error code.
              example: -32602
            message:
              type: string
              description: The error message.
            data:
              type: object
              description: Additional data about the error.
        id:
          type: string
          description: Identifier matching the request.
          example: '1'
    ProgramAccountV2Entry:
      type: object
      properties:
        pubkey:
          type: string
          description: The account Pubkey as a base-58 encoded string.
          example: CxELquR1gPP8wHe33gZ4QxqGB3sZ9RSwsJ2KshVewkFY
        account:
          type: object
          description: Details about the account.
          properties:
            lamports:
              type: integer
              description: Number of lamports assigned to this account.
              example: 15298080
            owner:
              type: string
              description: >-
                Base-58 encoded Pubkey of the program this account is assigned
                to.
              example: TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA
            data:
              type: array
              description: Account data as encoded binary or JSON format.
              items:
                type: string
              example:
                - 2R9jLfiAQ9bgdcw6h8s44439
                - base64
            executable:
              type: boolean
              description: Indicates if the account contains a program.
              example: false
            rentEpoch:
              type: integer
              description: The epoch at which this account will next owe rent.
              example: 28
            space:
              type: integer
              description: The data size of the account.
              example: 165
  securitySchemes:
    ApiKeyQuery:
      type: apiKey
      in: query
      name: api-key
      description: >-
        Your Helius API key. You can get one for free in the
        [dashboard](https://dashboard.helius.dev/api-keys).

````