> For the complete documentation index, see [llms.txt](https://docs.triton.one/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.triton.one/solana/real-time-streaming/whirligig-websockets.md).

# WebSocket

Subscribe to accounts, programs, logs, signatures, slots, blocks, and transactions over wss\:// with the Solana WebSocket API, backed by Dragon's Mouth gRPC.

Connect at `wss://<your-endpoint>.mainnet.rpcpool.com/<your-token>`.

{% hint style="info" %}
The WebSocket service runs on Whirligig, Triton's WebSocket server for Dragon's Mouth gRPC. Usage pages and invoices list WebSocket traffic as Whirligig. The older `/whirligig` path reaches the same service.
{% endhint %}

## Use cases

* **Real-time browser apps and browser extensions.** Browsers don't support gRPC. Subscribe over `wss://` with the standard Solana WebSocket API.
* **Backends.** If you can run a gRPC client, use [Dragon's Mouth](/solana/real-time-streaming/dragon-s-mouth-grpc.md). If your backend already uses a Solana WebSocket client, use the WebSocket API.

## Features

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-bolt">:bolt:</i> <strong>transactionSubscribe</strong></td><td>A full-transaction subscription, a Triton extension, with account include, exclude, and required filters.</td><td></td></tr><tr><td><i class="fa-gauge-high">:gauge-high:</i> <strong>Intra-slot updates</strong></td><td>At <code>processed</code> commitment, <code>accountSubscribe</code> and <code>programSubscribe</code> notify on every account write as the stream delivers it, within the slot.</td><td></td></tr><tr><td><i class="fa-code">:code:</i> <strong>jsonParsed encoding</strong></td><td><code>accountSubscribe</code> and <code>programSubscribe</code> return structured objects for parsable programs instead of raw byte arrays, with resolved mint metadata on token accounts.</td><td></td></tr><tr><td><i class="fa-cube">:cube:</i> <strong>blockSubscribe</strong></td><td>New blocks over <code>wss://</code>. Needs <code>confirmed</code> or <code>finalized</code> commitment.</td><td></td></tr></tbody></table>

## How it works

The WebSocket server reads a Dragon's Mouth gRPC stream, matches the updates to each client's subscriptions, and sends them as standard Solana WebSocket notifications.

```mermaid
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#F2EDF6','primaryBorderColor':'#7A4BA0','primaryTextColor':'#171717','lineColor':'#956FB3','secondaryColor':'#E4DBEC','tertiaryColor':'#D7C9E3','edgeLabelBackground':'#F2EDF6'},'flowchart':{'nodeSpacing':20,'rankSpacing':35,'curve':'linear'}}}%%
flowchart LR
    dm["Dragon's Mouth<br/>gRPC stream"] --> w["WebSocket server<br/>gRPC to WebSocket"] --> you["Your client<br/>(standard Solana WS API)"]
    style you fill:#D6EAF8,stroke:#259DD0
```

## Supported methods

The methods follow the [Solana WebSocket API](https://solana.com/docs/rpc/websocket). Parameters and results are in [WebSocket methods](/solana/rpc-methods/real-time-streaming/whirligig-websocket.md), except for `rootSubscribe`, `voteSubscribe`, and `slotsUpdatesSubscribe`, which have no reference page.

| Method                  | Returns                                                                            |
| ----------------------- | ---------------------------------------------------------------------------------- |
| `accountSubscribe`      | An account's data, on change                                                       |
| `blockSubscribe`        | New blocks                                                                         |
| `logsSubscribe`         | Transaction logs mentioning an address                                             |
| `programSubscribe`      | Accounts owned by a program, on change                                             |
| `signatureSubscribe`    | A signature's confirmation status                                                  |
| `slotSubscribe`         | Each new slot                                                                      |
| `rootSubscribe`         | Each new root (the highest finalized slot)                                         |
| `voteSubscribe`         | Votes from committed vote transactions (none on Alpenglow; unstable Solana method) |
| `slotsUpdatesSubscribe` | Detailed slot-status updates (unstable Solana method)                              |
| `transactionSubscribe`  | Full transactions matching a filter. Triton extension to the Solana WebSocket API  |

Each subscribe method returns a subscription `id` and has a matching unsubscribe (see [Unsubscribe](#unsubscribe)).

## Connection options

{% tabs %}
{% tab title="JavaScript (web3.js)" %}
Set `wsEndpoint` to your `wss://` endpoint URL. Standard Solana WebSocket clients usually need no other change.

```javascript
import { Connection, PublicKey } from "@solana/web3.js";

const connection = new Connection(
  "https://<your-endpoint>.mainnet.rpcpool.com/<your-token>",
  {
    wsEndpoint: "wss://<your-endpoint>.mainnet.rpcpool.com/<your-token>",
    commitment: "processed",
  }
);

const subscriptionId = connection.onAccountChange(
  new PublicKey("<account-pubkey>"),
  (accountInfo, context) => {
    console.log("slot:", context.slot, "lamports:", accountInfo.lamports);
  },
  "processed"
);

// When done:
// await connection.removeAccountChangeListener(subscriptionId);
```

{% endtab %}

{% tab title="Rust" %}
Uses the standard [`solana-pubsub-client`](https://docs.rs/solana-pubsub-client) crate.

{% code title="Cargo.toml" %}

```toml
[dependencies]
solana-pubsub-client = "~4.4"
solana-rpc-client-types = "~4.4"
solana-account-decoder-client-types = "~4.4"
solana-pubkey = "4"
solana-commitment-config = "3"
tokio = { version = "1", features = ["full"] }
futures = "0.3"
serde_json = "1"
rustls = { version = "0.23", default-features = false, features = ["ring"] } # TLS crypto provider for wss://
```

{% endcode %}

{% code title="src/main.rs" %}

```rust
use futures::StreamExt;
use solana_account_decoder_client_types::UiAccountEncoding;
use solana_commitment_config::CommitmentConfig;
use solana_pubkey::Pubkey;
use solana_pubsub_client::nonblocking::pubsub_client::PubsubClient;
use solana_rpc_client_types::config::RpcAccountInfoConfig;
use std::str::FromStr;

#[tokio::main]
async fn main() {
    let client = PubsubClient::new("wss://<your-endpoint>.mainnet.rpcpool.com/<your-token>")
        .await
        .expect("connect");

    let pubkey = Pubkey::from_str("<account-pubkey>").expect("valid pubkey");
    let config = RpcAccountInfoConfig {
        encoding: Some(UiAccountEncoding::JsonParsed),
        commitment: Some(CommitmentConfig::processed()),
        data_slice: None,
        min_context_slot: None,
    };

    let (mut stream, unsubscribe) = client
        .account_subscribe(&pubkey, Some(config))
        .await
        .expect("subscribe");

    while let Some(update) = stream.next().await {
        println!("{}", serde_json::to_string(&update).unwrap());
    }

    drop(stream);
    drop(unsubscribe);
    client.shutdown().await.expect("shutdown");
}
```

{% endcode %}
{% endtab %}

{% tab title="JavaScript (raw WebSocket)" %}
Required for `transactionSubscribe`, which returns full transaction data in a single call and is not available in `@solana/web3.js`.

```javascript
const ws = new WebSocket("wss://<your-endpoint>.mainnet.rpcpool.com/<your-token>");

ws.addEventListener("open", () => {
  // Keep alive: idle connections are closed after 60 s
  setInterval(() => ws.send(JSON.stringify({ jsonrpc: "2.0", method: "ping" })), 30_000);

  ws.send(JSON.stringify({
    jsonrpc: "2.0", id: 1,
    method: "transactionSubscribe",
    params: [
      { vote: false, failed: false },
      {
        commitment: "processed",
        encoding: "jsonParsed",
        transactionDetails: "full",
        maxSupportedTransactionVersion: 1,
      },
    ],
  }));
});

ws.addEventListener("message", ({ data }) => {
  const msg = JSON.parse(data);
  if (msg.method === "transactionNotification") {
    console.log("tx:", msg.params.result.value.transaction.transaction.signatures[0]);
  }
});
```

{% endtab %}
{% endtabs %}

{% hint style="info" %}
Connections idle for over 60 seconds are closed, so keep them alive by sending `{"jsonrpc":"2.0","method":"ping"}`.
{% endhint %}

Run your client close to a Triton region to lower latency.

### Commitment levels

Set the commitment level per subscription in the `config` argument. `blockSubscribe` accepts `confirmed` or `finalized`, not `processed`.

| Level       | Meaning                                                                                                                                                                        | Update sent                            |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------- |
| `processed` | The node has processed the transaction or account write; its slot can still be in progress. Not yet `confirmed` or `finalized`; the block can still be skipped by the cluster. | Without waiting for its slot to finish |
| `confirmed` | The highest slot voted on by a supermajority of the cluster. On Alpenglow, `confirmed` and `finalized` updates arrive together.                                                | After its slot reaches `confirmed`     |
| `finalized` | The highest slot that is final. On Alpenglow, a block becomes final about 150 ms after the leader proposes it.                                                                 | After its slot reaches `finalized`     |

The WebSocket server subscribes to Dragon's Mouth at `processed`.

{% hint style="info" %}
For the lowest latency, subscribe at `processed` and track `confirmed` and `finalized` yourself. `slotsUpdatesSubscribe` sends `optimisticConfirmation` when a slot is confirmed and `root` when it is finalized.
{% endhint %}

## Subscribe request

### accountSubscribe

{% tabs %}
{% tab title="Request" %}

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "accountSubscribe",
  "params": [
    "SysvarC1ock11111111111111111111111111111111",
    {
      "encoding": "base58",
      "commitment": "processed"
    }
  ]
}

```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "accountNotification",
  "params": {
    "result": {
      "context": {
        "slot": 206122916
      },
      "value": {
        "data": [
          "9AAG2zomYcUVKQfondw13yz193crQ5R5zmzdEojhMPXiyYEjD8viLrb",
          "base58"
        ],
        "executable": false,
        "lamports": 1169280,
        "owner": "Sysvar1111111111111111111111111111111111111",
        "rentEpoch": 361,
        "space": 40
      }
    },
    "subscription": 0
  }
}
```

{% endtab %}
{% endtabs %}

### blockSubscribe

{% tabs %}
{% tab title="Request" %}

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "blockSubscribe",
  "params": [
    "all",
    {
      "commitment": "finalized",
      "maxSupportedTransactionVersion": 1,
      "showRewards": false,
      "transactionDetails": "none"
    }
  ]
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "blockNotification",
  "params": {
    "result": {
      "context": {
        "slot": 206125999
      },
      "value": {
        "block": {
          "blockHeight": 188652385,
          "blockTime": 1689709529,
          "blockhash": "74iqy9xdFvenLkFizkoBkkLRWTyygEeCiiN3B8Z8ma2D",
          "parentSlot": 206125998,
          "previousBlockhash": "Cq5nfgu9Y5KF47J9qj5CTYmt8D5CxBpw8HCRqQZ7o7i9"
        },
        "err": null,
        "slot": 206125999
      }
    },
    "subscription": 0
  }
}
```

{% endtab %}
{% endtabs %}

### logsSubscribe

{% tabs %}
{% tab title="Request" %}

```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "logsSubscribe",
  "params": [
    {
      "mentions": ["8BnEgHoWFysVcuFFX7QztDmzuH8r5ZFvyP3sYwn1XTh6"]
    },
    {
      "commitment": "processed"
    }
  ]
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "logsNotification",
  "params": {
    "result": {
      "context": {
        "slot": 206126709
      },
      "value": {
        "err": null,
        "logs": [
          "Program FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj invoke [1]",
          "Program log: process_instruction: FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj: 3 accounts, data=[12]",
          "Program log: Instruction: UpdateLendingPool",
          "Program log: current_borrow_rate: 73081853393945351",
          "Program FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj consumed 23800 of 1000000 compute units",
          "Program FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj success",
          "Program FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj invoke [1]",
          "Program log: process_instruction: FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj: 3 accounts, data=[12]",
          "Program log: Instruction: UpdateLendingPool",
          "Program log: current_borrow_rate: 82164236984041212",
          "Program FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj consumed 28159 of 976200 compute units",
          "Program FC81tbGt6JWRXidaWYFXxGnTk4VgobhJHATvTRVMqgWj success",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N invoke [1]",
          "Program log: Instruction: LiquidateUnstakeLp",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
          "Program log: Instruction: Transfer",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4740 of 879873 compute units",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N consumed 79765 of 948041 compute units",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N success",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N invoke [1]",
          "Program log: Instruction: RemoveLiquidity",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N consumed 24767 of 868276 compute units",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N success",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N invoke [1]",
          "Program log: Instruction: SwapAndWithdraw",
          "Program log: withdraw_type: 2,\\n            user_info.pending_repay_0: 0,\\n            user_info.pending_repay_1: 0,\\n            user_info.tkn_0: 0,\\n            user_info.tkn_1: 0,\\n            ",
          "Program log: swap_direction: 0,\\n            amount_in: 0\\n            ",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
          "Program log: Instruction: Transfer",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4785 of 815778 compute units",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
          "Program log: Instruction: Transfer",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4831 of 807689 compute units",
          "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N consumed 47497 of 843509 compute units",
          "Program 2nAAsYdXF3eTQzaeUQS3fr4o782dDg8L28mX39Wr5j8N success"
        ],
        "signature": "5UPB2AEWgUafVDEw2xTkup8CUedxCMNL4k7EMuxtcyi1WnYLmpXeYUfBANpnPnpSz6LRwwLnBQf7tViKSFT7ojiB"
      }
    },
    "subscription": 0
  }
}
```

{% endtab %}
{% endtabs %}

### programSubscribe

{% tabs %}
{% tab title="Request" %}

```json
{
  "id": 1,
  "jsonrpc": "2.0",
  "method": "programSubscribe",
  "params": [
    "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX",
    {
      "encoding": "base64+zstd",
      "commitment": "processed"
    }
  ]
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "programNotification",
  "params": {
    "result": {
      "context": {
        "slot": 206127070
      },
      "value": {
        "account": {
          "data": [
            "KLUv/QBYDQEAkHNlcnVtQQABAAQAcGFkZGluZwUA03+gI0CxQgAYeABG",
            "base64+zstd"
          ],
          "executable": false,
          "lamports": 457104960,
          "owner": "srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX",
          "rentEpoch": 0,
          "space": 65548
        },
        "pubkey": "5qRKrGPYaQmazdtMnia1iC3gFbpgW4CT7KPrHq9nJGm5"
      }
    },
    "subscription": 0
  }
}
```

{% endtab %}
{% endtabs %}

### signatureSubscribe

{% tabs %}
{% tab title="Request" %}

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "signatureSubscribe",
  "params": [
    "2EBVM6cB8vAAD93Ktr6Vd8p67XPbQzCJX47MpReuiCXJAtcjaxpvWpcg9Ege1Nr5Tk3a2GFrByT7WPBjdsTycY9b",
    {
      "commitment": "processed"
    }
  ]
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "signatureNotification",
  "params": {
    "result": {
      "context": {
        "slot": 206127070
      },
      "value": {
        "err": null
      }
    },
    "subscription": 24006
  }
}
```

{% endtab %}
{% endtabs %}

### slotSubscribe

{% tabs %}
{% tab title="Request" %}

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "slotSubscribe"
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "slotNotification",
  "params": {
    "result": {
      "parent": 206128153,
      "root": 206128115,
      "slot": 206128154
    },
    "subscription": 0
  }
}
```

{% endtab %}
{% endtabs %}

### transactionSubscribe

A Triton extension to the Solana WebSocket API. One subscription returns the full transaction, including metadata, log messages, token balances, and compute units, replacing a `signatureSubscribe` + `getTransaction` loop. Takes a `filter` object (all fields optional) and an optional `config` with the same fields as [`RpcBlockSubscribeConfig`](https://docs.rs/solana-client/latest/solana_client/rpc_config/struct.RpcBlockSubscribeConfig.html), except `transactionDetails: "none"`, which is refused.

{% tabs %}
{% tab title="Request" %}

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "transactionSubscribe",
  "params": [
    {
      "vote": false,
      "failed": false,
      "signature": "2EBVM6cB8vAAD93Ktr6Vd8p67XPbQzCJX47MpReuiCXJAtcjaxpvWpcg9Ege1Nr5Tk3a2GFrByT7WPBjdsTycY9b",
      "accounts": {
        "include": ["5qRKrGPYaQmazdtMnia1iC3gFbpgW4CT7KPrHq9nJGm5"],
        "exclude": ["srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX"],
        "required": ["TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA"]
      }
    },
    {
      "commitment": "processed",
      "encoding": "base64",
      "transactionDetails": "full",
      "showRewards": false,
      "maxSupportedTransactionVersion": 1
    }
  ]
}
```

{% endtab %}

{% tab title="Response" %}

```json
{
  "jsonrpc": "2.0",
  "method": "transactionNotification",
  "params": {
    "result": {
      "context": {
        "slot": 241068727
      },
      "value": {
        "slot": 241068727,
        "transaction": {
          "meta": {
            "computeUnitsConsumed": 27426,
            "err": null,
            "fee": 5000,
            "innerInstructions": [
              {
                "index": 3,
                "instructions": [
                  {
                    "accounts": [
                      7,
                      3,
                      11
                    ],
                    "data": "3DTZbgwsozUF",
                    "programIdIndex": 15,
                    "stackHeight": null
                  },
                  {
                    "accounts": [
                      9,
                      8,
                      11
                    ],
                    "data": "3DTZbgwsozUF",
                    "programIdIndex": 15,
                    "stackHeight": null
                  }
                ]
              }
            ],
            "loadedAddresses": {
              "readonly": [],
              "writable": []
            },
            "logMessages": [
              "Program ComputeBudget111111111111111111111111111111 invoke [1]",
              "Program ComputeBudget111111111111111111111111111111 success",
              "Program GDDMwNyyx8uB6zrqwBFHjLLG3TBYk2F8Az4yrQC5RzMp invoke [1]",
              "Program log: Sequence in order | sequence_num=755609 | last_known=755608",
              "Program GDDMwNyyx8uB6zrqwBFHjLLG3TBYk2F8Az4yrQC5RzMp consumed 3398 of 300000 compute units",
              "Program GDDMwNyyx8uB6zrqwBFHjLLG3TBYk2F8Az4yrQC5RzMp success",
              "Program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX invoke [1]",
              "Program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX consumed 3820 of 296602 compute units",
              "Program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX success",
              "Program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX invoke [1]",
              "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
              "Program log: Instruction: Transfer",
              "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4740 of 285091 compute units",
              "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
              "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA invoke [2]",
              "Program log: Instruction: Transfer",
              "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA consumed 4740 of 277786 compute units",
              "Program TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA success",
              "Program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX consumed 20208 of 292782 compute units",
              "Program srmqPvymJeFKQ4zGQed1GFppgkRHL9kaELCbyksJtPX success"
            ],
            "postBalances": [
              10194778999,
              1224960,
              457104960,
              2039280,
              23357760,
              1825496640,
              3591360,
              2039280,
              2039280,
              2039280,
              457104960,
              0,
              1,
              1141440,
              1141440,
              934087680
            ],
            "postTokenBalances": [
              {
                "accountIndex": 3,
                "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                "owner": "ASx1wk74GLZsxVrYiBkNKiViPLjnJQVGxKrudRgPir4A",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "4973704995974757",
                  "decimals": 5,
                  "uiAmount": 49737049959.74757,
                  "uiAmountString": "49737049959.74757"
                }
              },
              {
                "accountIndex": 7,
                "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                "owner": "3oQLKk1TyyXMT14p2i8p95v5jKqsQ5qzZGwxZCTnFC7p",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "3167826900000000",
                  "decimals": 5,
                  "uiAmount": 31678269000,
                  "uiAmountString": "31678269000"
                }
              },
              {
                "accountIndex": 8,
                "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                "owner": "ASx1wk74GLZsxVrYiBkNKiViPLjnJQVGxKrudRgPir4A",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "148629334218",
                  "decimals": 6,
                  "uiAmount": 148629.334218,
                  "uiAmountString": "148629.334218"
                }
              },
              {
                "accountIndex": 9,
                "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                "owner": "3oQLKk1TyyXMT14p2i8p95v5jKqsQ5qzZGwxZCTnFC7p",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "5797710875",
                  "decimals": 6,
                  "uiAmount": 5797.710875,
                  "uiAmountString": "5797.710875"
                }
              }
            ],
            "preBalances": [
              10194783999,
              1224960,
              457104960,
              2039280,
              23357760,
              1825496640,
              3591360,
              2039280,
              2039280,
              2039280,
              457104960,
              0,
              1,
              1141440,
              1141440,
              934087680
            ],
            "preTokenBalances": [
              {
                "accountIndex": 3,
                "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                "owner": "ASx1wk74GLZsxVrYiBkNKiViPLjnJQVGxKrudRgPir4A",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "4973704995974757",
                  "decimals": 5,
                  "uiAmount": 49737049959.74757,
                  "uiAmountString": "49737049959.74757"
                }
              },
              {
                "accountIndex": 7,
                "mint": "DezXAZ8z7PnrnRJjz3wXBoRgixCa6xjnB7YaB1pPB263",
                "owner": "3oQLKk1TyyXMT14p2i8p95v5jKqsQ5qzZGwxZCTnFC7p",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "3167826900000000",
                  "decimals": 5,
                  "uiAmount": 31678269000,
                  "uiAmountString": "31678269000"
                }
              },
              {
                "accountIndex": 8,
                "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                "owner": "ASx1wk74GLZsxVrYiBkNKiViPLjnJQVGxKrudRgPir4A",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "148629334218",
                  "decimals": 6,
                  "uiAmount": 148629.334218,
                  "uiAmountString": "148629.334218"
                }
              },
              {
                "accountIndex": 9,
                "mint": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v",
                "owner": "3oQLKk1TyyXMT14p2i8p95v5jKqsQ5qzZGwxZCTnFC7p",
                "programId": "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA",
                "uiTokenAmount": {
                  "amount": "5797710875",
                  "decimals": 6,
                  "uiAmount": 5797.710875,
                  "uiAmountString": "5797.710875"
                }
              }
            ],
            "rewards": null,
            "status": {
              "Ok": null
            }
          },
          "transaction": [
            "AY6n3kLw0z...Q2xB1CA==",
            "base64"
          ],
          "version": "legacy"
        }
      }
    },
    "subscription": 0
  }
}
```

{% endtab %}
{% endtabs %}

## Unsubscribe

Every subscribe request returns the subscription `id` on success:

```json
{ "jsonrpc": "2.0", "result": 42, "id": 1 }
```

Pass that `id` to the matching unsubscribe method (`accountUnsubscribe`, `slotUnsubscribe`, and so on):

```json
{ "id": 1, "jsonrpc": "2.0", "method": "slotUnsubscribe", "params": [42] }
```

The result is `true` if the subscription was active and removed:

```json
{ "jsonrpc": "2.0", "result": true, "id": 1 }
```

An `id` that does not exist on the connection returns error `-32602`, `Invalid subscription id.`

## Client

You can find a reference CLI client on GitHub: [WebSocket CLI client](https://github.com/rpcpool/yellowstone-whirligig-client).

## Pricing

WebSocket traffic is billed by the bandwidth it streams, on shared and dedicated endpoints. By default, a dedicated endpoint's WebSocket connections are served by Triton's shared servers, not by your node. See the [pricing page](https://triton.one/pricing).

WebSocket frames are not compressed (no `permessage-deflate`).

To stream less:

* Filter your subscriptions: `filters` on `programSubscribe`, account filters on `transactionSubscribe`.
* Use the `base64+zstd` encoding when bandwidth is limited, not by default. It compresses the account data field, not the whole message, and costs CPU on the server and on your client.

## What's next

<table data-card-size="large" data-view="cards"><thead><tr><th></th><th></th><th data-hidden data-card-target data-type="content-ref"></th></tr></thead><tbody><tr><td><i class="fa-tower-broadcast">:tower-broadcast:</i> <strong>Dragon's Mouth gRPC</strong></td><td>Sub-slot real-time updates for accounts, transactions, slots, and blocks via gRPC.</td><td><a href="/solana/real-time-streaming/dragon-s-mouth-grpc.md">Dragon's Mouth gRPC</a></td></tr><tr><td><i class="fa-list-check">:list-check:</i> <strong>Real-time streaming best practices</strong></td><td>Filtering, reconnect, and commitment guidance across the streaming services.</td><td><a href="/solana/real-time-streaming/best-practices.md">Real-time streaming best practices</a></td></tr></tbody></table>

***

<i class="fa-life-ring">:life-ring:</i> Contact support by clicking the chat icon in your [customer dashboard](https://customers.triton.one)\ <i class="fa-briefcase">:briefcase:</i> Sales questions? [Contact us](https://triton.one/contact)\ <i class="fa-sparkles">:sparkles:</i> AI agent? Read [llms.txt](https://docs.triton.one/llms.txt)\ <i class="fa-rss">:rss:</i> Follow updates: [Blog](https://blog.triton.one) · [X](https://x.com/triton_one) · [YouTube](https://www.youtube.com/@triton_one_ltd) · [Telegram](https://t.me/tritonone) · [GitHub](https://github.com/rpcpool)
