News Socket connecting

Real-time financial news stream via WebSocket

Live Preview

0 messages

Authentication

Pass your API key as a query parameter. Get your key at markets.sh.

wss://news.markets.sh/ws/news?api_key=msh_live_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0&topic=all&replay=100

Connection

ParamTypeDescription
api_keystringYour markets.sh API key (required)
topicstringall, tag:{name}, publisher:{domain}, company:{id}
min_qualityint 1-10Minimum quality score
tickerscsve.g. BTC,ETH
sentimentstringpositive / negative / neutral / mixed
countriescsvISO country codes
primary_categorycsve.g. markets,policy
asset_classescsve.g. crypto,equities
content_typecsvContent type filter
replayintReplay up to this many recent matching articles from Elasticsearch on connect (max 200)

Messages

Server → Client

{
        "type": "article",
        "data": { "id": "...", "headline": "...", ... }
    }

    {
        "type": "heartbeat",
        "ts": "2026-03-16T21:30:00Z"
    }

Client → Server

// Update filters mid-stream
    {
        "type": "filter",
        "data": { "min_quality": 7, "primary_category": ["markets"] }
    }

    // Keepalive ping
    { "type": "ping" }

Code Examples

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"]}}

REST API

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}