> ## Documentation Index
> Fetch the complete documentation index at: https://docs.mobula.io/llms.txt
> Use this file to discover all available pages before exploring further.

# Token Details Stream

> Real-time WebSocket stream for multiple tokens with enriched market data

<Tip> This endpoint is only available to Growth and Enterprise plans. </Tip>

<Warning>
  **Not suitable for real-time chart animation.**

  `token-details` is an **enriched but slow stream** — it delivers aggregated token data (volumes, holder stats, price changes, etc.) recomputed on each trade, which introduces significant processing latency. Updates may arrive **up to  1 second after a trade**.

  **If you want to animate a live price chart**, use [`fast-trade`](/indexing-stream/stream/websocket/wss-fast-trades) instead:

  * Trades arrive in **near real-time** (sub-second latency)
  * Minimal payload — price, amount, type, hash
  * Designed for high-frequency rendering

  Use `token-details` for dashboards, token screeners, or any UI that needs enriched stats (volume, buys/sells counts, holder percentages) but does **not** require tick-level speed.
</Warning>

## Endpoint Details

* **URL**: `wss://api.mobula.io`
* **Event Type**: `token-details`

## Subscription Formats

The `token-details` endpoint supports subscribing to multiple token addresses for real-time token data.

### Multiple Tokens Subscription (Recommended)

Subscribe to multiple tokens using the `tokens` array format:

```json theme={null}
{
  "type": "token-details",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "tokens": [
      {
        "blockchain": "solana",
        "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
      },
      {
        "blockchain": "solana",
        "address": "EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v"
      },
      {
        "blockchain": "evm:1",
        "address": "0x1234567890abcdef1234567890abcdef12345678"
      }
    ],
    "subscriptionTracking": true
  }
}
```

## Parameters

* **`tokens`** (required): Array of token subscription items, each containing:
  * **`blockchain`** (required): Blockchain identifier (e.g., `"evm:1"`, `"solana"`)
  * **`address`** (required): Token address
