Quickstart
From zero to live market news in about two minutes.
1. Get an API key
Sign up with email or Google. A key is created with the account. While you are signed in, the samples on this site use that key. Store it in an environment variable:
export MARKETNEWSAPI_KEY="mna-live-..."Treat your key like a password. Don't commit it or ship it in browser or mobile code. Call the API from your server instead.
2. Fetch the latest news
With no filters, GET /news returns the newest stock articles:
curl "https://api.marketnewsapi.com/v1/news?limit=5" \
-H "Authorization: Bearer $MARKETNEWSAPI_KEY"import json
import os
import requests
resp = requests.get(
"https://api.marketnewsapi.com/v1/news",
params={"limit": 5},
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({ limit: "5" });
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?limit=5", 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(['limit' => 5]);
$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(limit: 5)
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?limit=5");
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?limit=5"))
.header("Authorization", "Bearer " + System.getenv("MARKETNEWSAPI_KEY"))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
}
}3. Filter by what you care about
Filters combine with AND, and comma-separated values inside one filter are OR. A few examples:
| You want | Query |
|---|---|
| Apple or Microsoft news | ?tickers=AAPL,MSFT |
| Business Wire only | ?sources=businesswire.com |
| Only press releases from today | ?category=stocks&type=press_release&from=2026-10-06 |
| Stock news only | ?category=stocks&type=news or ?type=stock_news |
| Legal notices | ?category=stocks&type=legal |
curl "https://api.marketnewsapi.com/v1/news?tickers=NVDA&type=press_release&limit=1" \
-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": 1},
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: "1" });
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=1", 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' => 1]);
$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: 1)
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=1");
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=1"))
.header("Authorization", "Bearer " + System.getenv("MARKETNEWSAPI_KEY"))
.build();
HttpResponse<String> res = HttpClient.newHttpClient()
.send(req, HttpResponse.BodyHandlers.ofString());
System.out.println(res.body());
}
}4. Read the response
{
"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",
"ingested_at": null,
"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
}
}Every article has the same shape. See the article object for each field.
5. Stream it live (Pro)
Open a WebSocket, subscribe to channels, and articles arrive as they're ingested. summary is still null on that socket. Use wss://ws.marketnewsapi.com/v1/stream/summaries when you want each article after its summary is written. That socket is a few seconds behind.
# 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();
}
}