> For the complete documentation index, see [llms.txt](https://docs.shyft.to/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.shyft.to/solana/get-transactions-for-address/filters.md).

# Filters

By default, `getTransactionsForAddress` <mark style="color:yellow;">returns</mark> all transactions for an address in <mark style="color:yellow;">reverse chronological order</mark>. <mark style="color:yellow;">Filters</mark> let you <mark style="color:yellow;">narrow</mark> that <mark style="color:yellow;">result set</mark> on the server before anything is returned - so you're not pulling down thousands of transactions and discarding most of them on the client.

Following filters are available:&#x20;

* **slot** - for slot based scans,
* **blockTime -** for time-range scans,&#x20;
* **signature -** for ledger-position bounds,&#x20;
* **status -** for filtering by execution outcome, and&#x20;
* **tokenAccounts -** for expanding or restricting coverage to SPL token accounts owned by the address. All filters are optional and can be combined in a single request.

Filters are passed as a nested `filters` object inside the options parameter. Comparison-based filters (`slot`, `blockTime`, `signature`) accept a comparison object with one or more operators (`gte`, `gt`, `lte`, `lt`, `eq`) so you can express both open-ended bounds and closed ranges.

### Available Filters

| Filter        | Type                          | Description                                                                                                                                            |
| ------------- | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| slot          | comparison object             | Filter by slot number. Supports `gte`, `gt`, `lte`, `lt`.                                                                                              |
| blockTime     | comparison object             | Filter by Unix timestamp. Supports `gte`, `gt`, `lte`, `lt`, `eq`.                                                                                     |
| signature     | comparison object             | Filter by signature position within the ledger. Supports `gte`, `gt`, `lte`, `lt`. Rarely needed — prefer `slot` or `paginationToken` for range scans. |
| status        | any \| succeeded \| failed    | Filter by transaction outcome. `any` returns both. Corresponds to `meta.err === null` (succeeded) or non-null (failed).                                |
| tokenAccounts | none \| balanceChanged \| all | Controls token-account fan-out. See Token Account Filtering below.                                                                                     |

**Comparison object example**

```json
{
  "gte": 425214949,
  "lt":  425215949
}
```

Multiple comparison operators can be combined in a single filter to express a range.

### Slot, Block time & Signature Filtering

**Slot**

Filters by the <mark style="color:yellow;">slot number</mark> a transaction was confirmed in. Accepts `gte`, `gt`, `lte`, `lt`. Use a single operator for an open-ended bound, or combine two to express a closed range:

```json
"slot": { "gte": 425214949, "lt": 425215949}
```

**Blocktime**

Filters by the <mark style="color:yellow;">Unix timestamp</mark> of the block. Accepts `gte`, `gt`, `lte`, `lt`, and also `eq` for an exact match. Works the same way as `slot` but in wall-clock time:

```json
"blockTime": { "gte": 1780963204, "lt": 1780963600}
```

**Signature**

Filters by a <mark style="color:yellow;">transaction's position in the ledger</mark> relative to a known signature. Accepts `gte`, `gt`, `lte`, `lt` - no `eq`, since you'd just query that signature directly. Works the same way structurally as `slot` and `blockTime`:

```json
"signature": { "gt": "5wHu1qwD4E5ZPx..." }
```

***

The key difference between the three: `slot` and `signature` are ledger-native (always present, always reliable), while `blockTime` can be `null` for very old blocks. For deep historical scans, prefer `slot`.

***

### Token Account Filtering

By default, `getTransactionsForAddress` only returns transactions where the queried address appears directly in `accountKeys`. Setting `tokenAccounts` expands this to include transactions that touched token accounts owned by that address.

<table><thead><tr><th width="160">Value</th><th>Behavior</th></tr></thead><tbody><tr><td><code>none</code></td><td>Only transactions where the address appears directly in <code>accountKeys</code>. Default.</td></tr><tr><td><code>all</code></td><td>Also includes transactions that reference any token account owned by the address, regardless of whether a balance change occurred.</td></tr><tr><td><code>balanceChanged</code></td><td>Like <code>all</code>, but only for token accounts where the pre/post token balance metadata shows a change. Useful for filtering to actual transfers and swaps rather than read-only account references.</td></tr></tbody></table>

Token ownership is determined from the `meta.preTokenBalances` and `meta.postTokenBalances` fields embedded in the transaction, not from a separate on-chain lookup.

{% hint style="info" %}
When `tokenAccounts` is `all` or `balanceChanged`, the queried address may not appear in `accountKeys` at all for some results. The address is the *owner* of an account that participated — not a signer or fee payer in that transaction.
{% endhint %}

{% tabs %}
{% tab title=""signatures" mode" %}
**Signatures mode (`transactionDetails: "signatures"`)**

{% code overflow="wrap" %}

```json
{
  "jsonrpc": "2.0",
  "result": {
    "data": [
      {
        "signature": "TransactionSignatureBase58",
        "slot": 250000001,
        "transactionIndex": 12,
        "err": null,
        "memo": null,
        "blockTime": 1780963600,
        "confirmationStatus": "finalized"
      }
    ],
    "paginationToken": "425214939:34"
  },
  "id": 1
}
```

{% endcode %}

**Response fields**

<table><thead><tr><th width="191">Field</th><th width="113">Type</th><th>Description</th></tr></thead><tbody><tr><td><code>signature</code></td><td>string</td><td>Base58-encoded transaction signature.</td></tr><tr><td><code>slot</code></td><td>u64</td><td>The slot this transaction was confirmed in.</td></tr><tr><td><code>transactionIndex</code></td><td>number</td><td>The transaction's position within its block. Zero-indexed. Useful for deterministic ordering when multiple transactions share a slot.</td></tr><tr><td><code>err</code></td><td>object | null</td><td><code>null</code> if the transaction succeeded. Otherwise contains the <code>TransactionError</code> object. Mirrors the <code>err</code> field from <code>getSignaturesForAddress</code>.</td></tr><tr><td><code>memo</code></td><td>string | null</td><td>Memo program message attached to the transaction, if any.</td></tr><tr><td><code>blockTime</code></td><td>i64 | null</td><td>Estimated Unix timestamp of the block. <code>null</code> for very old blocks where this wasn't recorded.</td></tr><tr><td><code>confirmationStatus</code></td><td>string</td><td>Confirmation status: <code>processed</code>, <code>confirmed</code>, or <code>finalized</code>.</td></tr><tr><td><code>paginationToken</code></td><td>string | null</td><td>Cursor for the next page. <code>null</code> when there are no more results.</td></tr></tbody></table>
{% endtab %}

{% tab title=""full" mode" %}
**Full transaction mode (`transactionDetails: "full"`)**

```json
{
  "jsonrpc": "2.0",
  "result": {
    "data": [
      {
        "slot": 250000001,
        "transactionIndex": 12,
        "blockTime": 1700000000,
        "transaction": { ... },
        "meta": { ... }
      }
    ],
    "paginationToken": "250000001:12"
  },
  "id": 1
}
```

Each item in `data` corresponds to a single confirmed transaction. The `transaction` and `meta` fields are identical in structure to what `getTransaction` returns for the same signature and encoding. Refer to the [`getTransaction` response structure](https://solana.com/docs/rpc/http/gettransaction) for full field documentation.

{% hint style="warning" %}
**Versioned transactions:** If any result in the page is a versioned transaction (version `0` or higher), the request will fail unless `maxSupportedTransactionVersion` is set. Set it to `0` to handle all current transaction versions - this mirrors the same requirement in `getTransaction`.
{% endhint %}
{% endtab %}
{% endtabs %}

### Pagination

When a response includes a non-null `paginationToken`, there are more results. Pass the token in the next request unchanged to continue scanning from where the previous page ended.

```json
{
  "jsonrpc": "2.0",
  "id": 2,
  "method": "getTransactionsForAddress",
  "params": [
    "AddressBase58",
    {
      "limit": 100,
      "paginationToken": "425214939:34"
    }
  ]
}
```

**Understanding the token structure**

The pagination token is two numbers separated by a colon:

```
"paginationToken": "425214939:34"
```

The first number is the **slot** - the block the last returned transaction was confirmed in. The second number is the **transactionIndex** - the zero-indexed position of that transaction within that block. So `250000101:5` means the 6th transaction in slot `250000101`.

This two-part structure is more precise than a signature-based cursor. A signature alone doesn't tell you where in a block a transaction sat - two transactions in the same slot have different signatures but you can't derive their ordering from those signatures alone. The `slot:transactionIndex` pair pins the exact position in the ledger, so resumption is always deterministic.

### How to Paginate?

A single request only returns up to your `limit`. When more transactions exist, <mark style="color:yellow;">the response contains a</mark> <mark style="color:yellow;"></mark><mark style="color:yellow;">`paginationToken`</mark> <mark style="color:yellow;"></mark><mark style="color:yellow;">you can pass into the next request to continue fetching</mark>. It's a `"slot:transactionIndex"` <mark style="color:yellow;">string</mark> pointing to the last result returned.

{% tabs %}
{% tab title="JavaScript" %}
{% code overflow="wrap" %}

```javascript
async function printAllTransactions(address) {
  let paginationToken = null;
  let totalFetched = 0;

  do {
    const response = await fetch("https://rpc.shyft.to?api_key=YOUR-API-KEY", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        jsonrpc: "2.0",
        id: 1,
        method: "getTransactionsForAddress",
        params: [address, { limit: 100, paginationToken }]
      })
    });

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

    result.data.forEach(tx => console.log(tx));
    totalFetched += result.data.length;
    console.log(`Fetched ${totalFetched} transactions so far...`);

    paginationToken = result.paginationToken;

  } while (paginationToken !== null);

  console.log(`Done. Total transactions fetched: ${totalFetched}`);
}

printAllTransactions("AddressBase58");
```

{% endcode %}
{% endtab %}

{% tab title="Rust" %}
{% code overflow="wrap" %}

```rs
use reqwest::Client;
use serde_json::{json, Value};

#[tokio::main]
async fn main() {
    let client = Client::new();
    let address = "AddressBase58";
    let mut pagination_token: Option<String> = None;
    let mut total_fetched = 0;

    loop {
        let response = client
            .post("https://rpc.shyft.to?api_key=YOUR_KEY")
            .json(&json!({
                "jsonrpc": "2.0",
                "id": 1,
                "method": "getTransactionsForAddress",
                "params": [address, { "limit": 100, "paginationToken": pagination_token }]
            }))
            .send()
            .await
            .unwrap()
            .json::<Value>()
            .await
            .unwrap();

        let data = response["result"]["data"].as_array().unwrap();

        for tx in data {
            println!("{:#?}", tx);
        }

        total_fetched += data.len();
        println!("Fetched {} transactions so far...", total_fetched);

        pagination_token = response["result"]["paginationToken"]
            .as_str()
            .map(|s| s.to_string());

        if pagination_token.is_none() {
            break;
        }
    }

    println!("Done. Total transactions fetched: {}", total_fetched);
}
```

{% endcode %}
{% endtab %}
{% endtabs %}
