# Quickstart

From zero to live market news in about two minutes.

## 1. Get an API key

[Sign up](/signup) 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:

```bash
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
curl "https://api.marketnewsapi.com/v1/news?limit=5" \
 -H "Authorization: Bearer $MARKETNEWSAPI_KEY"
```

```python
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))
```

```javascript
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());
```

```go
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
<?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);
```

```ruby
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))
```

```csharp
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);
```

```java
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
curl "https://api.marketnewsapi.com/v1/news?tickers=NVDA&type=press_release&limit=1" \
 -H "Authorization: Bearer $MARKETNEWSAPI_KEY"
```

```python
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))
```

```javascript
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());
```

```go
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
<?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);
```

```ruby
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))
```

```csharp
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);
```

```java
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

200 OK

```json
{
 "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](/docs/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.

```curl
# 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"]}
```

```python
# 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())
```

```javascript
// 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
// 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
<?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;
 }
}
```

```ruby
# 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 }
```

```csharp
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")}");
 }
}
```

```java
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();
 }
}
```

## Next steps

- [Every filter on GET /news](/docs/news)
- [All WebSocket channels](/docs/websocket-channels)
- [MCP server for Claude, ChatGPT and Cursor](/docs/mcp)
- [Tutorial: a stock news alert bot in Python](/blog/stock-news-alert-bot-python)
