Skip to main content
Helius Exclusive Feature - getTransactionsForAddress is only available through Helius RPC nodes and is not part of standard Solana RPC. This endpoint requires a Developer plan or higher and costs 100 credits per request. Returns 100 full transactions or 1,000 signatures.

Overview

getTransactionsForAddress provides powerful transaction history queries with advanced filtering, flexible sorting, and efficient pagination.

Key Features

Flexible sorting

Sort chronologically (oldest first) or reverse (newest first)

Advanced filtering

Filter by time ranges, slots, signatures, and transaction status

Full transaction data

Get complete transaction details in one call

Token accounts

Include transactions for an addresses’ associated token accounts

Common Use Cases

This method is particularly useful for several scenarios. Token Launch Analysis helps track first mint transactions and early token holders for new projects. Wallet Funding History allows you to identify funding sources and transaction patterns for specific addresses. Transaction Analysis lets you filter by success/failure status to focus on completed transactions and exclude failed attempts. The API also supports Audit & Compliance workflows by generating transaction reports for specific time periods with status filtering. Analytics Dashboards can leverage the historical replay functionality to build comprehensive transaction analytics. Finally, Portfolio Tracking applications can access complete successful transaction history for DeFi portfolio management.

Associated Token Accounts

On Solana, your wallet doesn’t actually hold tokens directly. Instead, your wallet owns token accounts, and those token accounts hold your tokens. When someone sends you USDC, it goes to your USDC token account instead of your main wallet address.
This method is unique because it allows you to query complete token history. You can query for a wallet’s full history, including associated token addresses (ATAs). Native RPC methods such as getSignaturesForAddress do not include ATAs. The tokenAccounts filter gives you control over this behavior:
  • none (default): Only returns transactions that directly reference the wallet address. Use this when you only care about direct wallet interactions.
  • balanceChanged (recommended): Returns transactions that reference the wallet address OR modify the balance of a token account owned by the wallet. This filters out spam and unrelated operations like fee collections or delegations, giving you a clean view of meaningful wallet activity.
  • all: Returns all transactions that reference the wallet address or any token account owned by the wallet.

Network Support

NetworkSupportedRetention Period
MainnetYesUnlimited
DevnetYes2 weeks
TestnetNoN/A

Quick Start

1

Get Your API Key

Obtain your API key from the Helius Dashboard.
2

Query with Advanced Features

Get all successful transactions for a wallet between two dates, sorted chronologically:
// Get successful transactions between Jan 1-31, 2025 in chronological order
const response = await fetch('https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY', {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'getTransactionsForAddress',
    params: [
      'YOUR_ADDRESS_HERE',
      {
        transactionDetails: 'full',
        sortOrder: 'asc',
        limit: 100,
        filters: {
          blockTime: {
            gte: 1735689600,   // Jan 1, 2025
            lte: 1738368000    // Jan 31, 2025
          },
          status: 'succeeded',  // Only successful transactions
          tokenAccounts: 'balanceChanged' // Include associated token accounts
        }
      }
    ]
  })
});

const data = await response.json();
console.log('Successful transactions in January:', data.result.data);
3

Understand the Parameters

This example shows key features:
  • transactionDetails: Set to 'full' to get complete transaction data in one call
  • sortOrder: Use 'asc' for chronological order (oldest first) or 'desc' for newest first
  • filters.blockTime: Set time ranges with gte (greater than or equal) and lte (less than or equal)
  • filters.status: Filter to only 'succeeded' or 'failed' transactions
  • filters.tokenAccounts: Include transfers, mints, and burns for associated token accounts

Request Parameters

address
string
required
Base-58 encoded public key of the account to query transaction history for
transactionDetails
string
default:"signatures"
Level of transaction detail to return:
  • signatures: Basic signature info (faster)
  • full: Complete transaction data (eliminates need for getTransaction calls, requires limit ≤ 100)
sortOrder
string
default:"desc"
Sort order for results:
  • desc: Newest first (default)
  • asc: Oldest first (chronological, great for historical analysis)
limit
number
default:"1000"
Maximum transactions to return:
  • Up to 1000 when transactionDetails: "signatures"
  • Up to 100 when transactionDetails: "full"
