RugCheck bulkTokenSummary Developer Guide

Learn how to fetch RugCheck report summaries for up to 255 tokens in a single bulkTokenSummary API call — and use it to compute the average RugCheck score of every token a wallet owns.

Before We Begin

Before reading this guide, you should know how to fetch the token accounts owned by a wallet with getTokenAccountsByOwner, as well as how to optimize RPC calls with byte slicing. Our getTokenAccountsByOwner & getTokenReportSummary guide covers both, if you need a refresher.

Unlike most of our other guides, our free API keys are NOT sufficient to complete this guide — the bulkTokenSummary endpoint is available to paid RugCheck plans only. A free plan on FluxRPC is OK though.

There is no need to copy-paste your keys, just navigate back to this page while logged in, and we will automatically use keys from your account. Remember you must have API keys created for both RugCheck and FluxRPC — the banners at the top of this guide will tell you if you are missing one.

In this guide, we will accomplish the following:

  1. Fetch all the token accounts for our wallet, like in our getTokenReportSummary guide.
  2. More optimization!
  3. Learn how to fetch bulk token report summaries with the RugCheck API.

Specifically, we're going to build something a little fun. We're going to efficiently calculate the average RugCheck score of all the token accounts a wallet owns — call it a "RugCheck Wisdom Score" if you like. Try it on your colleagues, see who scores the best!

About Token Accounts

Just a quick recap. Token accounts store data as follows:

We can fetch all the token accounts owned by a wallet with the getTokenAccountsByOwner RPC call. When making this RPC call, we must specify the wallet public key, and the Token program (there are two!).

In this example, we'll be fetching both SPL Token and Token-2022 accounts, so this will require 2 RPC calls.

For more detail, consider our getTokenAccountsByOwner Developer Guide! In that guide, we used the following RPC call:

curl "https://eu.fluxrpc.com?key=<Your-API-Key>" -s -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getTokenAccountsByOwner",
    "params": [
      "MfDuWeqSHEqTFVYZ7LoexgAK9dxk7cy4DFJWjWMGVWa",
      { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
      {
        "encoding": "base64",
        "dataSlice": { "offset": 0, "length": 72 }
      }
    ]
  }'

We sliced out the mint, owner, and balance here. However, in this application we only need the mint! So we can slice out more and save more bandwidth:

curl "https://eu.fluxrpc.com?key=<Your-API-Key>" -s -X POST \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "getTokenAccountsByOwner",
    "params": [
      "MfDuWeqSHEqTFVYZ7LoexgAK9dxk7cy4DFJWjWMGVWa",
      { "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA" },
      {
        "encoding": "base64",
        "dataSlice": { "offset": 0, "length": 32 }
      }
    ]
  }'

If we wanted to confirm that the token accounts had a nonzero balance, we'd have to keep all 72 bytes. However, for our purposes, just the mint is good enough.

Fetching Bulk Report Summaries

Our strategy is simple — append all the mint addresses to an array, and use the RugCheck bulkTokenSummary endpoint to get all their scores in a single API call. The request body is just a list of token mints:

curl -X POST "https://api.rugcheck.xyz/v1/bulk/tokens/summary" \
  -H "Content-Type: application/json" \
  -H "X-API-KEY: {{RUGCHECK_API_KEY}}" \
  -d '{
    "tokens": [
      "eb5U8spZFfJUUTS4RoterQTVTKwctzMRcd4PctZpump",
      "8JxfHVpnqHeSz99w9XfBwT2uaKHFNU72RNYxrbrxdj69"
    ]
  }'

The API call supports up to 255 tokens at once, so we'll add a check that aborts if you specify a wallet that has more than that. You may also want to split it into multiple API calls of up to 255 tokens.

import requests
import json
import base64
import base58

