Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.ivory.finance/llms.txt

Use this file to discover all available pages before exploring further.

Overview

Connect to a WebSocket to receive enriched financial news in real time — typically within seconds of publication. Optionally send a filter to narrow the stream to specific tickers, categories, countries, or sentiment.
No backfill — the stream delivers live messages only. For historical articles use GET /v1/news.

Endpoint

wss://api.ivory.finance/v1/news/stream
Auth required: pass your API key via the Kong X-API-Key header or as a query param ?apikey=.

Connection flow

  1. Connect to the WebSocket.
  2. Receive a connected welcome message.
  3. Optionally send a filter JSON to scope the stream.
  4. Receive article messages matching your filter as they arrive.

Filter message

Send this JSON any time after connecting. Sending a new filter replaces the previous one. An empty filter (or no filter) delivers all financial news.
{
  "tickers":      ["AAPL", "TSLA"],
  "categories":   ["ESG", "Markets"],
  "countries":    ["US", "GB"],
  "sentiment":    "bearish",
  "min_impact":   0.5,
  "source_types": ["rss", "gdelt"]
}
Filter fields (all optional)
FieldTypeDescription
tickersstring[]Only articles mentioning these tickers (OR match)
categoriesstring[]Only articles in these categories (OR match)
countriesstring[]Only articles referencing these ISO-2 countries (OR match)
sentimentstringbullish · bearish · neutral
min_impactfloatMinimum impact score 0.01.0
source_typesstring[]rss · gdelt · reddit · twitter

Message types

connected

Sent immediately on connect.
{
  "type": "connected",
  "message": "Connected to Ivory Finance news stream. Send filter JSON to subscribe."
}

filter_applied

Sent after your filter is accepted.
{ "type": "filter_applied", "filter": { "tickers": ["AAPL"], "min_impact": 0.5 } }

article

Emitted for each enriched article matching your filter.
{
  "type": "article",
  "data": {
    "article_id": "018e4f91-0c3b-7d2a-b3b1-4f9c2e0a1234",
    "url": "https://www.reuters.com/...",
    "title": "Apple reports record services revenue",
    "snippet": "Apple Inc. reported record services revenue of $26.3B...",
    "summary": "Apple's Q1 services revenue hit $26.3B, a 17% YoY increase.",
    "source_name": "Reuters",
    "source_type": "rss",
    "published_at": "2026-03-10T14:23:00+00:00",
    "categories": "[\"Earnings\", \"Markets\"]",
    "country_codes": "[\"US\"]",
    "company_tickers": "[\"AAPL\"]",
    "company_names": "[\"Apple Inc.\"]",
    "sentiment_label": "bullish",
    "sentiment_score": "0.72",
    "impact_score": "0.8",
    "impact_label": "high"
  }
}
Array fields (categories, country_codes, company_tickers, company_names) are JSON-encoded strings in the stream payload. Parse them with JSON.parse().

error

Sent if your filter JSON is malformed.
{ "type": "error", "message": "Expecting value: line 1 column 1" }

Code examples

const ws = new WebSocket(
  "wss://api.ivory.finance/v1/news/stream?apikey=YOUR_API_KEY"
);

ws.onopen = () => {
  console.log("Connected");
  // Subscribe to high-impact ESG news
  ws.send(JSON.stringify({
    categories: ["ESG"],
    min_impact: 0.6,
  }));
};

ws.onmessage = ({ data }) => {
  const msg = JSON.parse(data);
  if (msg.type === "article") {
    const tickers = JSON.parse(msg.data.company_tickers || "[]");
    console.log(`[${msg.data.impact_label}] ${msg.data.title}${tickers.join(", ")}`);
  }
};

ws.onclose = () => console.log("Disconnected");

Capacity limits

LimitValue
Queue per connection200 messages
Slow client handlingDropped messages (no disconnect)
Stream bufferLast 10,000 enriched articles retained in Valkey