Skip to main content
This endpoint is only available to Growth and Enterprise plans.

Product demo

Coming soon.

Endpoint Details

Mobula now provides two dedicated WSS endpoints Why? Because EVM and Solana work very differently under the hood. If we tried to send both through a single WebSocket channel, things would get messy:
  • The event queue would get backed up under heavy traffic
  • Messages would arrive slower or even drop
  • Scaling would be harder since both ecosystems compete for the same resources
By keeping them separate, you get:
  • Faster and more reliable streams
  • Independent scaling (EVM traffic won’t affect Solana, and vice-versa)
  • Stable event delivery, even when network activity spikes
You cannot mix Solana subscriptions on the EVM endpoint (and vice-versa).
Always use the correct endpoint for the chain you’re working with.

EVM Chains

  • Endpoint: wss://stream-evm-prod.mobula.io/
  • Supported events: swap, transfer, swap-enriched
  • Subscription Payload:
This stream will capture all transfers & swaps and enriched swaps received by a specific address.
The EVM address in the filters must be lowercase.
{ 
    "type": "stream",
    "authorization": "YOUR_API_KEY",
    "payload": {
      "name": "MyWalletEvmTransactions",
      "chainIds": ["evm:6342"],
      "events": ["swap", "transfer", "swap-enriched"],
      "filters": { "eq": ["transactionTo", "0xd36b20c9dd8ffe68ed6078204dea8862d147193e"] },
      "subscriptionTracking":"true"
    }
}

SVM Chains

  • Endpoint: wss://stream-sol-prod.mobula.io/
  • Supported events: swap, transfer, swap-enriched
  • Subscription Payload:
{ 
    "type": "stream",
    "authorization": "YOUR_API_KEY",
    "payload": {
      "name": "MyWalletEvmTransactions",
      "chainIds": ["solana:solana"],
      "events": ["swap", "transfer"],
      "subscriptionTracking":"true"
    }
}

Usage Examples

Before diving into the examples, make sure to check the data models for both EVM and SVM chains for swaps and transfers.
Pro Tip for Devs: Dive into these data models and experiment with filters — your imagination is the only limit! Mix and / or, combine keys, and watch your streams come alive!
  • Explore poolType, poolAddress, transactionFrom, transactionTo, and other keys in the data models.
  • Combine multiple conditions using and / or operators to capture exactly the events you want.
  • Mix and match filters across swaps and transfers to suit your application needs.

Filter Swaps by Pools

This stream captures all swaps from either raydium or raydium-clmm pools.
{ 
    "type": "stream",
    "authorization": "YOUR_API_KEY",
    "payload": {
      "name": "MyWalletSolTransactions",
      "chainIds": ["solana:solana"],
      "events": ["swap"],
      "filters": {
        "or": [
          {"eq": ["poolType", "raydium"]},
          {"eq": ["poolType", "raydium-clmm"]}
        ]
      },
      "subscriptionTracking":"true"
    }
}

Filter Swap-Enriched by Pools

This stream captures all swap-enriched events from either raydium or raydium-clmm pools. The returned data is enriched, including:
  • Derived swap view
  • Base and quote token details
  • Token metadata
{
  "type": "stream",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "name": "MyWalletSolTransactions",
    "chainIds": ["solana:solana"],
    "events": ["swap-enriched"],
    "filters": {
      "or": [
        { "eq": ["poolType", "raydium"] },
        { "eq": ["poolType", "raydium-clmm"] }
      ]
    },
    "subscriptionTracking": "true"
  }
}

Filter Transfer by Contract Address

This stream captures all swaps for a specific poolAddress and poolType.
{ 
    "type": "stream",
    "authorization": "YOUR_API_KEY",
    "payload": {
      "name": "MyWalletSolTransactions",
      "chainIds": ["solana:solana"],
      "events": ["transfer"],
      "filters": {
        "and": [
          {"eq": ["poolType", "pumpswap"]},
          {"eq": ["poolAddress", "68L2iPWLtkRuxhHBYVJLSzaApBVuM6DNqLL1pEywbDGR"]}
        ]
      },
      "subscriptionTracking":"true"
    }
}

Filter Transfers by Sender

This stream captures all transfers sent to a specific address.
{ 
    "type": "stream",
    "authorization": "YOUR_API_KEY",
    "payload": {
      "name": "MyWalletTransactions",
      "chainIds": ["solana:solana"],
      "events": ["transfer"],
      "filters": { "eq": ["transactionTo", "ASde6y8pBCU1aityWHRpqT7pEAcEonjCgFUMeh5egRes"] },
      "subscriptionTracking":"true"
    }
}

