WebSocket API Documentation
Real-time stock news feed with AI sentiment analysis. Connect via WebSocket to receive live updates.
Authentication
All WebSocket connections require authentication using a bearer token. Get your token from the Account page after subscribing to a Pro plan.
wss://dev.stocknews.live/ws?token=YOUR_AUTH_TOKEN
WebSocket Endpoint
Establishes a WebSocket connection for real-time news updates. The connection will be closed if your subscription expires.
Message Types
Connected Message
Sent immediately after successful authentication:
{
"type": "connected",
"message": "WebSocket connection established",
"subscription": {
"expiresAt": "2026-03-06T00:00:00.000Z",
"isActive": true
}
}
News Message
Sent whenever new stock news is detected and analyzed:
{
"type": "news",
"timestamp": "2026-02-06T12:34:56.789Z",
"data": {
"ticker": "AAPL",
"sentimentScore": 0.75,
"sentimentLabel": "Bullish",
"confidence": 0.92,
"summary": "Apple announces record quarterly earnings...",
"content": "Full article content...",
"category": "earnings",
"stockTickers": ["AAPL"],
"keyFactors": ["earnings beat", "revenue growth"],
"isStockRelated": true,
"articleUrl": "https://stocknews.live/news/AAPL/article-slug",
"articleSlug": "article-slug",
"channel": "Stock News",
"guild": "Trading Community",
"timestamp": "2026-02-06T12:34:56.789Z",
"price": 175.50,
"priceChange": 2.5,
"priceCurrency": "USD",
"priceFormatted": "$175.50 (+2.5%)",
"volume": 45000000,
"marketCap": "2.8T",
"sector": "Technology"
}
}
Client Messages
You can send these messages to the server:
| Type | Description | Payload |
|---|---|---|
ping |
Keep-alive ping | {"type": "ping"} |
subscribe |
Subscribe to specific tickers (optional) | {"type": "subscribe", "tickers": ["AAPL", "TSLA"]} |
Integration Examples
const WebSocket = require('ws');
const token = 'YOUR_AUTH_TOKEN';
const ws = new WebSocket(`wss://dev.stocknews.live/ws?token=${token}`);
ws.on('open', () => {
console.log('Connected to StockNews WebSocket');
});
ws.on('message', (data) => {
const message = JSON.parse(data);
if (message.type === 'connected') {
console.log('Authenticated:', message.subscription);
} else if (message.type === 'news') {
const news = message.data;
console.log(`News for ${news.ticker}:`, news.sentimentLabel);
console.log('Summary:', news.summary);
console.log('Price:', news.priceFormatted);
// Process the news data
handleNewsUpdate(news);
}
});
ws.on('error', (error) => {
console.error('WebSocket error:', error);
});
ws.on('close', () => {
console.log('Connection closed');
});
function handleNewsUpdate(news) {
// Your custom logic here
if (news.sentimentScore > 0.7) {
console.log('Bullish signal detected!');
}
}
import websocket
import json
token = 'YOUR_AUTH_TOKEN'
ws_url = f'wss://dev.stocknews.live/ws?token={token}'
def on_message(ws, message):
data = json.loads(message)
if data['type'] == 'connected':
print('Authenticated:', data['subscription'])
elif data['type'] == 'news':
news = data['data']
print(f"News for {news['ticker']}: {news['sentimentLabel']}")
print(f"Summary: {news['summary']}")
print(f"Price: {news['priceFormatted']}")
# Process the news data
handle_news_update(news)
def on_error(ws, error):
print('WebSocket error:', error)
def on_close(ws):
print('Connection closed')
def on_open(ws):
print('Connected to StockNews WebSocket')
def handle_news_update(news):
# Your custom logic here
if news['sentimentScore'] > 0.7:
print('Bullish signal detected!')
ws = websocket.WebSocketApp(
ws_url,
on_message=on_message,
on_error=on_error,
on_close=on_close,
on_open=on_open
)
ws.run_forever()
<?php
use Ratchet\Client\WebSocket;
use React\EventLoop\Factory;
require __DIR__ . '/vendor/autoload.php';
$token = 'YOUR_AUTH_TOKEN';
$wsUrl = "wss://dev.stocknews.live/ws?token={$token}";
$loop = Factory::create();
\Ratchet\Client\connect($wsUrl, [], [], $loop)
->then(function(WebSocket $conn) {
echo "Connected to StockNews WebSocket\n";
$conn->on('message', function($msg) use ($conn) {
$data = json_decode($msg, true);
if ($data['type'] === 'connected') {
echo "Authenticated: " . json_encode($data['subscription']) . "\n";
} elseif ($data['type'] === 'news') {
$news = $data['data'];
echo "News for {$news['ticker']}: {$news['sentimentLabel']}\n";
echo "Summary: {$news['summary']}\n";
echo "Price: {$news['priceFormatted']}\n";
// Process the news data
handleNewsUpdate($news);
}
});
$conn->on('close', function($code = null, $reason = null) {
echo "Connection closed ({$code} - {$reason})\n";
});
}, function(\Exception $e) {
echo "Could not connect: {$e->getMessage()}\n";
});
function handleNewsUpdate($news) {
// Your custom logic here
if ($news['sentimentScore'] > 0.7) {
echo "Bullish signal detected!\n";
}
}
$loop->run();
?>
const token = 'YOUR_AUTH_TOKEN';
const ws = new WebSocket(`wss://dev.stocknews.live/ws?token=${token}`);
ws.onopen = () => {
console.log('Connected to StockNews WebSocket');
};
ws.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'connected') {
console.log('Authenticated:', message.subscription);
} else if (message.type === 'news') {
const news = message.data;
console.log(`News for ${news.ticker}:`, news.sentimentLabel);
console.log('Summary:', news.summary);
console.log('Price:', news.priceFormatted);
// Update UI or process data
displayNews(news);
}
};
ws.onerror = (error) => {
console.error('WebSocket error:', error);
};
ws.onclose = () => {
console.log('Connection closed');
// Optionally reconnect
setTimeout(() => {
connectWebSocket();
}, 5000);
};
function displayNews(news) {
// Update your UI with the news data
const newsElement = document.createElement('div');
newsElement.innerHTML = `
<h3>${news.ticker} - ${news.sentimentLabel}</h3>
<p>${news.summary}</p>
<p>Price: ${news.priceFormatted}</p>
`;
document.getElementById('news-feed').appendChild(newsElement);
}
Data Fields
| Field | Type | Description |
|---|---|---|
ticker |
string | Primary stock ticker symbol (e.g., "AAPL") |
sentimentScore |
number | Sentiment score from -1 (bearish) to +1 (bullish) |
sentimentLabel |
string | Human-readable label: "Very Bearish", "Bearish", "Neutral", "Bullish", "Very Bullish" |
confidence |
number | AI confidence score (0-1) |
summary |
string | Brief summary of the news |
content |
string | Full article content |
category |
string | News category (e.g., "earnings", "merger", "product") |
stockTickers |
array | All stock tickers mentioned in the article |
keyFactors |
array | Key factors affecting sentiment |
price |
number | Current stock price |
priceChange |
number | Price change percentage |
priceFormatted |
string | Formatted price display (e.g., "$175.50 (+2.5%)") |
volume |
number | Trading volume |
marketCap |
string | Market capitalization |
sector |
string | Stock sector |
articleUrl |
string | URL to full article |
timestamp |
string | ISO 8601 timestamp |
Sample Response
{
"type": "news",
"timestamp": "2026-02-06T12:34:56.789Z",
"data": {
"ticker": "AAPL",
"sentimentScore": 0.75,
"sentimentLabel": "Bullish",
"confidence": 0.92,
"summary": "Apple Inc. reported record quarterly earnings, beating analyst expectations...",
"content": "Full article content here...",
"category": "earnings",
"stockTickers": ["AAPL"],
"keyFactors": ["earnings beat", "revenue growth", "strong iPhone sales"],
"isStockRelated": true,
"articleUrl": "https://stocknews.live/news/AAPL/apple-record-earnings-q1-2026",
"articleSlug": "apple-record-earnings-q1-2026",
"channel": "Stock News",
"guild": "Trading Community",
"timestamp": "2026-02-06T12:34:56.789Z",
"price": 175.50,
"priceChange": 2.5,
"priceCurrency": "USD",
"priceFormatted": "$175.50 (+2.5%)",
"volume": 45000000,
"marketCap": "2.8T",
"sector": "Technology"
}
}
Error Handling
The WebSocket connection may close with these codes:
- 1008: Authentication failed or subscription expired
- 1000: Normal closure
Always implement reconnection logic with exponential backoff for production applications.
Rate Limits
There are no rate limits on WebSocket connections. However, ensure your client handles reconnections gracefully and doesn't flood the server with ping messages.
Support
For questions or issues, please contact support or visit your Account page.