WebSocket Integration
Connect directly to StocksEyes WebSocket service for real-time stock market data with minimal latency. This guide provides complete implementation details for Flutter applications.
Prerequisites
- Flutter SDK 3.0 or higher
- Dart 2.17 or higher
- Valid StocksEyes API key
- Active internet connection
Installation
Add the following dependencies to your pubspec.yaml:
dependencies:
flutter:
sdk: flutter
http: ^1.1.0 # For HTTP API calls
web_socket_channel: ^2.4.0 # For WebSocket connection
Install packages:
flutter pub get
Quick Start
Step 1: Fetch WebSocket URL
First, obtain the WebSocket URL with authentication token from the API:
import 'package:http/http.dart' as http;
import 'dart:convert';
Future<String> fetchWebSocketUrl() async {
final response = await http.get(
Uri.parse('https://api.stockseyes.com/v1/public/websocket'),
headers: {'Authorization': '<API_KEY>'},
);
final data = json.decode(response.body);
return data['url'];
}
API Endpoint: GET https://api.stockseyes.com/v1/public/websocket
Response:
{
"url": "ws://***.***.***.***?token=***"
}
Step 2: Connect to WebSocket
import 'package:web_socket_channel/web_socket_channel.dart';
final wsUrl = await fetchWebSocketUrl();
final channel = WebSocketChannel.connect(Uri.parse(wsUrl));
Step 3: Subscribe to Instruments
Subscribe to receive real-time data for specific instrument tokens:
// Subscribe to single instrument
channel.sink.add('SUBSCRIBE:738561'); // RELIANCE
// Subscribe to multiple instruments
channel.sink.add('SUBSCRIBE:738561,256265,408065');
Step 4: Listen for Data
channel.stream.listen((message) {
final data = json.decode(message);
if (data['type'] == 'ACK') {
print('Subscription confirmed: ${data['instruments']}');
} else if (data['type'] == 'TICK') {
print('Price update: ${data['data']['trading_symbol']} - ₹${data['data']['last_price']}');
}
});
Step 5: Unsubscribe and Close
// Unsubscribe from instruments
channel.sink.add('UNSUBSCRIBE:738561');
// Close connection
channel.sink.close();
WebSocket Commands
SUBSCRIBE
Subscribe to receive real-time data for instrument tokens.
Format:
SUBSCRIBE:token1,token2,token3
Example:
channel.sink.add('SUBSCRIBE:738561'); // Single
channel.sink.add('SUBSCRIBE:738561,256265'); // Multiple
Response:
{
"type": "ACK",
"action": "Subscribed",
"instruments": ["738561"]
}
UNSUBSCRIBE
Stop receiving data for instrument tokens.
Format:
UNSUBSCRIBE:token1,token2,token3
Example:
channel.sink.add('UNSUBSCRIBE:738561');
Response:
{
"type": "ACK",
"action": "Unsubscribed",
"instruments": ["738561"]
}
Message Formats
ACK Message
Confirmation message sent by server after subscription/unsubscription.
{
"type": "ACK",
"action": "Subscribed",
"instruments": ["738561", "256265"]
}
Fields:
type: Always "ACK"action: "Subscribed" or "Unsubscribed"instruments: Array of instrument tokens
TICK Message
Real-time market data for subscribed instruments.
{
"type": "TICK",
"data": {
"instrument_token": 738561,
"trading_symbol": "RELIANCE",
"last_price": 1487.7,
"volume_traded": 5666888,
"last_traded_quantity": 1,
"average_traded_price": 1494.83,
"total_buy_quantity": 408982,
"total_sell_quantity": 761689,
"ohlc": {
"open": 1500.0,
"high": 1503.1,
"low": 1487.1,
"close": 1504.2
},
"change": -1.096,
"last_trade_time": "2025-10-30T08:48:56.000Z",
"exchange_timestamp": "2025-10-30T08:48:57.000Z",
"depth": {
"buy": [
{"quantity": 100, "price": 1487.5, "orders": 5},
{"quantity": 200, "price": 1487.0, "orders": 8}
],
"sell": [
{"quantity": 150, "price": 1488.0, "orders": 6},
{"quantity": 180, "price": 1488.5, "orders": 7}
]
},
"timestamp": 1761814138048
}
}
Key Fields:
instrument_token: Unique identifier for the instrumenttrading_symbol: Stock symbol (e.g., "RELIANCE")last_price: Current trading pricevolume_traded: Total volume tradedohlc: Open, High, Low, Close priceschange: Percentage change from previous closedepth: Order book depth (5 levels of buy/sell orders)timestamp: Unix timestamp in milliseconds
Complete Example
import 'package:http/http.dart' as http;
import 'package:web_socket_channel/web_socket_channel.dart';
import 'dart:convert';
class StockEyesWebSocketClient {
WebSocketChannel? _channel;
Future<void> connect() async {
// Fetch WebSocket URL
final response = await http.get(
Uri.parse('https://api.stockseyes.com/v1/public/websocket'),
headers: {'Authorization': '<API_KEY>'},
);
final data = json.decode(response.body);
final wsUrl = data['url'];
// Connect to WebSocket
_channel = WebSocketChannel.connect(Uri.parse(wsUrl));
// Listen for messages
_channel!.stream.listen(
(message) {
final data = json.decode(message);
_handleMessage(data);
},
onError: (error) => print('Error: $error'),
onDone: () => print('Connection closed'),
);
}
void _handleMessage(Map<String, dynamic> data) {
if (data['type'] == 'ACK') {
print('${data['action']}: ${data['instruments']}');
} else if (data['type'] == 'TICK') {
final tick = data['data'];
print('${tick['trading_symbol']}: ₹${tick['last_price']}');
}
}
void subscribe(List<int> tokens) {
final command = 'SUBSCRIBE:${tokens.join(',')}';
_channel?.sink.add(command);
}
void unsubscribe(List<int> tokens) {
final command = 'UNSUBSCRIBE:${tokens.join(',')}';
_channel?.sink.add(command);
}
void close() {
_channel?.sink.close();
}
}
// Usage
void main() async {
final client = StockEyesWebSocketClient();
await client.connect();
// Subscribe to RELIANCE
client.subscribe([738561]);
// Wait for data...
await Future.delayed(Duration(seconds: 30));
// Cleanup
client.unsubscribe([738561]);
client.close();
}
Best Practices
Connection Management
✅ DO:
- Always close connections when done
- Handle connection errors gracefully
- Implement reconnection logic for production apps
❌ DON'T:
- Leave connections open indefinitely
- Ignore error states
- Create multiple connections for the same data
Subscription Management
✅ DO:
- Subscribe only to instruments you need
- Unsubscribe when data is no longer needed
- Batch multiple subscriptions in one command
❌ DON'T:
- Subscribe to hundreds of instruments at once
- Keep subscriptions active when app is in background
Data Handling
✅ DO:
- Parse JSON safely with try-catch
- Validate data before using
- Use models/classes for type safety
❌ DON'T:
- Assume all fields are present
- Ignore parsing errors
- Use dynamic types everywhere
Common Instrument Tokens
| Symbol | Token | Exchange |
|---|---|---|
| RELIANCE | 738561 | NSE |
| TCS | 2953217 | NSE |
| INFY | 408065 | NSE |
| HDFCBANK | 341249 | NSE |
| ICICIBANK | 1270529 | NSE |
Troubleshooting
Connection Issues
Problem: Connection closes immediately
Solutions:
- Verify API key is correct
- Check if WebSocket URL includes token
- Ensure network connectivity
Problem: "Unauthorized" error
Solutions:
- Verify API key in Authorization header
- Don't modify the URL returned by API
- Token is already included in URL
Data Issues
Problem: Not receiving tick data
Solutions:
- Verify you've sent SUBSCRIBE command
- Check instrument token is valid
- Ensure market is open (for live data)
- Check connection state
Problem: Parsing errors
Solutions:
- Use try-catch around JSON parsing
- Check for null values
- Validate data types before casting
Support
For issues or questions:
- Email: support@stockseyes.com
- Documentation: https://documentation.stockseyes.com
Last updated: 2025-10-30