paginationToken
string
Pagination token from previous response (format: "slot:position")
commitment
string
default:"finalized"
Commitment level: finalized or confirmed. The processed commitment is not supported.
filters
object
Advanced filtering options for narrowing down results.
filters.slot
object
Filter by slot number using comparison operators: gte, gt, lte, ltExample: { "slot": { "gte": 1000, "lte": 2000 } }
filters.blockTime
object
Filter by Unix timestamp using comparison operators: gte, gt, lte, lt, eqExample: { "blockTime": { "gte": 1640995200, "lte": 1641081600 } }
filters.signature
object
Filter by transaction signature using comparison operators: gte, gt, lte, ltExample: { "signature": { "lt": "SIGNATURE_STRING" } }
filters.status
string
Filter by transaction success/failure status:
  • succeeded: Only successful transactions
  • failed: Only failed transactions
  • any: Both successful and failed (default)
Example: { "status": "succeeded" }
filters.tokenAccounts
string
default:"none"
Filter transactions for related token accounts:
  • none: Only return transactions that reference the provided address (default)
  • balanceChanged: Return transactions that reference either the provided address or modify the balance of a token account owned by the provided address (recommended)
  • all: Return transactions that reference either the provided address or any token account owned by the provided address
Example: { "tokenAccounts": "balanceChanged" }
encoding
string
Encoding format for transaction data (only applies when transactionDetails: "full"). Same as getTransaction API. Options: json, jsonParsed, base64, base58
maxSupportedTransactionVersion
number
Set the max transaction version to return. If omitted, only legacy transactions will be returned. Set to 0 to include all versioned transactions.
minContextSlot
number
The minimum slot that the request can be evaluated at

Filters

When using filters, you can use comparison operators for slot, blockTime, or signature, plus the special status & tokenAccounts filters.

Comparison Operators

These operators work like database queries to give you precise control over your data range.
OperatorFull NameDescriptionExample
gteGreater Than or EqualInclude values ≥ specified valueslot: { gte: 100 }
gtGreater ThanInclude values > specified valueblockTime: { gt: 1641081600 }
lteLess Than or EqualInclude values ≤ specified valueslot: { lte: 2000 }
ltLess ThanInclude values < specified valueblockTime: { lt: 1641168000 }
eqEqualInclude values exactly equal (only blockTime)blockTime: { eq: 1641081600 }

Enum Filters

FilterDescriptionValues
statusFilter transactions by success/failuresucceeded, failed, or any
tokenAccountsFilter transactions for related token accountsnone, balanceChanged, or all
Combined Filters Examples:
// Time range with successful transactions only
"filters": {
  "blockTime": {
    "gte": 1640995200,
    "lte": 1641081600
  },
  "status": "succeeded"
}

// Slot range
"filters": {
  "slot": {
    "gte": 1000,
    "lte": 2000
  }
}

// Only failed transactions
"filters": {
  "status": "failed"
}

Response Format

{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "data": [
      {
        "signature": "5h6xBEauJ3PK6SWCZ1PGjBvj8vDdWG3KpwATGy1ARAXFSDwt8GFXM7W5Ncn16wmqokgpiKRLuS83KUxyZyv2sUYv",
        "slot": 1054,
        "transactionIndex": 42,
        "err": null,
        "memo": null,
        "blockTime": 1641038400,
        "confirmationStatus": "finalized"
      }
    ],
    "paginationToken": "1055:5"
  }
}

Response Fields

FieldTypeDescription
signaturestringTransaction signature (base-58 encoded). Only in signatures mode.
slotnumberThe slot containing the block with this transaction.
transactionIndexnumberThe zero-based index of the transaction within its block. Useful for transaction ordering and block reconstruction.
blockTimenumber | nullEstimated production time as Unix timestamp (seconds since epoch).
errobject | nullError if the transaction failed, null if successful. Only in signatures mode.
memostring | nullMemo associated with the transaction. Only in signatures mode.
confirmationStatusstringTransaction’s cluster confirmation status. Only in signatures mode.
transactionobjectFull transaction data. Only in full mode.
metaobjectTransaction status metadata. Only in full mode.
paginationTokenstring | nullToken for fetching the next page, or null if no more results.
The transactionIndex field is exclusive to getTransactionsForAddress. Other similar endpoints like getSignaturesForAddress, getTransaction, and getTransactions do not include this field.

