WebSocket channels for a stock news stream
Subscribe to ticker, type, keyword, and source channels. They match with OR, up to 200 per connection.

A MarketNewsAPI WebSocket connection receives only the articles that match a channel you subscribed to. Channels are OR. There is no AND between channels, so a narrow bot subscribes to the smaller set and filters the rest in code. Pro includes the socket. Free does not.
The channels
| Channel | Example | Matches |
|---|---|---|
all | all | Every article |
ticker:{SYMBOL} | ticker:AAPL | Articles tagged with that stock or ETF |
category:{id} | category:stocks | The live category, which is stocks |
type:{id} | type:press_release | news, press_release, or legal |
keyword:{text} | keyword:guidance | Case-insensitive phrase on the title and summary, 2 to 60 characters |
source:{domain} | source:businesswire.com | One publisher domain |
You can subscribe to 200 channels on one connection. Pro allows 3 connections. A fourth connection is closed with code 4008. Messages on the stream are not billed. Control messages (subscribe, ping, and the rest) are capped at 20 per second.
Open and subscribe
const url = "wss://ws.marketnewsapi.com/v1/stream?api_key=" + process.env.MARKETNEWSAPI_KEY;
const ws = new WebSocket(url);
ws.addEventListener("open", () => {
ws.send(JSON.stringify({
action: "subscribe",
channels: ["ticker:NVDA", "type:press_release"]
}));
});
That connection delivers NVIDIA articles and every press release, because the two channels are OR. If the bot should post only NVIDIA press releases, keep type:press_release and check tickers in the client, or subscribe to ticker:NVDA and check type. Do both checks if you subscribed to both channels.
Reconnects
Store the newest published_at you handled. After a disconnect, call GET /v1/news with the same tickers and from set to that timestamp, then drop ids you already stored. The socket does not replay the gap. Sources are polled about every second, and an article is pushed after it is ingested.
Try it for 7 days. Signup starts Pro. A card is required. Real-time REST, WebSocket, and MCP, with no request cap. After that it's $15/month, or Free if you stop.
Three subscriptions that stay understandable
A single-name bot subscribes to ticker:NVDA and nothing else. Every message is in scope. A wire bot subscribes to type:press_release and checks the ticker set in process. A desk that wants several names subscribes to one ticker: channel per name, up to the 200 cap, and does not also subscribe to all. Adding all makes the other channels pointless, because OR already includes everything.
Keyword channels are phrases, 2 to 60 characters, matched on the title and the summary, not on a private full-text index of publisher stories. keyword:price target will miss a release whose headline says "outlook" and whose summary never uses your phrase. Use it as a narrowing hint, then still look at the title yourself. It is not a search engine.
Authenticate with the api_key query parameter, or connect and send an auth message first, within 10 seconds. Prefer the message if your proxy logs query strings. REST should keep using the Bearer header. After welcome, send subscribe. Store nothing until you see an article message, and ignore error messages only after you have logged the code.
Limits that surprise people in week one
- 3 connections, not one per ticker. Multiplex tickers as channels.
- A dropped connection does not rewind. REST fills the hole.
- Free, and a key whose trial has ended without a subscription, cannot open the socket.
- Control messages at more than 20 per second are your own loop, usually a resubscribe on every article. Subscribe once.
Put the key in an environment variable. Pro is $15 a month, or $162 a year. The 7-day trial includes the live feed and the full archive, and a card is required. Free stays at 100 requests a day, delayed 15 minutes, with the last year of history. The channel page is WebSocket channels, and a full bot is in the Python tutorial.