* **`subscriptionId`** (optional): Unique identifier for your WebSocket connection. Auto-generated if not provided
* **`subscriptionTracking`** (optional, default: `false`): Include subscription details in response logs for debugging
* **`maxUpdatesPerMinute`** (optional): Limit how often the server sends updates for each token. See [Update Rate Throttling](#update-rate-throttling) below
* **`filterOutliers`** (optional, default: `false`): When `true`, drops dust trades and price outliers that would otherwise overwrite `tokenData.priceUSD` in the broadcast payload. See [Outlier Filtering](#outlier-filtering) below

<Note>
  **Token Addresses Only**: This endpoint is for subscribing to token addresses. For pool-specific subscriptions, use the `market-details` endpoint instead.
</Note>

## Real-Time Updates

After subscribing, you'll receive real-time updates whenever new trades occur involving the subscribed tokens.

### Real-Time Trade Updates for Token Subscriptions

When trades happen involving subscribed tokens, you'll receive updates with trade information:

```json theme={null}
{
  "pair": "0x1234567890abcdef1234567890abcdef12345678",
  "date": 1704067800000,
  "token_price": 0.0234,
  "token_price_vs": 2500.75,
  "token_amount": 1000.0,
  "token_amount_vs": 0.4,
  "token_amount_usd": 23.40,
  "type": "sell",
  "operation": "regular",
  "blockchain": "Ethereum",
  "hash": "0xdef789abc012...",
  "sender": "0x1234567890abcdef...",
  "token_amount_raw": "1000000000000000000000",
  "token_amount_raw_vs": "400000000000000000",
  "labels": ["sniper", "proTrader"],
  "walletMetadata": {
    "entityName": "Wintermute",
    "entityLogo": "https://example.com/wintermute.png",
    "entityLabels": ["market-maker"],
    "entityType": "market_maker",
    "entityDescription": "Wintermute is a leading global algorithmic trading firm",
    "entityTwitter": "https://twitter.com/wintermute_t",
    "entityWebsite": "https://wintermute.com",
    "entityGithub": null,
    "entityDiscord": null,
    "entityTelegram": null
  },
  "preBalanceBaseToken": "5000000000000000000000",
  "preBalanceQuoteToken": "2000000000000000000",
  "postBalanceBaseToken": "4000000000000000000000",
  "postBalanceQuoteToken": "2400000000000000000",
  "swapRecipient": null,
  "platform": "axiom",
  "platformMetadata": {
    "id": "axiom",
    "name": "Axiom",
    "logo": "https://example.com/axiom.png"
  },
      "tokenData": {
    // Complete EnrichedTokenData structure with all fields from TokenDetailsOutput.ts
    "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump",
    "chainId": "solana",
    "symbol": "EXAMPLE",
    "name": "Example Token",
    "decimals": 9,
    "id": 12345,
    "priceUSD": 0.0234,
    "priceToken": 43.21,
    "priceTokenString": "43.210000000000000000000000000000",
    "approximateReserveUSD": 125000.50,
    "approximateReserveTokenRaw": "5000000000000000000",
    "approximateReserveToken": 5000.0,
    "totalSupply": 1000000000,
    "circulatingSupply": 800000000,
    "marketCapUSD": 18720000,
    "marketCapDilutedUSD": 23400000,
    "logo": "https://example.com/token-logo.png",
    "exchange": {
      "name": "Uniswap V3",
      "logo": "https://example.com/uniswap-logo.png"
    },
    "factory": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
    "source": "uniswap",
    "sourceFactory": "0x1F98431c8aD98523631AE4a59f267346ea31F984",
    "liquidityUSD": 250000.75,
    "liquidityMaxUSD": 300000.0,
    "bonded": false,
    "bondingPercentage": 0,
    "bondingCurveAddress": null,
    "preBondingFactory": null,
    "poolAddress": null,
    "top10HoldingsPercentage": 45.6,
    "top50HoldingsPercentage": 68.9,
    "top100HoldingsPercentage": 78.5,
    "top200HoldingsPercentage": 85.2,
    "devHoldingsPercentage": 15.5,
    "insidersHoldingsPercentage": 8.2,
    "bundlersHoldingsPercentage": 2.8,
    "snipersHoldingsPercentage": 3.1,
    "proTradersHoldingsPercentage": 5.0,
    "blockchain": "solana",
    "type": "token",
    "deployer": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump",
    "bondedAt": null,
    "athUSD": 0.0456,
    "atlUSD": 0.0012,
    "athDate": "2024-12-15T10:30:00.000Z",
    "atlDate": "2024-12-01T00:00:00.000Z",
    "priceChange1minPercentage": 0.5,
    "priceChange5minPercentage": -1.2,
    "priceChange1hPercentage": 3.4,
    "priceChange4hPercentage": 2.1,
    "priceChange6hPercentage": 1.8,
    "priceChange12hPercentage": 0.9,
    "priceChange24hPercentage": -5.8,
    "liquidityBurnPercentage": 100,
    "volume1minUSD": 1250.75,
    "volume5minUSD": 8500.25,
    "volume15minUSD": 42500.80,
    "volume1hUSD": 45000.80,
    "volume4hUSD": 180000.25,
    "volume6hUSD": 270000.40,
    "volume12hUSD": 540000.50,
    "volume24hUSD": 890000.50,
    "volumeBuy1minUSD": 675.50,
    "volumeBuy5minUSD": 4500.25,
    "volumeBuy15minUSD": 22500.40,
    "volumeBuy1hUSD": 24000.40,
    "volumeBuy4hUSD": 96000.15,
    "volumeBuy6hUSD": 144000.25,
    "volumeBuy12hUSD": 288000.30,
    "volumeBuy24hUSD": 480000.25,
    "volumeSell1minUSD": 575.25,
    "volumeSell5minUSD": 4000.00,
    "volumeSell15minUSD": 20000.40,
    "volumeSell1hUSD": 21000.40,
    "volumeSell4hUSD": 84000.10,
    "volumeSell6hUSD": 126000.15,
    "volumeSell12hUSD": 252000.20,
    "volumeSell24hUSD": 410000.25,
    "trades1min": 15,
    "trades5min": 85,
    "trades15min": 425,
    "trades1h": 450,
    "trades4h": 1800,
    "trades6h": 2700,
    "trades12h": 5400,
    "trades24h": 8900,
    "buys1min": 8,
    "buys5min": 45,
    "buys15min": 225,
    "buys1h": 240,
    "buys4h": 960,
    "buys6h": 1440,
    "buys12h": 2880,
    "buys24h": 4800,
    "sells1min": 7,
    "sells5min": 40,
    "sells15min": 200,
    "sells1h": 210,
    "sells4h": 840,
    "sells6h": 1260,
    "sells12h": 2520,
    "sells24h": 4100,
    "buyers1min": 8,
    "buyers5min": 42,
    "buyers15min": 210,
    "buyers1h": 235,
    "buyers4h": 940,
    "buyers6h": 1410,
    "buyers12h": 2820,
    "buyers24h": 4650,
    "sellers1min": 7,
    "sellers5min": 38,
    "sellers15min": 190,
    "sellers1h": 205,
    "sellers4h": 820,
    "sellers6h": 1230,
    "sellers12h": 2460,
    "sellers24h": 3950,
    "traders1min": 14,
    "traders5min": 78,
    "traders15min": 390,
    "traders1h": 420,
    "traders4h": 1680,
    "traders6h": 2520,
    "traders12h": 5040,
    "traders24h": 8200,
    "feesPaid1minUSD": 6.25,
    "feesPaid5minUSD": 42.5,
    "feesPaid15minUSD": 212.5,
    "feesPaid1hUSD": 225.0,
    "feesPaid4hUSD": 900.0,
    "feesPaid6hUSD": 1350.0,
    "feesPaid12hUSD": 2700.0,
    "feesPaid24hUSD": 4450.0,
    "totalFeesPaidUSD": 8900.0,
    "organicTrades1min": 12,
    "organicTrades5min": 68,
    "organicTrades15min": 340,
    "organicTrades1h": 360,
    "organicTrades4h": 1440,
    "organicTrades6h": 2160,
    "organicTrades12h": 4320,
    "organicTrades24h": 7120,
    "organicTraders1min": 11,
    "organicTraders5min": 62,
    "organicTraders15min": 310,
    "organicTraders1h": 335,
    "organicTraders4h": 1340,
    "organicTraders6h": 2010,
    "organicTraders12h": 4020,
    "organicTraders24h": 6560,
    "organicVolume1minUSD": 1000.6,
    "organicVolume5minUSD": 6800.2,
    "organicVolume15minUSD": 34000.64,
    "organicVolume1hUSD": 36000.64,
    "organicVolume4hUSD": 144000.2,
    "organicVolume6hUSD": 216000.32,
    "organicVolume12hUSD": 432000.4,
    "organicVolume24hUSD": 712000.4,
    "organicVolumeBuy1minUSD": 540.32,
    "organicVolumeBuy5minUSD": 3600.16,
    "organicVolumeBuy15minUSD": 18000.32,
    "organicVolumeBuy1hUSD": 19200.32,
    "organicVolumeBuy4hUSD": 76800.12,
    "organicVolumeBuy6hUSD": 115200.2,
    "organicVolumeBuy12hUSD": 230400.24,
    "organicVolumeBuy24hUSD": 384000.2,
    "organicVolumeSell1minUSD": 460.28,
    "organicVolumeSell5minUSD": 3200.04,
    "organicVolumeSell15minUSD": 16000.32,
    "organicVolumeSell1hUSD": 16800.32,
    "organicVolumeSell4hUSD": 67200.08,
    "organicVolumeSell6hUSD": 100800.12,
    "organicVolumeSell12hUSD": 201600.16,
    "organicVolumeSell24hUSD": 328000.2,
    "organicBuys1min": 6,
    "organicBuys5min": 36,
    "organicBuys15min": 180,
    "organicBuys1h": 192,
    "organicBuys4h": 768,
    "organicBuys6h": 1152,
    "organicBuys12h": 2304,
    "organicBuys24h": 3840,
    "organicSells1min": 6,
    "organicSells5min": 32,
    "organicSells15min": 160,
    "organicSells1h": 168,
    "organicSells4h": 672,
    "organicSells6h": 1008,
    "organicSells12h": 2016,
    "organicSells24h": 3280,
    "organicBuyers1min": 6,
    "organicBuyers5min": 33,
    "organicBuyers15min": 165,
    "organicBuyers1h": 188,
    "organicBuyers4h": 752,
    "organicBuyers6h": 1128,
    "organicBuyers12h": 2256,
    "organicBuyers24h": 3720,
    "organicSellers1min": 6,
    "organicSellers5min": 30,
    "organicSellers15min": 152,
    "organicSellers1h": 164,
    "organicSellers4h": 656,
    "organicSellers6h": 984,
    "organicSellers12h": 1968,
    "organicSellers24h": 3168,
    "createdAt": "2024-12-01T00:00:00.000Z",
    "latestPriceUSD": 0.0234,
    "holdersCount": 1250,
    "description": "Example token description",
    "socials": {
      "twitter": "https://twitter.com/example",
      "website": "https://example.com",
      "telegram": "https://t.me/example",
      "others": {},
      "uri": "https://example.com/token"
    },
    "security": {
      "buyTax": "5.00",
      "sellTax": "10.00",
      "transferPausable": false,
      "top10Holders": "42.50",
      "isBlacklisted": false,
      "isHoneypot": false,
      "isNotOpenSource": false,
      "renounced": true,
      "locked": "80.00",
      "isWhitelisted": false,
      "balanceMutable": false,
      "lowLiquidity": "false",
      "burnRate": "2.50",
      "isMintable": false,
      "modifyableTax": false,
      "selfDestruct": false,
      "liquidityBurnPercentage": 75.5,
      "noMintAuthority": true
    },
    "twitterReusesCount": 0,
    "twitterRenameCount": 0,
    "twitterRenameHistory": [],
    "deployerMigrationsCount": 0,
    "dexscreenerListed": true,
    "dexscreenerHeader": null,
    "dexscreenerAdPaid": false,
    "isMayhemMode": null,
    "isCashbackCoin": null,
    "isAgentMode": null,
    "isOGCoin": true
  },
  "subscriptionId": "sub_abc123",
  "updated": true,
  "timestamp": 1704067800000
}
```

### Optional Fields Behavior

<Warning>
  **Fields may be entirely absent, not `null`**: Several fields in trade update messages are **conditionally included** — when there is no data, the field is **completely omitted** from the JSON payload rather than being set to `null` or an empty value.

  This applies to:

  * **`labels`**: Only present when the sender wallet has known labels for this token. If absent, the sender has no labels.
  * **`walletMetadata`**: Only present when the sender wallet has entity metadata (e.g., known entity like Wintermute, Binance). If absent, no entity info is available.

  Always use optional chaining or check for field existence:

  ```typescript theme={null}
  // Correct
  const labels = data.labels ?? [];
  const entityName = data.walletMetadata?.entityName ?? null;

  // Incorrect — will throw if field is missing
  const labels = data.labels; // undefined, not []
  ```
</Warning>

## Security Object Fields

All fields in `tokenData.security` are **optional** — only present when data is available for the token. A missing field means the check was not performed, not that the token is safe.

<Note>
  **EVM vs Solana availability**: Most fields apply to EVM chains. `noMintAuthority` is Solana-specific. `isHoneypot`, `isNotOpenSource`, `renounced`, `locked`, `isWhitelisted`, `isMintable`, `modifyableTax`, and `selfDestruct` are EVM-only.
</Note>

| Field                     | Type      | Description                                                                                                                          |
| ------------------------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `buyTax`                  | `string`  | Buy fee as a percentage string (e.g. `"5.00"` = 5%). Present when a transfer tax is charged on buys.                                 |
| `sellTax`                 | `string`  | Sell fee as a percentage string (e.g. `"10.00"` = 10%). Present when a transfer tax is charged on sells.                             |
| `transferPausable`        | `boolean` | Whether the contract owner can pause all token transfers.                                                                            |
| `top10Holders`            | `string`  | Percentage of total supply held by the top 10 wallets (e.g. `"42.50"`).                                                              |
| `isBlacklisted`           | `boolean` | Whether the contract contains a blacklist mechanism that can block specific addresses from trading.                                  |
| `isHoneypot`              | `boolean` | Whether the token is a honeypot — users can buy but cannot sell. *(EVM only)*                                                        |
| `isNotOpenSource`         | `boolean` | Whether the contract source code is not verified/open source on-chain. *(EVM only)*                                                  |
| `renounced`               | `boolean` | Whether contract ownership has been renounced (owner is the zero address). *(EVM only)*                                              |
| `locked`                  | `string`  | Percentage of liquidity that is locked (e.g. `"80.00"`). *(EVM only)*                                                                |
| `isWhitelisted`           | `boolean` | Whether the contract has a whitelist mechanism restricting who can trade. *(EVM only)*                                               |
| `balanceMutable`          | `boolean` | Whether the contract owner can arbitrarily modify token balances.                                                                    |
| `lowLiquidity`            | `string`  | Indicates low liquidity status (e.g. `"true"` or `"false"`).                                                                         |
| `burnRate`                | `string`  | Percentage of each transaction automatically burned (e.g. `"2.50"`).                                                                 |
| `isMintable`              | `boolean` | Whether the contract allows minting new tokens after deployment. *(EVM only)*                                                        |
| `modifyableTax`           | `boolean` | Whether the contract owner can change the buy/sell tax rates. *(EVM only)*                                                           |
| `selfDestruct`            | `boolean` | Whether the contract contains a self-destruct function. *(EVM only)*                                                                 |
| `liquidityBurnPercentage` | `number`  | Percentage of liquidity pool tokens that have been burned (legacy — prefer the top-level `liquidityBurnPercentage` described below). |
| `noMintAuthority`         | `boolean` | Whether the mint authority has been disabled (safe = `true`). *(Solana only)*                                                        |

### Liquidity Burn

| Field                     | Type             | Description                                                                                                                                                                                                                                                        |
| ------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `liquidityBurnPercentage` | `number \| null` | Share of LP tokens (V2) or position liquidity (V3/V4) held by dead/locker addresses **for the largest pool**. Computed from on-chain LP holder balances — no longer sourced from GoPlus. `null` until the LP-burn cache is warmed for this token. Range `0`–`100`. |

## Unsubscribing from the Stream

### Unsubscribe from All Token-Details Streams

```json theme={null}
{
  "type": "unsubscribe",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "type": "token-details"
  }
}
```

### Unsubscribe from Specific Subscription

```json theme={null}
{
  "type": "unsubscribe",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "subscriptionId": "sub_abc123"
  }
}
```

### Unsubscribe from Specific Subscription with Type

```json theme={null}
{
  "type": "unsubscribe",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "type": "token-details",
    "subscriptionId": "sub_abc123"
  }
}
```

### Unsubscribe from Specific Tokens (Partial Unsubscription)

You can unsubscribe from specific tokens while keeping others active in the same subscription:

```json theme={null}
{
  "type": "unsubscribe",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "type": "token-details",
    "tokens": [
      {
        "blockchain": "solana",
        "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
      }
    ]
  }
}
```

### Unsubscribe from Multiple Specific Tokens

```json theme={null}
{
  "type": "unsubscribe",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "type": "token-details",
    "tokens": [
      {
        "blockchain": "solana",
        "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
      },
      {
        "blockchain": "evm:1",
        "address": "0x1234567890abcdef1234567890abcdef12345678"
      }
    ]
  }
}
```

### Unsubscribe from Specific Tokens in a Specific Subscription

```json theme={null}
{
  "type": "unsubscribe",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "type": "token-details",
    "subscriptionId": "sub_abc123",
    "tokens": [
      {
        "blockchain": "solana",
        "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
      }
    ]
  }
}
```

<Note>
  If you didn't provide a `subscriptionId` when subscribing, one is auto-generated. To retrieve it, set `"subscriptionTracking": true` in the subscription payload.

  For partial unsubscriptions without `subscriptionId`, the system will automatically find and modify subscriptions that contain the specified tokens, leaving other tokens in those subscriptions active.
</Note>

## Update Rate Throttling

You can control how frequently the server sends update messages per token using the `maxUpdatesPerMinute` field. This is useful for reducing bandwidth on dashboards that don't need every single trade update.

```json theme={null}
{
  "type": "token-details",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "tokens": [
      {
        "blockchain": "solana",
        "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
      }
    ],
    "maxUpdatesPerMinute": 60
  }
}
```

### How It Works

Despite the name, `maxUpdatesPerMinute` does **not** set a budget that gets consumed over a minute. Instead, it sets a **minimum interval between delivered updates** per token:

```
interval = 60 000ms / maxUpdatesPerMinute
```

For example, `maxUpdatesPerMinute: 100` → minimum interval of **600ms** between two delivered updates for the same token.

* **Interval-based, not budget-based**: The server enforces a cooldown between updates. Once an update is delivered, all subsequent updates for that token are dropped until the interval elapses. There is no counter that depletes — after each delivered update, the cooldown simply restarts.
* **Per-token throttle**: Each token is throttled independently. Subscribing to 5 tokens with `maxUpdatesPerMinute: 60` means each token sends at most 1 update/second.
* **Dropped, not buffered**: When an update arrives during the cooldown, it is silently dropped — not queued or aggregated. The next update arriving **after** the interval has elapsed will be delivered normally.

### Burst Behavior Example

With `maxUpdatesPerMinute: 100` (interval = 600ms), if a token receives a burst of 50 updates in 1 second:

| Time    | Event                  | Result                                        |
| ------- | ---------------------- | --------------------------------------------- |
| t=0ms   | Update 1 arrives       | **Delivered** (cooldown starts)               |
| t=50ms  | Updates 2–10 arrive    | **Dropped** (still within 600ms cooldown)     |
| t=600ms | Update \~20 arrives    | **Delivered** (cooldown elapsed, restarts)    |
| t=800ms | Updates \~25–50 arrive | **Dropped** (still within new 600ms cooldown) |
| t=2s    | Next update arrives    | **Delivered** normally                        |

You receive \~2 updates from the burst, and updates resume normally afterwards. There is **no debt or penalty** — the throttle does not "remember" dropped updates or block future delivery.

### Reference Values

| `maxUpdatesPerMinute` | Effective interval | Description                               |
| --------------------- | ------------------ | ----------------------------------------- |
| 600                   | 100ms              | Maximum rate (\~10 updates/sec per token) |
| 60                    | 1s                 | One update per second per token           |
| 6                     | 10s                | One update every 10 seconds               |
| 1                     | 60s                | One update per minute (minimum rate)      |

<Note>
  When `maxUpdatesPerMinute` is not provided, no throttle is applied and updates are delivered as fast as they arrive.
</Note>

## Outlier Filtering

When `filterOutliers` is set to `true`, the server applies the same outlier detection used by the `fast-trade` and OHLCV streams. This is important for `token-details` specifically: each broadcast trade **overrides** `tokenData.priceUSD` in the payload with that trade's computed price — so a single dust or low-liquidity swap can otherwise pollute your UI price.

```json theme={null}
{
  "type": "token-details",
  "authorization": "YOUR-API-KEY",
  "payload": {
    "filterOutliers": true,
    "tokens": [
      {
        "blockchain": "solana",
        "address": "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
      }
    ]
  }
}
```

### What Gets Filtered

| Filter                    | Condition                                         | Purpose                                                                        |
| ------------------------- | ------------------------------------------------- | ------------------------------------------------------------------------------ |
| **Dust trades**           | `amountUSD <= $0.10`                              | Removes near-zero trades that can print false prices                           |
| **Non-regular swaps**     | `swapType != REGULAR`                             | Removes LP deposits/withdrawals                                                |
| **Extreme prices**        | Price > 3.4e30 or \< 1e-16                        | Removes UniV3/CLMM edge-case prices                                            |
| **Low-volume multi-pool** | `amountUSD <= $100` on tokens with multiple pools | Removes small trades on low-liquidity pools that deviate from the market price |

<Note>
  When `filterOutliers` is `false` (default), every trade is delivered — including dust and edge-case prints. Existing clients keep the same behavior as before this flag was introduced.
</Note>

<Tip>
  If every trade in a batch gets filtered out, the stream falls back to a compact snapshot message `{ token, subscriptionId, updated: true, timestamp }` (no `hash`/`token_price` fields). Your UI still gets a refreshed server-side aggregate price instead of a polluted per-trade print.
</Tip>

## Implementation Example

```typescript theme={null}
const socket = new WebSocket("wss://api.mobula.io");

socket.addEventListener("open", () => {
  socket.send(JSON.stringify({
    type: "token-details",
    authorization: "YOUR_API_KEY",
    payload: {
      tokens: [
        {
          blockchain: "solana",
          address: "3vz82EWYv8xnc7Cm7qSgERcpMeqw92PcX8PBz88npump"
        }
      ],
      subscriptionTracking: true
    }
  }));
});

socket.addEventListener("message", (event) => {
  const data = JSON.parse(event.data);
  
  // Process token update
  if (data.tokenData) {
    console.log("Token update:", data.tokenData);
    console.log(`Price: $${data.tokenData.priceUSD}`);
    console.log(`24h Volume: $${data.tokenData.volume24hUSD}`);
  }
});

socket.addEventListener("error", (error) => {
  console.error("WebSocket error:", error);
});

socket.addEventListener("close", () => {
  console.log("WebSocket connection closed");
});
```

<Tip>You can use the Network tab in your browser to see the WebSocket requests and responses in real-time.</Tip>

## Connection Keepalive (Ping/Pong)

To maintain active WebSocket connections and prevent timeouts, you can use the ping/pong mechanism:

**Send ping:**

```json theme={null}
{"event":"ping"}
```

**Receive pong:**
The server will respond with a pong message to confirm the connection is active.

<Tip>Use ping messages periodically (every 30-60 seconds) to keep long-lived connections alive.</Tip>

## Support

Can't find what you're looking for? Reach out to us, response times \< 1h.

<CardGroup>
  <Card title="Support" icon="Telegram" href="https://t.me/mobuladevelopers?start=Mobula_API_Support_Key">
    Telegram
  </Card>

  <Card title="Support" icon="Slack" href="https://join.slack.com/t/mobulaapi/shared_invite/zt-29zrrpjnl-I0tyD73sy7zKy8q~KLL3Ug">
    Slack
  </Card>

  <Card title="Need help?" icon="envelope" href="mailto:contact@mobulalabs.org">
    Email
  </Card>
</CardGroup>
