Address Lookup Tables

Address Lookup Table queries through getProgramAccounts and getProgramAccountsV2, answered from an in-memory index, with plan rates, account layout and filters.

Address Lookup Tables are found and read in bulk with getProgramAccounts or getProgramAccountsV2 on the Address Lookup Table program.

Access

Queries go through getProgramAccounts or getProgramAccountsV2 with AddressLookupTab1e1111111111111111111111111 as the first parameter. The endpoint and the API key are the same as every other Solana RPC call. There is no separate method, hostname or add-on.

PlanAvailability
Blade Runner, NexusServed
Free, OperatorHTTP 403, code -32600, message getProgramAccounts requires higher tier. The getProgramAccountsV2 message names getProgramAccountsV2

Answers come from an in-memory index, not a disk scan. No filter is required, and the 256 MB scan-results cap of a disk scan does not apply. Batch requests (a JSON array of calls) are not served: one call per HTTP request.

Rate limits

PlanCalls per second per API key
Blade Runner25/s
Nexus75/s
Free, Operator—

The budget is shared per API key. Address Lookup Table queries count together with every other getProgramAccounts and getProgramAccountsV2 call on that key, whichever program they address. A Nexus key sending 50 calls per second against other programs has 25 calls per second left for table queries.

There is no cap on open requests; only the rate is counted. The plan's total requests-per-second limit also applies. See Plans & Limits.

Over the rate, the response is HTTP 429 with code -32005 and the message Rate limit exceeded (gpa: 25/sec) on Blade Runner or Rate limit exceeded (gpa: 75/sec) on Nexus. It carries no Retry-After header and no rate-limit headers. The window is one whole second. See Gateway errors.

One known table

A table whose address is already known is read with getAccountInfo or getMultipleAccounts with encoding: "jsonParsed". That is a plain account read: it is not an index query and does not count against the getProgramAccounts budget.

getProgramAccounts on the Address Lookup Table program is for finding tables by content (authority, size, addresses, status) or for walking all tables.

Account layout

OffsetSizeFieldNotes
04typeu32 little-endian; 1 = lookup table
48deactivationSlotu64 little-endian; 18446744073709551615 (all bytes 0xFF) while the table is active
128lastExtendedSlotu64 little-endian
201lastExtendedSlotStartIndexu8
211authority present1 = has an authority, 0 = frozen
2232authoritypublic key
542padding
5632 × NaddressesN stored addresses, at most 256

Account size is 56 + 32 × N bytes. A table with 4 addresses is 184 bytes.

Filters

GoalFilter
Tables controlled by an authoritymemcmp at offset 22, bytes = the authority public key (base58)
Tables with an authority set (not frozen)memcmp at offset 21, bytes: "2" (base58 of the single byte 0x01)
Active tables onlymemcmp at offset 4, bytes: "jpXCZedGfVQ" (base58 of eight 0xFF bytes)
Tables holding exactly N addressesdataSize: 56 + 32 × N
Tables whose address at index i is Xmemcmp at offset 56 + 32 × i, bytes = X

memcmp compares at one fixed offset, so a table that holds an address at an unknown position matches only a filter for that position. There is no "contains" filter.

Filters combine with AND. memcmp bytes may be base58 (default) or base64 via memcmp.encoding.

Examples

getProgramAccounts on the tables controlled by one authority, with no account data returned:

curl "https://rpc-newyork.constant-k.com/?api-key=YOUR_API_KEY" \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getProgramAccounts",
    "params": [
      "AddressLookupTab1e1111111111111111111111111",
      {
        "filters": [
          { "memcmp": { "offset": 22, "bytes": "DStdNqtygUnfNwkHNrEhsPWwN7hqXrYrMJ8JMkLvidjT" } }
        ],
        "dataSlice": { "offset": 0, "length": 0 }
      }
    ]
  }'

dataSlice with length: 0 returns no data, so the answer carries only the table addresses and account metadata. The response is trimmed to one account:

[
  {
    "account": {
      "data": ["", "base64"],
      "executable": false,
      "lamports": 2171520,
      "owner": "AddressLookupTab1e1111111111111111111111111",
      "rentEpoch": 18446744073709551615,
      "space": 184
    },
    "pubkey": "1AjuJovi8byYxtUPyFna86jaRipDgVeX4TCXbkWNZxg"
  }
]

