TriportRPC

getProgramAccounts

POSThttps://api.triport.io

Returns all accounts owned by a given Solana program, optionally narrowed by data-size and memcmp filters.

Solanasol_read_rpc_heavyfree+ — **2 rps (free) / 5 rps (basic) / 20 rps (pro) / 80 rps (business)**, with burst

getProgramAccounts returns every account whose owner is the supplied programId. It is the canonical way to enumerate program state — for example, all token accounts of a mint, all open orders on a market, or all PDAs created by your own program.

This is a heavy method (sol_read_rpc_heavy category) and is rate-limited far more strictly than standard read RPC: just 2 rps on the free tier, up to 80 rps on business. A single unfiltered call can scan a very large account set, so always narrow the result with filters (a memcmp byte match and/or a dataSize match) and request only the bytes you need with dataSlice. Treat this method as expensive and cache its results where you can.

By default the result is a plain array of ProgramAccount objects. Set withContext: true to wrap the array in an RpcContext envelope ({ context, value }), which is useful when you need the slot the result was evaluated at.

Parameters

JSON-RPC params is a positional array: [programId, config?].

programIdstring (base-58 Pubkey)required
Public key of the owning program. Must match ^[1-9A-HJ-NP-Za-km-z]{32,44}$.
configobjectoptional
Optional configuration object (see below).
config (GetProgramAccountsConfig)object
encodingstringoptional
Account-data encoding for each result: base58, base64, base64+zstd, or jsonParsed.
commitmentstringoptional
Commitment level: processed, confirmed, or finalized.
dataSliceobjectoptional
Limits returned account data to a byte window: { "offset": <integer>, "length": <integer> }. Only valid with binary encodings.
filtersarrayoptional
Up to-N filter objects (logical AND). Each is either a dataSize filter or a memcmp filter (see below).
minContextSlotintegeroptional
Minimum slot the request must be evaluated at. The request fails if the node has not yet reached this slot.
withContextbooleanoptional
When true, wraps the result array in an RpcContext envelope ({ context, value }). Defaults to false.
filters entries (AccountFilter)object
dataSizeinteger
Matches accounts whose data length is exactly this many bytes.
memcmpobject
Matches accounts whose data, at a byte offset, equals the given bytes.

Response

With withContext: true, the array is wrapped in an envelope:

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "context": { "slot": 348392041, "apiVersion": "2.0.18" },
    "value": [
      { "pubkey": "Cx...", "account": { "lamports": 2039280, "owner": "Tok...", "executable": false, "rentEpoch": 18446744073709551615, "space": 165, "data": ["...", "base64"] } }
    ]
  }
}
pubkeystring (base-58)
Public key of the matched account.
accountobject
The account state (AccountInfo).
account.lamportsinteger
Balance of the account in lamports.
account.ownerstring (base-58)
Owning program — equals the queried programId.
account.executableboolean
Whether the account holds a loaded program.
account.rentEpochinteger
Epoch at which the account next owes rent (u64).
account.spaceinteger
Size of the account data in bytes.
account.dataarray | object
Account data. For binary encodings: [<data>, <encoding>]. For jsonParsed: a decoded object, or the binary tuple if no parser matched.

Errors

Errors use the standard JSON-RPC envelope (error.code, error.message, error.data).

CodeHTTPMeaningWhen it happens
-32602400Invalid paramsprogramId is not valid base-58, or config/filters contain an invalid value (e.g. base58 encoding on oversized data, malformed memcmp).
-32002403Tier insufficientAPI key's tier/scope does not include sol_read_rpc_heavy.
-32003429Rate limit exceededMore than your tier's sustained RPS for sol_read_rpc_heavy (2 / 5 / 20 / 80, with burst) was sent. Honour the Retry-After header.
-32601404Method not foundMethod name misspelled or not available on this chain.

Example rate-limit envelope:

{
  "jsonrpc": "2.0",
  "id": 1,
  "error": {
    "code": -32003,
    "message": "Rate limit exceeded: 2 RPS sustained on sol_read_rpc_heavy (free tier)",
    "data": {
      "current_tier": "free",
      "category": "sol_read_rpc_heavy",
      "limit_rps": 2,
      "burst_capacity": 4,
      "retry_after_sec": 1
    }
  }
}

See the shared errors reference for the full envelope and retry guidance.

Examples

JavaScript (fetch)

const res = await fetch("https://api.triport.io", {
  method: "POST",
  headers: {
    "Authorization": `Bearer ${process.env.TRIPORT_API_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: 1,
    method: "getProgramAccounts",
    params: [
      "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
      {
        encoding: "base64",
        commitment: "finalized",
        filters: [{ dataSize: 165 }],
      },
    ],
  }),
});


const { result } = await res.json();
console.log(`${result.length} accounts owned by the program`);

TypeScript SDK (@triport/sdk)

import { Triport } from "@triport/sdk";


const client = new Triport({ apiKey: process.env.TRIPORT_API_KEY! });


const accounts = await client.sol.getProgramAccounts(
  "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
  {
    encoding: "base64",
    commitment: "finalized",
    filters: [
      { dataSize: 165 },
      { memcmp: { offset: 0, bytes: "So11111111111111111111111111111111111111112", encoding: "base58" } },
    ],
  },
);


for (const { pubkey, account } of accounts) {
  console.log(pubkey, account.lamports);
}

Python (triport-sdk)

import os
from triport import Triport


client = Triport(api_key=os.environ["TRIPORT_API_KEY"])


accounts = client.sol.get_program_accounts(
    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
    encoding="base64",
    commitment="finalized",
    filters=[
        {"dataSize": 165},
        {"memcmp": {"offset": 0, "bytes": "So11111111111111111111111111111111111111112", "encoding": "base58"}},
    ],
)


print(f"{len(accounts)} accounts owned by the program")

Notes

  • Always filter. An unfiltered query can scan a huge account set and is the fastest way to exhaust your tier's RPS. Combine a dataSize filter (match the exact account layout size) with one or more memcmp filters (match a discriminator or owner field) to return only what you need.
  • Trim the payload with dataSlice. If you only read a few fields, request a byte window instead of full account data. dataSlice is ignored by jsonParsed.
  • Heavy rate limits. This method sits in sol_read_rpc_heavy (2 / 5 / 20 / 80 rps), an order of magnitude below standard read RPC. Cache results and back off on -32003 using the Retry-After header.
  • Pagination. This method returns the full matching set in one response and has no cursor. For large, paginated enumeration use getProgramAccountsV2 (see the method catalog) once its full schema is published.
  • Related methods: getAccountInfo (a single account by key) and getBalance (lamports only).