WebSocket API
Paid Plans Only ws:connect scopeStream real-time news events directly to your application. Receive new articles, enrichment updates, and story ranking changes the moment they happen.
Connection
Connect to the WebSocket endpoint with your API key:
Use our SDK libraries for the easiest setup
The official TypeScript, Python, and Go SDKs handle connection management, auto-reconnect, and typed events for you.
Open a WebSocket connection to the endpoint above. Once connected, send a subscribe message to specify which events and filters you want. The server will begin streaming matching
events immediately.
The connection stays open indefinitely. The server sends periodic pings to keep the connection alive — your client should respond to pongs automatically (most WebSocket libraries handle this).
import { NewsRankRealtime } from '@newsrank/realtime';
const rt = new NewsRankRealtime('nrf_your_api_key');
await rt.connect();
rt.subscribe({
categories: ['politics', 'business'],
topics: ['articles']
});
rt.on('item.new', (event) => {
console.log(event.data.title);
});Authentication
Pass your API key as the token query parameter. The key must have the ws:connect scope.
| Status | Reason |
|---|---|
| 401 | No token provided or token is invalid |
| 403 | Free tier — WebSocket requires a paid plan |
| 403 | API key has been revoked |
Subscribing
After connecting, send a JSON message to subscribe to specific event types and apply filters. All filter fields are optional — omit a field to receive all events of that type.
{
"type": "subscribe",
"filters": {
"topics": ["articles", "stories"],
"categories": ["politics", "business"],
"sources": ["reuters", "bbc"],
"keywords": ["climate", "AI"],
"entities": [42, 108]
}
}Filter Options
| Field | Type | Description | Note |
|---|---|---|---|
| topics | string[] | Event topics to subscribe to — "articles" and/or "stories" | |
| categories | string[] | Filter by news category (e.g. politics, business, technology) | |
| sources | string[] | Filter by source ID (e.g. reuters, bbc) | |
| keywords | string[] | Match keywords in article titles | |
| entities | number[] | Filter by entity IDs | |
| include_embeddings | boolean | Include embedding vectors in article and story events | Pro+ |
| embedding_filters | EmbeddingFilter[] | Filter events by semantic similarity using up to 10 pre-computed embedding vectors (1536-dim) | Pro+ |
Event Types
Each message from the server includes a type field identifying the event and a data field with the event payload.
item.newNew article discovered. Includes basic metadata like title, source, category, and URL. Fired as soon as an article is ingested from an RSS feed.
{
"type": "item.new",
"data": {
"id": 98201,
"url_hash": "a1b2c3...",
"title": "Fed Signals Rate Cut in March Meeting Minutes",
"url": "https://reuters.com/...",
"source_id": "reuters",
"source_name": "Reuters",
"category": "business",
"published_at": 1708789800000,
"discovered_at": 1708789810000,
"excerpt": "Federal Reserve meeting minutes revealed..."
}
}item.enrichedArticle fully processed with extracted content, AI-generated summary, and tagged entities. Now sent to all clients subscribed to the "articles" topic (entity filters narrow delivery if set).
{
"type": "item.enriched",
"data": {
"id": 98201,
"url_hash": "a1b2c3...",
"title": "Fed Signals Rate Cut in March Meeting Minutes",
"url": "https://reuters.com/...",
"source_id": "reuters",
"source_name": "Reuters",
"category": "business",
"published_at": 1708789800000,
"discovered_at": 1708789810000,
"excerpt": "Federal Reserve meeting minutes revealed...",
"headline_summary": "Fed minutes show consensus for March cut"
},
"entity_ids": [42, 108]
}clusters.rankedStory clusters re-ranked based on new articles. Includes updated rank position, article count, and top contributing sources. Now includes velocity acceleration data.
{
"type": "clusters.ranked",
"data": [
{
"id": 1042,
"title": "Federal Reserve Signals March Rate Cut",
"article_count": 12,
"category": "business",
"top_source": "Reuters"
}
],
"updated": true
}story.developmentA significant narrative development detected in a story cluster — new facts emerged, situation changed, or a major event occurred. Only fires when genuinely new information is detected by the AI enrichment pipeline.
{
"type": "story.development",
"data": {
"cluster_id": 1042,
"title": "Fed Chair confirms March rate cut",
"description": "Jerome Powell confirmed in testimony that the March rate cut is 'highly likely', shifting from previous cautious language.",
"significance": "major",
"headline": "Federal Reserve Signals March Rate Cut",
"category": "business",
"previous_headline": "Fed Officials Discuss Possible Rate Adjustment",
"new_headline": "Federal Reserve Signals March Rate Cut",
"created_at_ms": 1708858412000,
"enrichment_seq": 3
}
}story.priority_changedA story's priority label changed (e.g. from "developing" to "breaking"). Useful for alerting on escalating or de-escalating stories. Includes the overall score and acceleration metrics.
{
"type": "story.priority_changed",
"data": {
"cluster_id": 1042,
"headline": "Federal Reserve Signals March Rate Cut",
"category": "business",
"previous_priority": "developing",
"new_priority": "breaking",
"overall_score": 87.5,
"acceleration_score": 80
}
}cluster.eventCluster lifecycle event — fired when a story cluster is created, merged, or split. Only significant structural changes are broadcast.
{
"type": "cluster.event",
"data": {
"action": "merge",
"cluster_id": 1042,
"detail": {
"merged_from": 1038,
"member_count": 15
}
}
}Embedding Features
Pro+ OnlyTwo embedding-related features are available for Pro tier and above:
include_embeddings Set to true in your subscribe filters to receive embedding vectors alongside article and story events. Useful for building semantic search or recommendation systems.
embedding_filters Provide up to 10 pre-computed 1536-dimensional embedding vectors (text-embedding-3-small compatible) to filter events by semantic similarity. Only events matching above the threshold are delivered.
{
"type": "subscribe",
"filters": {
"topics": ["articles"],
"include_embeddings": true,
"embedding_filters": [
{
"embedding": [0.023, -0.041, "...1536 dimensions"],
"threshold": 0.75,
"label": "climate-news"
}
]
}
}Connection Limits
The number of concurrent WebSocket connections depends on your plan tier.
| Plan | Max Connections | Note |
|---|---|---|
| Free | 0 | Not available |
| Starter | 1 | |
| Pro | 10 | |
| Business | 50 |
Billing
WebSocket events count toward your monthly credit quota. Each event delivered to your connection costs 1 credit.
Best Practices
- • Use narrow filters. Subscribe only to the categories, sources, and entities you need. This reduces event volume and keeps your quota usage low.
- • Handle reconnection with exponential backoff. Connections can drop due to network issues or server restarts. Start with a 1-second delay and double it on each retry, up to 30 seconds.
- • Don't ignore clusters.ranked events. These tell you when story rankings change — essential for keeping a "top stories" view up to date.
- • Monitor connection health. The server sends pings every 30 seconds. If you stop receiving them, your connection may have silently dropped — reconnect promptly.