getAccountInfo Solana Developer Guide
Learn how to read a single Solana account with getAccountInfo — response fields, encoding trade-offs, parsing program-specific data, and how to keep bandwidth costs down.
Reference documentation: getAccountInfo
Before We Begin
If you are new to Solana development, this is a good place to start your journey. You will need a FluxRPC API key to complete all the steps in this guide — our free keys are sufficient.
There is no need to copy-paste it — just navigate back to this page while logged in, and we will automatically use the key you select.
In this guide, we will accomplish the following:
- Fetch the data from a single account on the Solana blockchain
- Explain how to interpret the main response fields
- Weigh the advantages of different data encoding options
- Deal with program-specific data stored in accounts
- Optimize the request so it costs you less
We will provide examples in Python, TypeScript, Go, and cURL.
Reading Account Data on Solana
Solana accounts are identified by a 32-byte public key. With this public key, you can fetch the data stored in the account by using the getAccountInfo RPC call.
This is the right method to use when you only need information about a single account. If you need information about several accounts, it's faster and more efficient to use getMultipleAccounts — which is covered in the getMultipleAccounts guide.
This RPC call is very straightforward to use:
import requests
import json
APIKey = "<Your-API-Key>"
RPCRegion = "eu"
AccountPubKey = "MfDuWeqSHEqTFVYZ7LoexgAK9dxk7cy4DFJWjWMGVWa"
def fetchAccount(pubKey):
print("getAccount for public key " + pubKey)
headers = {'content-type': 'application/json'}
url = "https://" + RPCRegion + ".fluxrpc.com?key=" + APIKey
data = {
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [
pubKey,
{
"encoding": "base64"
}
]
}
response = requests.post(url, data=json.dumps(data), headers=headers)
return response
response = fetchAccount(AccountPubKey)
if response.status_code != 200:
raise Exception("RPC returned HTTP error code " + str(response.status_code))
responseJSON = json.loads(response.text)
print(responseJSON)
It's not necessary to specify the
commitmentparameter on FluxRPC. We only supportprocessedcommitment.
You will get a response that looks something like the following:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"context": {
"apiVersion": "1.33.7",
"slot": 434450667
},
"value": {
"owner": "11111111111111111111111111111111",
"lamports": 94275198182,
"executable": false,
"rentEpoch": 18446744073709551615,
"space": 0,
"data": [
"",
"base64"
]
}
}
}
We've selected a pretty active account — if you re-run this request in a minute, the lamports will likely be different! Starting from the top, the significance of each field in the response is as follows:
- jsonrpc: This is the version of the JSON-RPC specification. In practice, this always returns
2.0, and there's not much you will use this for. - id: This identifies which request the response is for. This lets you match responses to requests, useful if you are making many requests.
- result: This object contains all of the response data.
- context: The only important item in this object is the slot, which tells you what the latest slot was at the time this data was fetched. If you're making many similar requests, this will let you determine which is the most up-to-date.
- value: This object contains the actual information about the Solana account you queried.
- owner: All accounts on Solana are owned by a program, which determines how the account may be modified and by whom. The System program (
11111111111111111111111111111111) owns most accounts. Other common owners are the two Token programs or various decentralized exchanges (DEXs). - lamports: The amount of SOL in the account. 1 SOL = 1,000,000,000 lamports. 1 lamport is the minimum quantity of SOL — you cannot have 0.5 lamports.
- executable: Returns
trueif the account is a Solana program (an executable smart contract). Returnsfalsefor all other accounts. - rentEpoch: Currently this value is unused and will always return
18446744073709551615, the max value of a 64-bit unsigned integer. - space: Solana accounts can store arbitrary data — this is the raw number of bytes stored.
- data: This object contains the data stored in the account (if any), as well as the encoding scheme for the data (
jsonParsed, base58, or base64). More on this later!
Reference
The canonical field-by-field description of an account lives in the Solana account model documentation. We recommend keeping it open in a second tab while you work through this guide.
What Happens when the Public Key Doesn't Exist?
In the case where you make a getAccountInfo RPC call for a public key that doesn't exist, it will respond with:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"context": {
"apiVersion": "1.33.7",
"slot": 434654544
},
"value": null
}
}
In other words, it will not return an error, but a null result in the value field. Be sure to handle this case in any code you write! There are many cases where this can come up:
- The account was closed and contains zero lamports
- There's an error in the public key caused by a user input error
- A Program Derived Address (PDA) was given the wrong inputs
- You have an error in your program and have passed something that's not a valid public key to getAccountInfo
Encoding
You may have noticed in our request, we selected base64 encoding. Data on Solana is stored as raw bytes, so it's necessary to choose an encoding scheme to transmit the information as text characters. There are 3 choices here:
- base64: This is the most efficient option and recommended for general use. Base64 uses all upper and lowercase alphabetic characters, numbers 0-9, and some punctuation (for a total of 64 characters) to represent binary data efficiently. Since FluxRPC charges by the bandwidth you use, you'll spend less by using this option.
- base58: This is similar to base64, but eliminates ambiguous characters (e.g.
1vsl,ovs0and so on). The result is something reasonably efficient, but easier to spot differences in. This is why it's used as the standard way to represent Solana public keys. It's a useful encoding option during development, when you need to compare output. - jsonParsed: This option is only available for certain standard programs (like the Token programs, and SYSVAR). It will automatically parse the
datafield of the response into human-readable JSON. This wastes a lot of data and is slower, but is useful during software development when running getAccountInfo against standard Solana programs. Mostly it's useful while learning or debugging. You should use base64 in production.
Program-Specific Data
Solana accounts can store arbitrary data. Usually this is used by the program that owns them to store information needed for its operation.
For example, in Associated Token Accounts (ATA) the Token program stores the mint and amount of tokens held in the data field. We can fetch the token balance using the getTokenAccountBalance RPC method as follows:
curl "https://eu.fluxrpc.com?key=<Your-API-Key>" -s -X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getTokenAccountBalance",
"params": [
"5Dui9R5UUFJuXm911BmijxZcsm5hmx5gBBdvTwzo9zfE"
]
}'
This will return something like the following:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"context": {
"apiVersion": "1.33.7",
"slot": 434464244
},
"value": {
"amount": "410000971248",
"decimals": 6,
"uiAmount": 410000.971248,
"uiAmountString": "410000.971248"
}
}
}
From this response, we can see that the account holds 410000971248 base units of the token, and the mint has 6 decimals. This means it holds 410000.971248 tokens.
However, getTokenAccountBalance is really just parsing applied on top of a getAccountInfo request. Let's look at how we would get the mint and number of tokens by parsing getAccountInfo ourselves:
- Look at the Solana Token Account Structure
- Fetch the account data
- Convert the base64
datafield to an array of bytes - Slice the bytes according to the ATA layout to extract the data
- Convert the data to base58 (in the case of public keys) or an integer (in the case of a token amount)
import requests
import json
import base64
import base58
APIKey = "<Your-API-Key>"
RPCRegion = "eu"
AccountPubKey = "5Dui9R5UUFJuXm911BmijxZcsm5hmx5gBBdvTwzo9zfE"
def fetchAccount(pubKey):
print("getAccount for public key " + pubKey)
headers = {'content-type': 'application/json'}
url = "https://" + RPCRegion + ".fluxrpc.com?key=" + APIKey
data = {
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [
pubKey,
{
"encoding": "base64"
}
]
}
response = requests.post(url, data=json.dumps(data), headers=headers)
return response
response = fetchAccount(AccountPubKey)
if response.status_code != 200:
raise Exception("RPC returned HTTP error code " + str(response.status_code))
responseJSON = json.loads(response.text)
print(responseJSON) # Print the raw data from getAccountInfo
result = responseJSON["result"]["value"]
if result == None: # Handle NULL result
raise Exception("Public Key not found")
dataBytes = base64.b64decode(result["data"][0])
if len(dataBytes) == 0: # Handle empty data field, probably this is an account owned by the System program, not a token account!
raise Exception("Public Key found, but could not parse the data. Is it a token account?")
# The first 32 bytes in an ATA are the token mint
mint = base58.b58encode(dataBytes[0:32]).decode("utf-8")
# The next 32 bytes are the owner of this token account
owner = base58.b58encode(dataBytes[32:64]).decode("utf-8")
# The next 8 bytes (uint64) are the amount of tokens they own, in base units
amount = int.from_bytes(dataBytes[64:72], byteorder='little')
print("Mint: " + mint)
print("Owner: " + owner)
print("Amount owned (base units): " + str(amount))
Note that we only have the token amount in base units! If we wanted to get the user-facing amount of tokens, we'd have to additionally run getAccountInfo on the token mint (USDC at public key EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v in this case), and extract the mint decimals.
There are many RPC methods that work similarly — they could be accomplished with multiple getAccountInfo calls, but it would be a bit of a pain, so we define specialized RPC methods for convenience. As a result, a good understanding of getAccountInfo is a solid first step to understanding many of the other methods in the RPC reference!
A Final Note on Encoding
If we had instead selected jsonParsed encoding for our last getAccountInfo call like so:
curl "https://eu.fluxrpc.com?key=<Your-API-Key>" -s -X POST \
-H "Content-Type: application/json" \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "getAccountInfo",
"params": [
"5Dui9R5UUFJuXm911BmijxZcsm5hmx5gBBdvTwzo9zfE",
{
"encoding": "jsonParsed"
}
]
}'
You'll get something like the following:
{
"jsonrpc": "2.0",
"id": 1,
"result": {
"context": {
"apiVersion": "1.33.7",
"slot": 434468103
},
"value": {
"lamports": 2039280,
"data": {
"program": "spl-token",
"parsed": {
"info": {
"isNative": false,
"mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
"owner": "4ePFLN3dkHoaJNXYeScr5ZDp823tSt2ZJPbcZgccbASv",
"state": "initialized",
"tokenAmount": {
"amount": "410000971248",
"decimals": 6,
"uiAmount": 410000.971248,
"uiAmountString": "410000.971248"
}
},
"type": "account"
},
"space": 165
},
"owner": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
"executable": false,
"rentEpoch": 18446744073709551615,
"space": 165
}
}
}
We'd like to point out that some of this data is not actually stored in the account 5Dui9R5UUFJuXm911BmijxZcsm5hmx5gBBdvTwzo9zfE.
For example, you might notice the decimals (6) in there! That data is actually stored in the token mint (EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v).
When you specify jsonParsed encoding on an Associated Token Address (ATA), the RPC will assume you need this extra data and include it in the response. It will not include it for the other encoding types.
Watch out
This inconsistency catches new developers by surprise regularly. If a field appears under
jsonParsedbut vanishes when you switch to base64 in production, this is usually why.
Optimization
An engineer's task is to do for a dime what anyone can do for a dollar! Here are some tips that will help you scale:
- If you have to call more than one account, use getMultipleAccounts instead of getAccountInfo. It has less overhead.
- Use base64 encoding, and convert to other formats in your application.
- Use more specialized RPC methods instead of multiple getAccountInfo calls.
- Consider using Lantern! It will save you a lot of bandwidth, because you'll be answering your own RPC requests. There's also no rate limit, and serving 1,000 requests per second is quite easy to achieve — all on our affordable Developer plan. At other RPCs, you'd be looking at $1500 per month for that kind of rate limit.
Next Steps
A good method to learn next is getMultipleAccounts — it is the first optimization most Solana developers reach for, and it builds directly on everything you just read.