RPC_APIKey = "<Your-API-Key>"
rugCheck_APIKey = "{{RUGCHECK_API_KEY}}"
RPCRegion = "eu"
AccountPubKey = "" # Add your wallet here, or enter MfDuWeqSHEqTFVYZ7LoexgAK9dxk7cy4DFJWjWMGVWa to test the failure case

def fetchTokenAccounts(pubKey, program):
    headers = {'content-type': 'application/json'}
    url = "https://" + RPCRegion + ".fluxrpc.com?key=" + RPC_APIKey

    data = {
        "jsonrpc": "2.0",
        "id": 1,
        "method": "getTokenAccountsByOwner",
        "params": [
            pubKey,
            {
                "programId": program
            },
            {
                "encoding": "base64",
                "dataSlice": {"offset": 0, "length": 32} # We only need the mint, so the first 32 bytes are fine.
            }
        ]
    }
    response = requests.post(url, data=json.dumps(data), headers=headers)
    return response

def fetchBulkRugCheckReports(tokenMints):
    headers = {'content-type': 'application/json', 'X-API-KEY': rugCheck_APIKey}
    url = "https://api.rugcheck.xyz/v1/bulk/tokens/summary"
    data = {
        "tokens": tokenMints
    }
    response = requests.post(url, data=json.dumps(data), headers=headers)
    return response

tokenMints = []
# Fetch all SPL token accounts for the wallet & append to tokenMints list
response = fetchTokenAccounts(AccountPubKey, "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA")
if response.status_code != 200:
    raise Exception("RPC returned HTTP error code " + str(response.status_code))
responseJSON = json.loads(response.text)
tokenAccounts = (responseJSON["result"]["value"])
for i in tokenAccounts:
    dataBytes = base64.b64decode(i["account"]["data"][0])
    tokenMints.append(str(base58.b58encode(dataBytes[:32]), 'utf-8'))

# Fetch all Token-2022 token accounts for the wallet & append to tokenMints list
response = fetchTokenAccounts(AccountPubKey, "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb")
if response.status_code != 200:
    raise Exception("RPC returned HTTP error code " + str(response.status_code))
responseJSON = json.loads(response.text)
tokenAccounts = (responseJSON["result"]["value"])
for i in tokenAccounts:
    dataBytes = base64.b64decode(i["account"]["data"][0])
    tokenMints.append(str(base58.b58encode(dataBytes[:32]), 'utf-8'))

# Check that we have a reasonable amount of tokens to fetch. Each bulk report can request up to 255 tokens.
if len(tokenMints) > 255:
    raise Exception("This account has too many token accounts, " + str(len(tokenMints)) + "!")
if len(tokenMints) == 0:
    raise Exception("This account owns no token accounts!")

# Fetch the RugCheck scores with a single API call, we only need the report summaries here, not the full reports
response = fetchBulkRugCheckReports(tokenMints)
if response.status_code != 200:
    raise Exception("RugCheck returned HTTP error code " + str(response.status_code))
responseJSON = json.loads(response.text)
reports = responseJSON["reports"]
num_reports = len(reports)
scoreSum = 0
# Extract the token scores and compute an average. The score_normalised is the score from 0-100
# (lower is better) and usually more useful than the raw "score" parameter.
for i in reports:
    scoreSum = scoreSum + i["score_normalised"]
averageScore = scoreSum / num_reports
print("Wallet Holds " + str(num_reports) + " Tokens, with an average score of: " + str(averageScore))

Don't forget to add your wallet public key! Using the RugCheck bulk reporting endpoints like this is much faster than requesting the individual reports. Moreover, it counts as only a single API request, letting you get the maximum usage out of your RugCheck plan.

Next Steps

If you need the full token reports rather than summaries, the bulkTokenReports endpoint follows exactly the same pattern — just expect a much larger response.

Still on a free RugCheck plan? You can compute the same score by fetching the report summaries one token at a time with getTokenReportSummary — our getTokenAccountsByOwner guide shows how, including how to stay under the rate limit while you loop.

← All developer guides