Real-time financial news stream via WebSocket
Pass your API key as a query parameter. Get your key at markets.sh.
| Param | Type | Description |
|---|---|---|
api_key | string | Your markets.sh API key (required) |
topic | string | all, tag:{name}, publisher:{domain}, company:{id} |
min_quality | int 1-10 | Minimum quality score |
tickers | csv | e.g. BTC,ETH |
sentiment | string | positive / negative / neutral / mixed |
countries | csv | ISO country codes |
primary_category | csv | e.g. markets,policy |
asset_classes | csv | e.g. crypto,equities |
content_type | csv | Content type filter |
replay | int | Replay up to this many recent matching articles from Elasticsearch on connect (max 200) |
{
"type": "article",
"data": { "id": "...", "headline": "...", ... }
}
{
"type": "heartbeat",
"ts": "2026-03-16T21:30:00Z"
}
// Update filters mid-stream
{
"type": "filter",
"data": { "min_quality": 7, "primary_category": ["markets"] }
}
// Keepalive ping
{ "type": "ping" }
const API_KEY = "msh_live_a1b2c3d4e5f6...";
const ws = new WebSocket("wss://news.markets.sh/ws/news?api_key=" + API_KEY + "&topic=all&min_quality=5&replay=100");
ws.onopen = () => console.log("connected");
ws.onmessage = (e) => {
const msg = JSON.parse(e.data);
if (msg.type === "article") {
console.log(msg.data.headline);
}
};
// Update filters mid-stream
ws.send(JSON.stringify({
type: "filter",
data: { tickers: ["BTC"], min_quality: 7, primary_category: ["markets"] }
}));import Foundation
let apiKey = "msh_live_a1b2c3d4e5f6..."
let url = URL(string: "wss://news.markets.sh/ws/news?api_key=\(apiKey)&topic=all&replay=100")!
let task = URLSession.shared.webSocketTask(with: url)
task.resume()
func receive() {
task.receive { result in
switch result {
case .success(let message):
switch message {
case .string(let text):
print(text)
default: break
}
receive() // continue listening
case .failure(let error):
print("Error: \(error)")
}
}
}
receive()import asyncio, websockets, json
async def stream():
api_key = "msh_live_a1b2c3d4e5f6..."
uri = "wss://news.markets.sh/ws/news?api_key=" + api_key + "&topic=all&min_quality=5&replay=100"
async with websockets.connect(uri) as ws:
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "article":
print(msg["data"]["headline"])
asyncio.run(stream())# Install: npm i -g wscat
API_KEY="msh_live_a1b2c3d4e5f6..."
wscat -c "wss://news.markets.sh/ws/news?api_key=$API_KEY&topic=all&replay=100"
# With filters
wscat -c "wss://news.markets.sh/ws/news?api_key=$API_KEY&topic=all&min_quality=7&tickers=BTC,ETH&primary_category=markets&asset_classes=crypto"
# Tag-specific topic
wscat -c "wss://news.markets.sh/ws/news?api_key=$API_KEY&topic=tag:bitcoin"
# Send filter update once connected
> {"type":"filter","data":{"min_quality":8,"primary_category":["markets"],"asset_classes":["crypto"]}}Article bodies are stripped from the stream. Use the REST endpoint to fetch full article data:
GET https://news.markets.sh/api/v3/news?api_key=msh_live_...&q={query}