getProgramAccountsV2 returns one page of tables with the layout decoded:

curl "https://rpc-newyork.constant-k.com/?api-key=YOUR_API_KEY" \
  -X POST -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getProgramAccountsV2",
    "params": [
      "AddressLookupTab1e1111111111111111111111111",
      {
        "encoding": "jsonParsed",
        "filters": [{ "dataSize": 184 }],
        "limit": 1,
        "withContext": true
      }
    ]
  }'
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "context": { "slot": 457692691 },
    "value": {
      "accounts": [
        {
          "account": {
            "data": {
              "parsed": {
                "info": {
                  "addresses": [
                    "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                    "SysvarRent111111111111111111111111111111111",
                    "Ce6TQqeHC9p8KetsN6JsjHK7UTZk7nasjjnr7XxXp9F1",
                    "6EF8rrecthR5Dkzon8Nwu78hRvfCKubJ14M5uBEwF6P"
                  ],
                  "authority": "DStdNqtygUnfNwkHNrEhsPWwN7hqXrYrMJ8JMkLvidjT",
                  "deactivationSlot": "18446744073709551615",
                  "lastExtendedSlot": "306248204",
                  "lastExtendedSlotStartIndex": 0
                },
                "type": "lookupTable"
              },
              "program": "address-lookup-table",
              "space": 184
            },
            "executable": false,
            "lamports": 2171520,
            "owner": "AddressLookupTab1e1111111111111111111111111",
            "rentEpoch": 18446744073709551615,
            "space": 184
          },
          "pubkey": "1AjuJovi8byYxtUPyFna86jaRipDgVeX4TCXbkWNZxg"
        }
      ],
      "paginationKey": "1AjuJovi8byYxtUPyFna86jaRipDgVeX4TCXbkWNZxg"
    }
  }
}

paginationKey is the cursor for the next page. It is passed back as paginationKey on the next call, and is null on the last page.

Parameters

ParameterValuesNotes
encodingbase64 (default), base64+zstd, base58, jsonParsedbase58 covers data up to 128 bytes after dataSlice; larger data returns -32602 with base58 encoding is only supported for data under 129 bytes; use base64
dataSlice{ offset, length }length: 0 returns no data, only addresses and account metadata
filtersdataSize, memcmpOptional; every filter must match
withContexttrue, falseAdds context.slot
minContextSlotslot numberIf the index has not reached it, -32016 with Minimum context slot has not been reached
commitmentany levelAccepted, no effect. See the note below
limit1 to 10,000, default 1,000getProgramAccountsV2 only. Outside the range: -32602 with limit must be between 1 and 10000
paginationKeyaccount addressgetProgramAccountsV2 only; the cursor from the previous page
changedSinceSlotslot numbergetProgramAccountsV2 only; returns only tables changed since that slot, for incremental sync

commitment is accepted and ignored

Answers are at confirmed commitment. A finalized request gets confirmed data.

Result size and freshness

getProgramAccounts answers up to 1 GB of matched account data. Above that it returns -32012 with scan aborted: The accumulated scan results exceeded the limit. getProgramAccountsV2 pages through any size, so walking every table uses it with limit up to 10,000 and paginationKey. Results are narrowed with filters and dataSlice.

If the index falls behind the chain, a getProgramAccountsV2 call with changedSinceSlot returns -32005 with data.numSlotsBehind until the index catches up.

Errors

HTTPCodeMessageCause
403-32600getProgramAccounts requires higher tierFree or Operator plan. The getProgramAccountsV2 message names getProgramAccountsV2
429-32005Rate limit exceeded (gpa: 25/sec), Rate limit exceeded (gpa: 75/sec)Over the plan's calls per second
200-32602base58 encoding is only supported for data under 129 bytes; use base64, limit must be between 1 and 10000An invalid parameter
200-32012scan aborted: The accumulated scan results exceeded the limitMatched account data over 1 GB. getProgramAccounts only
200-32016Minimum context slot has not been reachedminContextSlot is above the slot the index has reached
200-32005Error data carries numSlotsBehindThe index is behind the chain. Only with changedSinceSlot

See Errors for every code and its fix.

On this page