Practical Examples

Time-Based Analytics

Generate monthly transaction reports:
// Get all successful transactions for January 2025
const startTime = Math.floor(new Date('2025-01-01').getTime() / 1000);
const endTime = Math.floor(new Date('2025-02-01').getTime() / 1000);

{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "WALLET_OR_PROGRAM_ADDRESS",
    {
      "transactionDetails": "signatures",
      "filters": {
        "blockTime": {
          "gte": startTime,
          "lt": endTime
        },
        "status": "succeeded"
      },
      "limit": 1000
    }
  ]
}
Process for analytics:
// Calculate daily transaction volume
const dailyStats = {};
response.result.data.forEach(tx => {
  const date = new Date(tx.blockTime * 1000).toISOString().split('T')[0];
  dailyStats[date] = (dailyStats[date] || 0) + 1;
});

console.log('Daily Transaction Counts:', dailyStats);

Token Mint Creation

Find the mint creation transaction for a specific token:
{
  "jsonrpc": "2.0",
  "id": "find-first-mints",
  "method": "getTransactionsForAddress",
  "params": [
    MINT_ADDRESS, // Token mint address
    {
      "encoding": "jsonParsed",
      "maxSupportedTransactionVersion": 0,
      "sortOrder": "asc",  // Chronological order from the beginning
      "limit": 10,
      "transactionDetails": "full"
    }
  ]
}
For Liquidity Pool creation, query the pool address:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress", 
  "params": [
    "POOL_ADDRESS_HERE", // Raydium/Meteora pool address
    {
      "transactionDetails": "full",
      "sortOrder": "asc",  // First transaction is usually pool creation
      "limit": 1
    }
  ]
}
Use Case: Find the exact moment when a token mint or liquidity pool was created, including the creator address and initial parameters.

Funding Transactions

Find who funded a specific address:
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "getTransactionsForAddress",
  "params": [
    "TARGET_WALLET_ADDRESS",
    {
      "transactionDetails": "full",
      "sortOrder": "asc",  // Oldest first
      "limit": 10
    }
  ]
}
Then analyze the transaction data to find SOL transfers:
response.result.data.forEach(tx => {
  // Look for SOL transfers in preBalances/postBalances
  const balanceChanges = tx.meta.preBalances.map((pre, index) => 
    tx.meta.postBalances[index] - pre
  );
  
  // Positive balance change = incoming SOL
  balanceChanges.forEach((change, index) => {
    if (change > 0) {
      console.log(`Received ${change} lamports from ${tx.transaction.message.accountKeys[index]}`);
    }
  });
});
The first few transactions often reveal the funding source and can help identify related addresses or funding patterns.

Pagination

When you have more transactions than your limit, use the paginationToken from the response to fetch the next page. The token is a simple string in the format "slot:position" that tells the API where to continue from.

How to Paginate

Use the pagination token from each response to fetch the next page:
// First request
let paginationToken = null;
let allTransactions = [];

const getNextPage = async (paginationToken = null) => {
  const params = [
    'ADDRESS',
    {
      transactionDetails: 'signatures',
      limit: 100,
      ...(paginationToken && { paginationToken })
    }
  ];

  const response = await fetch(rpcUrl, {
    method: 'POST',
    headers: { 'Content-Type': 'application/json' },
    body: JSON.stringify({
      jsonrpc: '2.0',
      id: 1,
      method: 'getTransactionsForAddress',
      params
    })
  });

  const data = await response.json();
  return data.result;
};

// Paginate through all results
do {
  const result = await getNextPage(paginationToken);
  allTransactions.push(...result.data);
  paginationToken = result.paginationToken;
  
  console.log(`Fetched ${result.data.length} transactions, total: ${allTransactions.length}`);
} while (paginationToken);

Multiple Addresses

You cannot query multiple addresses in a single request. To fetch transactions for multiple addresses, query each address within the same time or slot window, then merge and sort:
const addresses = ['Address1...', 'Address2...', 'Address3...'];

// Query all addresses in parallel with slot filter
const results = await Promise.all(
  addresses.map(address => 
    fetch(rpcUrl, {
      method: 'POST',
      headers: { 'Content-Type': 'application/json' },
      body: JSON.stringify({
        jsonrpc: '2.0',
        id: 1,
        method: 'getTransactionsForAddress',
        params: [address, {
          sortOrder: 'desc',
          filters: { slot: { gt: 250000000 } }
        }]
      })
    }).then(r => r.json())
  )
);

