The market's news, within reach.
Read stock news from the major newswires within 500 milliseconds of publishing. Fetch the archive over REST, take the live feed over WebSocket, or pass it to an agent over MCP. It is $15 a month on Pro, or free on a delayed plan, because fast access to the news that moves your positions should not be reserved for a trading desk.
- 7-day trial, 2,000 REST requests a day
- $15/mo after, or $13.50/mo annual
- Free plan if you don't continue
Connect MarketNewsAPI to Cursor
The same server works in Claude, ChatGPT, Cursor, and more. Ask about a stock, and the answer comes from live articles, with a link to each source.
Read the MCP server docsFrom API key to headlines in four lines
Send a request with your key in the Authorization header. Change the ticker below and run a live preview. No key is required on this page.
curl "https://api.marketnewsapi.com/v1/news?tickers=NVDA&type=press_release&limit=3" \
-H "Authorization: Bearer $MARKETNEWSAPI_KEY"import json
import os
import requests
resp = requests.get(
"https://api.marketnewsapi.com/v1/news",
params={"tickers": "NVDA", "type": "press_release", "limit": 3},
headers={"Authorization": f"Bearer {os.environ['MARKETNEWSAPI_KEY']}"},
timeout=10,
)
resp.raise_for_status()
print(json.dumps(resp.json(), indent=2))const params = new URLSearchParams({ tickers: "NVDA", type: "press_release", limit: "3" });
const res = await fetch(`https://api.marketnewsapi.com/v1/news?${params}`, {
headers: { Authorization: `Bearer ${process.env.MARKETNEWSAPI_KEY}` },
});
if (!res.ok) throw new Error(`HTTP ${res.status}`);
console.log(await res.json());package main
import (
"fmt"
"io"
"net/http"
"os"
)
func main() {
req, _ := http.NewRequest("GET", "https://api.marketnewsapi.com/v1/news?tickers=NVDA&type=press_release&limit=3", nil)
req.Header.Set("Authorization", "Bearer "+os.Getenv("MARKETNEWSAPI_KEY"))
res, err := http.DefaultClient.Do(req)
if err != nil {
panic(err)
}
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}<?php
$query = http_build_query(['tickers' => 'NVDA', 'type' => 'press_release', 'limit' => 3]);
$ch = curl_init("https://api.marketnewsapi.com/v1/news?$query");
curl_setopt_array($ch, [
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('MARKETNEWSAPI_KEY')],
]);
$body = json_decode(curl_exec($ch), true);
curl_close($ch);
print_r($body);require "json"
require "net/http"
uri = URI("https://api.marketnewsapi.com/v1/news")
uri.query = URI.encode_www_form(tickers: "NVDA", type: "press_release", limit: 3)
req = Net::HTTP::Get.new(uri)
req["Authorization"] = "Bearer #{ENV.fetch('MARKETNEWSAPI_KEY')}"
res = Net::HTTP.start(uri.host, uri.port, use_ssl: true) { |http| http.request(req) }
puts JSON.pretty_generate(JSON.parse(res.body))using System.Net.Http.Headers;
using var http = new HttpClient();
http.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue(
"Bearer", Environment.GetEnvironmentVariable("MARKETNEWSAPI_KEY"));
var json = await http.GetStringAsync("https://api.marketnewsapi.com/v1/news?tickers=NVDA&type=press_release&limit=3");
Console.WriteLine(json);import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
public class Main {
public static void main(String[] args) throws Exception {
HttpRequest req = HttpRequest.newBuilder()
.uri(URI.create("https://api.marketnewsapi.com/v1/news?tickers=NVDA&type=press_release&limit=3"))
.header("Authorization", "Bearer " + System.getenv("MARKETNEWSAPI_KEY"))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
}
}GET/v1/news?tickers=NVDA&type=press_release&limit=3
{
"data": [
{
"id": "art_fa355efccd9b2ac9",
"title": "AM Intelligence Expands NVIDIA Vera Rubin AI Factory Buildout in India and Malaysia",
"url": "https://www.businesswire.com/news/home/20261005478911/en/AM-Intelligence-Expands-NVIDIA-Vera-Rubin-AI-Factory-Buildout-in-India-and-Malaysia/",
"source": {
"name": "Business Wire",
"domain": "businesswire.com"
},
"publisher": "Business Wire",
"published_at": "2026-10-05T18:16:00Z",
"category": "stocks",
"type": "press_release",
"tickers": [
"NVDA"
],
"listings": [
{
"symbol": "NVDA",
"exchange": "NASDAQ"
}
],
"snippet": "HYDERABAD, India--(BUSINESS WIRE)-- #AI--AM Intelligence today announced two firm and binding orders for 20,000 NVIDIA Rubin GPUs to be deployed as NVIDIA Vera Rubin NVL72 rack-scale systems.",
"summary": null,
"body": "HYDERABAD, India--(BUSINESS WIRE)-- #AI--AM Intelligence today announced two firm and binding orders for 20,000 NVIDIA Rubin GPUs to be deployed as NVIDIA Vera Rubin NVL72 rack-scale systems.",
"entities": [
{
"type": "company",
"name": "NVIDIA",
"symbol": "NVDA"
}
],
"language": "en"
}
],
"meta": {
"count": 1,
"plan": "stream",
"delayed_minutes": 0
}
}
Fast enough to trade on. Cheap enough to start.
Trading APIs got expensive while the software behind them got cheaper, and that gap keeps a lot of retail traders and investors off the same feeds. Pro is real time and unlimited, and the article is the same whether you call REST, open a socket, or hand it to an agent.
Push, don't poll
A WebSocket stream sends each article the moment it's ingested and enriched. Subscribe by ticker, article type, keyword or source, or take the whole stock-news firehose.
AI summaries
A neutral 1–3 sentence summary of every story, so you can show context or feed an LLM without scraping the page.
Entities and symbols
Tickers, companies, people and products are extracted and normalized, so you can match articles to your universe.
Full-text press releases
Press releases come straight from GlobeNewswire, Business Wire, PR Newswire, ACCESS Newswire and Newsfile, with the complete text included.
Filters that compose
Stocks split into stock news, press releases and legal, the same three types Vantafin uses. Combine those with tickers, sources, date ranges, and full-text search.
Full archive
Paid plans search the full archive of stock news, which is useful for backtests, research and training datasets.
$15, and that's the point
Pro is $15 a month, or $13.50 a month billed annually, for unlimited real-time REST, WebSocket, and MCP. No credits and no overage fees. The 7-day trial requires a card.
Hand it to an agent
The MCP server gives Claude, ChatGPT, Cursor, and other agents the same articles, with a link to each source.
Stock news, three ways
The same split Vantafin uses: publisher stock news, full-text press releases, and legal notices.
Stock news
Publisher reporting on US equities and ETFs: earnings coverage, analyst moves, guidance and M&A.
category=stocks & type=newsPress releases
Full-text company announcements from GlobeNewswire, Business Wire, PR Newswire, ACCESS Newswire, Newsfile and Dow Jones.
category=stocks & type=press_releaseLegal
Shareholder class-action and investor-alert notices, kept separate so they don't bury stock news or press releases.
category=stocks & type=legal
Live desk
The desk is already running.
Stock news, press releases, and legal notices land with the ticker, the source, and the time already on the row.
Open live newsPull history with REST. Get new articles pushed over WebSocket.
Use REST to backfill and search. Open one WebSocket connection to receive new articles live, filtered server-side to the channels you subscribe to.
ticker:AAPLEvery Apple storytype:press_releaseWire releases onlytype:legalShareholder notices onlykeyword:guidancePhrase match on title and summarysource:businesswire.comOne wire serviceallThe full stock-news firehose# brew install websocat (or: cargo install websocat)
websocat "wss://ws.marketnewsapi.com/v1/stream?api_key=$MARKETNEWSAPI_KEY"
# then paste:
{"action":"subscribe","channels":["ticker:AAPL","type:press_release","keyword:guidance"]}# pip install websockets
import asyncio
import json
import os
import websockets
URL = f"wss://ws.marketnewsapi.com/v1/stream?api_key={os.environ['MARKETNEWSAPI_KEY']}"
async def main():
async for ws in websockets.connect(URL): # reconnects automatically
try:
await ws.send(json.dumps({"action": "subscribe", "channels": ["ticker:AAPL", "type:press_release", "keyword:guidance"]}))
async for raw in ws:
msg = json.loads(raw)
if msg["type"] == "article":
print(msg["data"]["published_at"], msg["data"]["title"])
except websockets.ConnectionClosed:
continue
asyncio.run(main())// Browsers and Node.js 22+ ship a global WebSocket.
const ws = new WebSocket(`wss://ws.marketnewsapi.com/v1/stream?api_key=${process.env.MARKETNEWSAPI_KEY}`);
ws.addEventListener("open", () => {
ws.send(JSON.stringify({ action: "subscribe", channels: ["ticker:AAPL", "type:press_release", "keyword:guidance"] }));
});
ws.addEventListener("message", (event) => {
const msg = JSON.parse(event.data);
if (msg.type === "article") console.log(msg.data.published_at, msg.data.title);
});
ws.addEventListener("close", (event) => console.log("closed", event.code, event.reason));// go get github.com/gorilla/websocket
package main
import (
"fmt"
"os"
"github.com/gorilla/websocket"
)
type message struct {
Type string `json:"type"`
Data struct {
Title string `json:"title"`
PublishedAt string `json:"published_at"`
} `json:"data"`
}
func main() {
url := "wss://ws.marketnewsapi.com/v1/stream?api_key=" + os.Getenv("MARKETNEWSAPI_KEY")
conn, _, err := websocket.DefaultDialer.Dial(url, nil)
if err != nil {
panic(err)
}
defer conn.Close()
conn.WriteJSON(map[string]any{
"action": "subscribe",
"channels": []string{"ticker:AAPL", "type:press_release", "keyword:guidance"},
})
for {
var msg message
if err := conn.ReadJSON(&msg); err != nil {
panic(err)
}
if msg.Type == "article" {
fmt.Println(msg.Data.PublishedAt, msg.Data.Title)
}
}
}<?php
// composer require phrity/websocket
require 'vendor/autoload.php';
use WebSocket\Client;
$client = new Client('wss://ws.marketnewsapi.com/v1/stream?api_key=' . getenv('MARKETNEWSAPI_KEY'));
$client->text(json_encode([
'action' => 'subscribe',
'channels' => ['ticker:AAPL', 'type:press_release', 'keyword:guidance'],
]));
while (true) {
$msg = json_decode($client->receive()->getContent(), true);
if (($msg['type'] ?? '') === 'article') {
echo $msg['data']['published_at'] . ' ' . $msg['data']['title'] . PHP_EOL;
}
}# gem install websocket-client-simple
require "json"
require "websocket-client-simple"
url = "wss://ws.marketnewsapi.com/v1/stream?api_key=#{ENV.fetch('MARKETNEWSAPI_KEY')}"
ws = WebSocket::Client::Simple.connect(url)
ws.on :open do
ws.send({ action: "subscribe", channels: ["ticker:AAPL", "type:press_release", "keyword:guidance"] }.to_json)
end
ws.on :message do |event|
msg = JSON.parse(event.data)
puts "#{msg['data']['published_at']} #{msg['data']['title']}" if msg["type"] == "article"
end
loop { sleep 1 }using System.IO;
using System.Net.WebSockets;
using System.Text;
using System.Text.Json;
var key = Environment.GetEnvironmentVariable("MARKETNEWSAPI_KEY");
using var ws = new ClientWebSocket();
await ws.ConnectAsync(new Uri($"wss://ws.marketnewsapi.com/v1/stream?api_key={key}"), CancellationToken.None);
var sub = JsonSerializer.Serialize(new { action = "subscribe", channels = new[] { "ticker:AAPL", "type:press_release", "keyword:guidance" } });
await ws.SendAsync(new ArraySegment<byte>(Encoding.UTF8.GetBytes(sub)),
WebSocketMessageType.Text, true, CancellationToken.None);
var buffer = new byte[64 * 1024];
while (ws.State == WebSocketState.Open)
{
using var ms = new MemoryStream();
WebSocketReceiveResult result;
do
{
result = await ws.ReceiveAsync(new ArraySegment<byte>(buffer), CancellationToken.None);
ms.Write(buffer, 0, result.Count);
} while (!result.EndOfMessage);
using var doc = JsonDocument.Parse(ms.ToArray());
var root = doc.RootElement;
if (root.GetProperty("type").GetString() == "article")
{
var data = root.GetProperty("data");
Console.WriteLine($"{data.GetProperty("published_at")} {data.GetProperty("title")}");
}
}import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.WebSocket;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.CountDownLatch;
public class Stream {
public static void main(String[] args) throws Exception {
String url = "wss://ws.marketnewsapi.com/v1/stream?api_key=" + System.getenv("MARKETNEWSAPI_KEY");
CountDownLatch closed = new CountDownLatch(1);
WebSocket ws = HttpClient.newHttpClient().newWebSocketBuilder()
.buildAsync(URI.create(url), new WebSocket.Listener() {
private final StringBuilder buf = new StringBuilder();
@Override
public CompletionStage<?> onText(WebSocket socket, CharSequence data, boolean last) {
buf.append(data);
if (last) {
System.out.println(buf); // parse with Jackson or Gson
buf.setLength(0);
}
socket.request(1);
return null;
}
@Override
public CompletionStage<?> onClose(WebSocket socket, int code, String reason) {
closed.countDown();
return null;
}
@Override
public void onError(WebSocket socket, Throwable error) {
error.printStackTrace();
closed.countDown();
}
}).join();
ws.sendText("{\"action\":\"subscribe\",\"channels\":[\"ticker:AAPL\",\"type:press_release\",\"keyword:guidance\"]}", true);
closed.await();
}
}Docs
Four lines to the first headline.
Search the archive over REST, subscribe to what just published, or hand the same feed to an agent.
Open the quickstart docsWho moves when the headline hits
Event-driven traders, long-term investors, bots, and desks. Each workflow has its own guide.
Event-driven traders
Catch a press release or a sharp headline on a name you trade, with the ticker already attached.
Long-term investors
Pull the filing-week headlines and guidance releases for a company you intend to hold.
Trading bots
Fire an alert when a watched ticker gets a new headline or a press release.
Dashboards
Show the latest headline beside a chart, with the source, time, and summary already on the payload.
AI agents
Let an agent answer “what just happened to NVDA?” from summaries and source links, not from a scraped page.
Research
Build features from headline time, ticker, and type instead of hand-labeling a scrape.
Newsletters
Assemble the day's top stories by ticker, then link readers to the original article.
Risk and compliance
Watch every holding for adverse headlines and shareholder alerts without mixing them into one pile.
Quant desks
Turn headlines into features: event type and the minute the story was stored.
One paid plan. $15 a month.
The trial is real-time Pro for 7 days: 2,000 REST requests a day, WebSocket, MCP, and the full archive. Paid Pro removes the daily cap. Then $15 a month, or $162 a year. Free stays available either way.
2 months free on annual
Free
REST · delayedStay on a delayed sandbox after the trial, or start here.
Free forever
Get a free key- REST API
- 100 requests per day
- 15-minute delayed headlines
- Last year of history
- US stock news, press releases, and legal
- Summaries and entities
- Real-time news
- WebSocket stream
- MCP server
- Full archive
Pro
REST + WebSocket + MCPReal-time REST, WebSocket, and MCP. The 7-day trial is 2,000 REST requests a day. A card is required.
Billed monthly, cancel anytime
Start 7-day free trial- 7-day trial: 2,000 REST requests a day. A card is required
- REST, WebSocket, and MCP
- Unlimited REST requests on paid Pro
- Real-time news (no delay)
- Full archive
- 3 concurrent WebSocket connections
- Unlimited WebSocket messages
- US stock news, press releases, and legal
- Summaries and entities
- Full text for press releases
"Unlimited" on paid Pro means no daily or monthly request cap. The 7-day trial is 2,000 REST requests a day. A fair-use burst limit of 20 requests per second protects everyone. Compare plans in detail.
Three stocks, three mornings a week.
Market Pulse takes a headline that moved a price and shows the MarketNewsAPI call that would have returned it.
Monday, Wednesday, and Friday. Unsubscribe from any issue, or from account settings if you have one.
Frequently asked questions
What is MarketNewsAPI?
Is there a free market news API?
Is the paid stock news API unlimited?
What is the difference between the REST API and the WebSocket?
How are stock articles divided?
How fast is the stock news API?
Which programming languages does the API support?
Can I use MarketNewsAPI with ChatGPT, Claude, or my own AI agent?
How far back does the stock news API go?
Is MarketNewsAPI a stock price API?
Real-time stock news for $15 a month.
Start a 7-day Pro trial. A card is required. REST, WebSocket, and MCP are included, with 2,000 REST requests a day. Paid Pro removes the daily cap. If you don't subscribe, the account stays on Free.