Filter Transfers From Sender and Receiver

This stream captures all transfers sent from or received by specific addresses.
{ 
    "type": "stream",
    "authorization": "YOUR_API_KEY",
    "payload": {
      "name": "MyWalletSolTransactions",
      "chainIds": ["solana:solana"],
      "events": ["transfer"],
      "filters": {
        "or": [
          {"eq": ["transactionFrom", "2zqLokC98qfedXyXZHeL4sEdFcmmTFizvb1UQeRweWxp"]},
          {"eq": ["transactionTo", "suqh5sHtr8HyJ7q8scBimULPkPpA557prMG47xCHQfK"]}
        ]
      },
      "subscriptionTracking":"true"
    }
}

Filter Swaps by Pool Address (Batch)

This stream listens for all swap events associated with one or more specific poolAddress values.
  • Using the "in" filter lets you efficiently capture swaps where the poolAddress matches any address in your provided list.
  • You can also apply similar logic to other fields such as from, to, or poolType — depending on what aspect of the swap you want to track.
{
  "type": "stream",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "name": "MyWalletEvmTransactions",
    "chainIds": ["evm:8453"],
    "events": ["swap"],
    "filters": {
      "or": [
        {
          "in": [
            "poolAddress",
            [
              "0xd0b53d9277642d899df5c87a3966a349a798f224",
              "0xedc625b74537ee3a10874f53d170e9c17a906b9c",
              "0x76fa2b719cad87970ed6a5948abd23a474aa092cfd99ba362b7c9f53880f3cac"
            ]
          ]
        }
      ]
    },
    "subscriptionTracking": "true"
  }
}

Filter Swaps by Pool Type and Sender Address

This stream tracks all swap events that match specific poolType values and originate from one or more given swapSenderAddress values.
It’s perfect if you want to monitor swap activity from certain wallets while limiting results to specific pool categories (like Uniswap pools).
By combining "in" filters inside an "and" block, you can precisely define your tracking logic:
  • Only capture swaps from specific wallet addresses
  • AND make sure they belong to one of your target DEX pool types
This gives you a flexible way to analyze user trading behavior or build custom real-time monitoring systems.
{
  "type": "stream",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "name": "MyWalletEvmTransactions",
    "chainIds": ["evm:8453"],
    "events": ["swap"],
    "filters": {
      "and": [
        {
          "in": [
            "poolType",
            [
              "uniswap-v2",
              "uniswap-v4",
              "uniswap-v3"
            ]
          ]
        },
        {
          "in": [
            "swapSenderAddress",
            [
              "0xd0b53d9277642d899df5c87a3966a349a798f224",
              "0xa6b579684e943f7d00d616a48cf99b5147fc57a5",
              "0xc88b2264d3ac0456a4863bf021de4e8ee1129a6b"
            ]
          ]
        }
      ]
    },
    "subscriptionTracking": "true"
  }
}

Parameters

  • chainIds (required): Array of blockchain identifiers - See supported chains
  • events (required): Array of event types - swap, transfer, swap-enriched
  • filters (optional): Filter conditions for events - See filter documentation
  • 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

Implementation Example

const socket = new WebSocket("wss://stream-evm-prod.mobula.io/");

socket.addEventListener("open", () => {
  socket.send(JSON.stringify({
    type: "stream",
    authorization: "YOUR_API_KEY",
    payload: {
      chainIds: ["evm:1", "evm:56"],
      events: ["swap", "transfer"],
      subscriptionTracking: true
    }
  }));
});

socket.addEventListener("message", (event) => {
  const data = JSON.parse(event.data);
  
  if (data.reorg) {
    // Handle blockchain reorganization
    console.log("Reorg detected:", data);
    return;
  }
  
  // Process normal events
  console.log("Event received:", data);
});

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

socket.addEventListener("close", () => {
  console.log("WebSocket connection closed");
});
You can use the Network tab in your browser to see the WebSocket requests and responses in real-time.

Unsubscribing from the Stream

Unsubscribe from All Streams

To terminate all active subscriptions on the current WebSocket connection:
{
  "type": "unsubscribe",
  "authorization": "YOUR_API_KEY",
  "payload": {}
}

Unsubscribe from Specific Subscription

To unsubscribe from a specific subscription using its ID:
{
  "type": "unsubscribe",
  "authorization": "YOUR_API_KEY",
  "payload": {
    "subscriptionId": "your-subscription-id"
  }
}
If you didn’t provide a subscriptionId when subscribing, one is auto-generated. To retrieve it, set "subscriptionTracking": true in the subscription payload.

Support

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