WebSocket Streaming Overview
Real-time blockchain data streaming via WebSocket for transactions, blocks, and account updates
WebSocket Streaming
FortiBlox provides WebSocket streaming for real-time X1 Blockchain data through the Geyser plugin. Stream transactions, blocks, accounts, and slots with sub-100ms latency.
What is WebSocket Streaming?
WebSocket streaming gives you a persistent, bidirectional connection to receive real-time blockchain events as they happen. Unlike polling REST APIs, WebSocket provides push-based updates with minimal latency and efficient bandwidth usage.
Beta Feature - Broadcast Mode
Current Implementation: WebSocket currently broadcasts all network transactions to connected clients. Subscription filtering (by account, program, commitment level) is coming in a future update. Simply connect and you'll receive all transactions automatically.
Key Features
- ✅ Real-time transaction streaming - Get notified of all network transactions instantly
- ✅ Low latency - Sub-100ms event delivery
- ✅ Efficient - Persistent connection for continuous streaming
- ✅ Free tier included - 5 concurrent connections on all plans
- ✅ No credit cost - WebSocket messages don't consume API credits
Use Cases
Real-Time Network Monitoring
- Monitor all network transactions as they occur
- Track transaction volume and patterns
- Build network analytics dashboards
- Detect unusual network activity
Data Aggregation
- Collect full transaction data for analysis
- Build transaction indexes
- Create historical datasets
- Power blockchain explorers
Trading Bots
- React to market conditions in real-time
- Track high-value transactions instantly
- Monitor network congestion
- Filter transactions client-side for specific strategies
Need Account/Program Filtering?
For monitoring specific accounts or programs, use the Geyser REST API to query filtered historical data. WebSocket currently provides the full transaction stream, which you can filter client-side.
Quick Example
// Browser WebSocket (uses query parameter for auth)
const ws = new WebSocket(
'wss://nexus.fortiblox.com/geyser/ws?api-key=fbx_YOUR_KEY_HERE'
);
ws.onopen = () => {
console.log('✅ Connected to FortiBlox');
// Connected! Transactions will stream automatically
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
if (data.type === 'connected') {
console.log('WebSocket ready:', data.message);
} else if (data.type === 'transaction') {
console.log('New transaction:', data.data.signature);
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};// Node.js with ws library (uses headers for auth)
const WebSocket = require('ws');
const ws = new WebSocket('wss://nexus.fortiblox.com/geyser/ws', {
headers: {
'X-API-Key': 'fbx_YOUR_KEY_HERE'
}
});
ws.on('open', () => {
console.log('✅ Connected to FortiBlox');
// Transactions stream automatically - no subscription needed
});
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.type === 'connected') {
console.log('WebSocket ready:', message.message);
} else if (message.type === 'transaction') {
console.log('New transaction:', message.data.signature);
}
});
ws.on('error', (error) => {
console.error('WebSocket error:', error);
});import asyncio
import websockets
import json
async def stream_transactions():
uri = 'wss://nexus.fortiblox.com/geyser/ws?api-key=fbx_YOUR_KEY_HERE'
async with websockets.connect(uri) as ws:
print('✅ Connected to FortiBlox')
# Transactions stream automatically - no subscription needed
# Listen for messages
async for message in ws:
data = json.loads(message)
if data['type'] == 'connected':
print(f"WebSocket ready: {data['message']}")
elif data['type'] == 'transaction':
print(f"New transaction: {data['data']['signature']}")
asyncio.run(stream_transactions())use tokio_tungstenite::{connect_async, tungstenite::Message};
use futures_util::{StreamExt, SinkExt};
use serde_json::json;
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let api_key = "fbx_YOUR_KEY_HERE";
let url = format!(
"wss://nexus.fortiblox.com/geyser/ws?api-key={}",
api_key
);
// Connect to WebSocket
let (ws_stream, _) = connect_async(&url).await?;
println!("✅ Connected to FortiBlox");
let (mut write, mut read) = ws_stream.split();
// Transactions stream automatically - no subscription needed
// Listen for messages
while let Some(msg) = read.next().await {
match msg {
Ok(Message::Text(text)) => {
let data: serde_json::Value = serde_json::from_str(&text)?;
if data["type"] == "connected" {
println!("WebSocket ready: {}", data["message"]);
} else if data["type"] == "transaction" {
println!(
"New transaction: {}",
data["data"]["signature"]
);
}
}
Ok(Message::Close(_)) => {
println!("Connection closed");
break;
}
Err(e) => {
eprintln!("WebSocket error: {}", e);
break;
}
_ => {}
}
}
Ok(())
}package main
import (
"encoding/json"
"fmt"
"log"
"os"
"os/signal"
"github.com/gorilla/websocket"
)
type ConnectedMessage struct {
Type string `json:"type"`
Message string `json:"message"`
}
type TransactionMessage struct {
Type string `json:"type"`
Timestamp string `json:"timestamp"`
Data struct {
Signature string `json:"signature"`
Slot int64 `json:"slot"`
} `json:"data"`
}
func main() {
apiKey := "fbx_YOUR_KEY_HERE"
url := fmt.Sprintf(
"wss://nexus.fortiblox.com/geyser/ws?api-key=%s",
apiKey,
)
// Connect to WebSocket
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
log.Fatal("Connection error:", err)
}
defer conn.Close()
fmt.Println("✅ Connected to FortiBlox")
// Transactions stream automatically - no subscription needed
// Handle interrupt signal
interrupt := make(chan os.Signal, 1)
signal.Notify(interrupt, os.Interrupt)
// Listen for messages
done := make(chan struct{})
go func() {
defer close(done)
for {
var msg TransactionMessage
err := conn.ReadJSON(&msg)
if err != nil {
log.Println("Read error:", err)
return
}
if msg.Type == "connected" {
fmt.Printf("WebSocket ready\n")
} else if msg.Type == "transaction" {
fmt.Printf("New transaction: %s\n", msg.Data.Signature)
}
}
}()
// Wait for interrupt or connection close
select {
case <-done:
return
case <-interrupt:
fmt.Println("\nDisconnecting...")
conn.WriteMessage(
websocket.CloseMessage,
websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""),
)
return
}
}Connection Limits by Tier
| Tier | Concurrent Connections | Messages/Second | Credit Cost per Message |
|---|---|---|---|
| Free | 5 | 100 | 0 credits (free!) |
| Developer | 5 | 500 | 0 credits (free!) |
| Business | 250 | 2,000 | 0 credits (free!) |
| Professional | 250 | 5,000 | 0 credits (free!) |
| Enterprise | Custom | Custom | 0 credits (free!) |
WebSocket messages are free! Unlike REST API calls, WebSocket messages don't consume credits. You only pay for the connection, which is included in all tiers.
Current Capabilities
What's Available Now
WebSocket currently broadcasts all network transactions in real-time:
- ✅ All transaction types (votes, transfers, program invocations, token operations)
- ✅ Complete transaction details (signature, slot, accounts, logs)
- ✅ Automatic streaming - just connect and receive
- ✅ Sub-100ms latency
Coming Soon (Roadmap)
These features are in development:
- 🔜 Subscription filtering - Filter by specific accounts or programs
- 🔜 Commitment levels - Choose processed/confirmed/finalized
- 🔜 Block updates - Subscribe to new blocks as they're produced
- 🔜 Slot progression - Track consensus in real-time
- 🔜 Account state changes - Monitor specific account updates
Need These Features Now?
For filtered transaction queries by account or program, use the Geyser REST API. It supports historical queries with full filtering capabilities.
Authentication
WebSocket requires API key authentication. Choose the method that works for your platform:
Query Parameter (Browser-friendly)
wss://nexus.fortiblox.com/geyser/ws?api-key=fbx_YOUR_KEYHeader (More secure, Node.js/Python)
headers: { 'X-API-Key': 'fbx_YOUR_KEY' }WebSocket vs REST API
| Feature | WebSocket | REST API (Geyser) |
|---|---|---|
| Latency | <100ms | ~200ms |
| Data Type | Real-time stream | Historical queries |
| Filtering | Client-side (coming soon: server-side) | Server-side (full support) |
| Bandwidth | High (all transactions) | Low (only what you request) |
| Browser Support | ✅ Native | ✅ Native |
| Credit Cost | 0 credits | 1-10 credits/request |
| Use Case | Full network monitoring | Specific account/program queries |
Choosing the Right Tool
Use WebSocket when:
- You need real-time updates as they happen
- You're building network analytics or explorers
- You want to process the full transaction stream
- You need sub-100ms latency
Use REST API when:
- You need specific account or program data
- You want server-side filtering
- You're querying historical data
- You want to minimize bandwidth usage
Next Steps
Getting Started
Connect to WebSocket and start receiving transactions
Authentication
Learn about API key authentication methods
Best Practices
Client-side filtering and performance optimization
Roadmap
Upcoming subscription and filtering features
Support
Need help with WebSocket streaming?
- Discord: discord.gg/fortiblox - Live community support
- Email: [email protected] - Direct support team
- Status: status.fortiblox.com - Real-time status updates