// Merge and sort by slot
const allTransactions = results
  .flatMap(r => r.result.data)
  .sort((a, b) => b.slot - a.slot);
For larger history scans, iterate through time or slot windows (e.g., 1000 slots at a time) and repeat this pattern.
Each address query counts as a separate API request (100 credits per address).

Best Practices

Performance

For optimal performance, use transactionDetails: "signatures" when you don’t need full transaction data. Implement reasonable page sizes better response times, and consider filtering by time ranges or specific slots for more targeted queries.

Filtering

Start with broad filters and narrow down progressively to find the data you need. Use time-based filters for analytics and reporting workflows. You can combine multiple filters for precise queries that target specific transaction types or time periods.

Pagination

Store pagination keys when you need to resume large queries later. Monitor pagination depth for performance planning, and use ascending order for scenarios where you need to replay historical events in chronological order.

Error Handling

Handle rate limits gracefully with exponential backoff strategies. Always validate addresses before making requests, and cache results when appropriate to reduce API usage and improve application performance.

How is this different from getSignaturesForAddress?

If you’re familiar with the standard getSignaturesForAddress method, here are the key differences:

Get Full Transactions in One Call

With getSignaturesForAddress, you need two steps:
// Step 1: Get signatures
const signatures = await connection.getSignaturesForAddress(address, { limit: 100 });

// Step 2: Get transaction details (100 additional calls!)
const transactions = await Promise.all(
  signatures.map(sig => connection.getTransaction(sig.signature))
);
With getTransactionsForAddress, it’s one call:
const response = await fetch(heliusRpcUrl, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify({
    jsonrpc: '2.0',
    id: 1,
    method: 'getTransactionsForAddress',
    params: [
      address,
      {
        transactionDetails: 'full',
        limit: 100
      }
    ]
  })
});

Get Token History in One Call

With getSignaturesForAddress, you need to first call getTokenAccountsByOwner and then query for every token account:
// OLD WAY (with getSignaturesForAddress)
// Step 1: Get all token accounts owned by this wallet
const tokenAccounts = await connection.getTokenAccountsByOwner(
  new PublicKey(walletAddress),
  { programId: TOKEN_PROGRAM_ID }
);

// Step 2: Fetch signatures for the wallet itself
const walletSignatures = await connection.getSignaturesForAddress(
  new PublicKey(walletAddress),
  { limit: 1000 }
);

// Step 3: Fetch signatures for EVERY token account (this is the painful part)
const tokenAccountSignatures = await Promise.all(
  tokenAccounts.value.map(async (account) => {
    return connection.getSignaturesForAddress(
      account.pubkey,
      { limit: 1000 }
    );
  })
);

// Step 4: Merge all results together
const allSignatures = [
  ...walletSignatures,
  ...tokenAccountSignatures.flat()
];

// Step 5: Deduplicate (many transactions touch multiple accounts)
const seen = new Set();
const uniqueSignatures = allSignatures.filter((sig) => {
  if (seen.has(sig.signature)) {
    return false;
  }
  seen.add(sig.signature);
  return true;
});

// Step 6: Sort chronologically
const sortedSignatures = uniqueSignatures.sort(
  (a, b) => a.slot - b.slot
);

return sortedSignatures;
With getTransactionsForAddress you only need to set filters.tokenAccounts:
// NEW WAY (with getTransactionsForAddress)
const response = await fetch("https://mainnet.helius-rpc.com/?api-key=YOUR_API_KEY", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({
    jsonrpc: "2.0",
    id: "helius-example",
    method: "getTransactionsForAddress",
    params: [
      walletAddress,
      {
        filters: {
          tokenAccounts: "all"
        }
        sortOrder: "asc",
        limit: 100

      }
    ]
  })
});

const { result } = await response.json();
return result;

Additional Capabilities

Chronological sorting

Sort transactions from oldest to newest with sortOrder: 'asc'

Time-based filtering

Filter by time ranges using blockTime filters

Status filtering

Get only successful or failed transactions with status filter

Simpler pagination

Use paginationToken instead of confusing before/until signatures

Support & Community