API Reference
Quick Start
The AletaIndex API is a REST API that returns JSON. It can be called from any language or HTTP client — Python, JavaScript, Go, curl, and more. Copy your API key from the API Key page to get started:
import requests
from datetime import date, timedelta
API_KEY = "nk_your_key"
BASE_URL = "https://aletaindex-narrative.com"
to_date = date.today()
from_date = to_date - timedelta(days=6) # 7-day window (inclusive)
resp = requests.get(
f"{BASE_URL}/v1/narratives/comprehensive",
headers={"X-API-Key": API_KEY},
params={
"tickers": "NVDA",
"from_date": from_date.isoformat(),
"to_date": to_date.isoformat(),
}
)
data = resp.json()
for narrative in data["results"][0]["global_narratives"]:
sentiment = narrative["sentiment"]
print(narrative["title"], "—", sentiment["sentiment_label"], f"({sentiment['avg_sentiment']:.2f})")
curl "https://aletaindex-narrative.com/v1/narratives/comprehensive?tickers=NVDA&from_date=2026-05-04&to_date=2026-05-10" \
-H "X-API-Key: nk_your_key"
Authentication
All endpoints require an API key passed as the X-API-Key request header. Your key starts with nk_ and is available on the API Key page. Never expose your key in client-side code.
headers = {"X-API-Key": "nk_your_key"}
Rate Limits
Limits are enforced per API key on a rolling 60-second window. When exceeded, the server returns 429 Too Many Requests with a Retry-After header indicating the seconds remaining until the window resets.
| Tier | Limit | Notes |
|---|---|---|
| Free | 100 req/min | Trial accounts |
| Plus | 300 req/min | Paid subscribers |
| Scale | Unlimited | Enterprise |
Data Model
All narrative data follows a three-level hierarchy:
Global Narratives are ranked by cumulative dominance score (sum across all daily topics in the requested window). Daily Topics within a narrative are sorted by dominance descending, then date descending. Articles within a topic are sorted by ticker_relevance_score × representativeness_score descending by default.
Endpoints
/v1/narratives/comprehensive
Primary endpoint. Returns the full narrative hierarchy — global narratives, daily topics, articles, and LLM-generated insights — for one or more tickers. Max 10 tickers per request; see batching guidance below for larger portfolios.
Parameters
| Parameter | Type | Description | |
|---|---|---|---|
tickers | string | required | Comma-separated ticker symbols, max 10 per request. e.g. NVDA,TSLA,AAPL. For portfolios >10 tickers, batch into separate requests. |
from_date | YYYY-MM-DD | required* | Start date (inclusive). Required unless all_time=true. |
to_date | YYYY-MM-DD | required* | End date (inclusive). Required unless all_time=true. Max range: 365 days. |
all_time | boolean | optional | Return full history from earliest available data. Ignores from_date. Default: false. |
article_limit | integer 1–100 | optional | Max articles returned in total across all narratives. Default: 100. |
article_sort_by | string | optional | representativeness (default) — most representative article first. time — most recent first. |
top_articles_per_daily_topic | integer 1–50 | optional | Cap articles surfaced per daily topic. e.g. 5 returns top 5 articles per topic. |
source | string | optional | Filter articles by source name (partial match). e.g. reuters. |
min_relevance | float 0–1 | optional | Minimum ticker_relevance_score threshold. e.g. 0.7 for high-relevance articles only. |
min_sentiment | float -1–1 | optional | Minimum sentiment score filter. |
max_sentiment | float -1–1 | optional | Maximum sentiment score filter. |
narrative_id | integer | optional | Drill into a single global narrative by its ID. |
paginate | boolean | optional | Enable article pagination (single ticker only). Use with article_limit and article_offset. |
article_offset | integer | optional | Article offset for pagination. Default: 0. |
include_aggregation | boolean | optional | Include daily topic mention counts and sentiment trend data. Default: false. |
from_date and to_date, or set all_time=true. The maximum date range is 365 days.
Batching for large portfolios
For portfolios exceeding 10 tickers, split into batches of 10 and merge results client-side. Each batch counts as one request against your rate limit quota.
import requests, time
API_KEY = "nk_your_key"
BASE_URL = "https://aletaindex-narrative.com"
tickers = ["NVDA","TSLA","AAPL","MSFT","AMZN","GOOGL","META","AMD","NFLX","JPM","GS","V"]
batches = [tickers[i:i+10] for i in range(0, len(tickers), 10)]
results = []
for batch in batches:
resp = requests.get(
f"{BASE_URL}/v1/narratives/comprehensive",
headers={"X-API-Key": API_KEY},
params={"tickers": ",".join(batch), "from_date": "2026-05-04", "to_date": "2026-05-10"},
).json()
results.extend(resp["results"])
time.sleep(0.2) # stay within rate limit
Response schema
{
"query_summary": {
"tickers": ["NVDA"],
"timeframe": { "from_date": "2026-05-04", "to_date": "2026-05-10", "days": 7 },
"requested_at": "2026-05-10T12:00:00+00:00"
},
"results": [
{
"ticker": "NVDA",
"timeframe": { "from_date": "2026-05-04", "to_date": "2026-05-10" },
"summary": {
"global_narrative_count": 5,
"daily_topic_count": 18,
"article_count": 94,
"source_count": 31
},
"insight": {
"insights": {
"summary": {
"overall_sentiment_trend": "improving",
"sentiment_trend_magnitude": 0.12,
"overall_sentiment_score": 0.38,
"overall_sentiment_label": "positive",
"dominant_narrative": { "title": "...", "sentiment": "positive" },
"key_metric": "Narrative momentum accelerating on Blackwell supply chain clarity"
},
"key_insights": [ "..." ],
"anomalies": [ "..." ],
"correlations": [ "..." ],
"behavioral_patterns": {
"narrative_correlations": [ "..." ],
"price_correlations": [ "..." ]
},
"narrative_colors": { "1042": "#4F8EF7" }
},
"generated_at": "2026-05-10T06:00:00+00:00",
"is_pre_generated": true,
"actual_timeframe": { "from_date": "2026-05-04", "to_date": "2026-05-10", "days": 7 }
},
"global_narratives": [
{
"id": 1042,
"title": "NVDA AI data center demand surge",
"created_at": "2026-01-15T08:22:00",
"last_updated_at": "2026-05-10T06:00:00",
"metadata": { "daily_topic_count": 5, "article_count": 34 },
"sentiment": { "avg_sentiment": 0.41, "sentiment_label": "positive" },
"daily_topics": [
{
"id": 882,
"title": "Blackwell GPU shipments beat estimates",
"dominance_score": 0.78,
"time": "2026-05-08",
"article_count": 7,
"avg_sentiment": 0.52,
"sentiment_label": "positive",
"articles": [
{
"id": 9921,
"title": "NVIDIA Blackwell shipments top Wall Street forecasts",
"source": "Reuters",
"link": "https://reuters.com/...",
"published_at": "2026-05-08T14:23:00",
"representativeness_score": 0.94,
"ticker_relevance_score": 0.88,
"rank_in_topic": 1,
"is_duplicate": false,
"is_near_duplicate": false,
"sentiment": { "score": 0.47, "label": "positive" }
}
]
}
]
}
]
}
]
}
Example
import requests
from datetime import date, timedelta
API_KEY = "nk_your_key"
BASE_URL = "https://aletaindex-narrative.com"
to_date = date.today()
from_date = to_date - timedelta(days=6)
resp = requests.get(
f"{BASE_URL}/v1/narratives/comprehensive",
headers={"X-API-Key": API_KEY},
params={
"tickers": "NVDA,TSLA",
"from_date": from_date.isoformat(),
"to_date": to_date.isoformat(),
"article_sort_by": "representativeness",
"top_articles_per_daily_topic": 5,
}
).json()
for result in resp["results"]:
print(result["ticker"], "—", result["summary"]["global_narrative_count"], "narratives")
for n in result["global_narratives"]:
s = n["sentiment"]
print(f" [{s['sentiment_label']:8s}] {n['title']}")
curl "https://aletaindex-narrative.com/v1/narratives/comprehensive?tickers=NVDA,TSLA&from_date=2026-05-04&to_date=2026-05-10&top_articles_per_daily_topic=5" \
-H "X-API-Key: nk_your_key"
/v1/portfolio/narrative-risk
Portfolio Narrative Risk Map. Given a list of holdings (ticker + weight), returns the dominant macro risk themes across your portfolio — each with exposure percentage, dominance score, and momentum trajectory (ESCALATING / STEADY / RECEDING). Themes are grouped using LLM-based semantic clustering, with cosine-similarity fallback. Analysis is based on the last 30 days of narrative data.
Request body
{
"holdings": [
{"ticker": "NVDA", "weight": 0.30},
{"ticker": "AMD", "weight": 0.20},
{"ticker": "TSLA", "weight": 0.25},
{"ticker": "AAPL", "weight": 0.25}
]
}
| Field | Type | Description | |
|---|---|---|---|
holdings | array | required | List of holdings. Max 50 per request. |
ticker | string | required | Ticker symbol (e.g. NVDA). |
weight | float | required | Portfolio weight. Can be decimal (0.30) or percentage (30.0) — normalized internally. |
Response schema
{
"top_risk": "AI Export Controls",
"narratives": [
{
"theme": "AI Export Controls",
"tickers": ["AMD", "NVDA"],
"ticker_narratives": [
{"ticker": "NVDA", "narrative": "NVDA Blackwell export license uncertainty"},
{"ticker": "AMD", "narrative": "AMD GPU export restrictions impact"}
],
"narrative_ids": [1042, 1055],
"exposure_pct": 50.0,
"dominance": 0.74,
"trajectory": "ESCALATING",
"momentum_delta": 0.12
}
],
"uncovered_tickers": [],
"credits_used": 4
}
Narratives are sorted by trajectory (ESCALATING first), then by exposure_pct descending. momentum_delta is the change in weighted dominance between the most recent 7-day window and the prior 7-day window. uncovered_tickers lists tickers for which no active narratives were found.
Credit cost
Credits deducted = number of unique tickers in the request. Returns 402 if balance is insufficient.
Example
import requests
API_KEY = "nk_your_key"
BASE_URL = "https://aletaindex-narrative.com"
resp = requests.post(
f"{BASE_URL}/v1/portfolio/narrative-risk",
headers={"X-API-Key": API_KEY, "Content-Type": "application/json"},
json={"holdings": [
{"ticker": "NVDA", "weight": 0.30},
{"ticker": "TSLA", "weight": 0.25},
{"ticker": "AAPL", "weight": 0.25},
{"ticker": "AMD", "weight": 0.20},
]}
).json()
print("Top risk:", resp["top_risk"])
for theme in resp["narratives"]:
print(f" {theme['trajectory']:11s} {theme['theme']:30s} {theme['exposure_pct']}% exposure")
curl -X POST "https://aletaindex-narrative.com/v1/portfolio/narrative-risk" \
-H "X-API-Key: nk_your_key" \
-H "Content-Type: application/json" \
-d '{"holdings":[{"ticker":"NVDA","weight":0.3},{"ticker":"TSLA","weight":0.25},{"ticker":"AAPL","weight":0.25},{"ticker":"AMD","weight":0.2}]}'
Terminology
- Global narrative — A persistent storyline spanning multiple days or weeks (e.g. "Tesla's AI & Robotaxi vision"). Narratives are discovered automatically through semantic clustering of articles.
- Daily topic — The day-specific manifestation of a global narrative: a cluster of articles covering that day's angle of the story. A narrative can have multiple daily topics on the same date if distinct sub-angles emerged.
- Dominance score — (0–1) How central a daily topic is within its global narrative on a given day. Higher = more representative of the narrative's core story that day.
- Representativeness score — (0–1) How well an individual article represents its daily topic cluster. Higher = more central to the cluster's semantic centroid.
- Ticker relevance score — (0–1) How specifically an article is about the requested ticker, rather than tangentially mentioning it. Scores below 0.5 are considered low-relevance.
- Sentiment score — Continuous scale from -1 (strongly negative) to +1 (strongly positive). Derived from a FinBERT-based model. Label thresholds: positive (>0.3), neutral (-0.3 to 0.3), negative (<-0.3).
- Momentum delta — Change in weighted dominance between the most recent 7-day window and the prior 7-day window. Positive = ESCALATING, negative = RECEDING, near-zero = STEADY.
- Behavioral patterns — Statistically-derived cross-signal structures computed over the full history: narrative co-movement, price-return correlations, and source-level sentiment divergence.
Errors
All errors return a JSON body: {"detail": "..."} describing the issue.
| Status | Meaning | Action |
|---|---|---|
| 400 | Invalid request — missing required fields, invalid date range, too many tickers, or conflicting parameters | Check the detail field for specifics |
| 401 | Missing or invalid API key | Verify your X-API-Key header on the API Key page |
| 402 | Insufficient API credits | Top up on the Subscription page |
| 403 | Account inactive, expired, or ticker requires a higher tier | Upgrade plan to access additional tickers, or contact support |
| 429 | Rate limit exceeded — Free: 100 req/min, Plus: 300 req/min | Check the Retry-After header for seconds until window resets |
| 500 | Internal server error | Safe to retry; transient errors resolve automatically |
Supported Tickers
109 tickers are currently tracked across 16 narrative themes. Ticker access depends on your plan:
Plus / Scale — access to all 109 tickers.
MCP Integration
Use AletaIndex directly inside Claude Code, Claude Desktop, Cursor, or any MCP-compatible AI agent — no API calls required. The agent discovers and calls tools automatically based on your natural language requests. Full MCP Quickstart →
Claude Code
Add to ~/.claude.json under mcpServers:
{
"mcpServers": {
"aletaindex": {
"command": "uvx",
"args": ["narrative-intelligence-mcp"],
"env": { "NARRATIVE_API_KEY": "your-api-key" }
}
}
}
Claude Desktop
- Open Claude Desktop → top menu Claude → Settings → Developer → Edit Config
- This opens
claude_desktop_config.json. AddmcpServersalongside the existingpreferenceskey:
{
"preferences": { ... },
"mcpServers": {
"aletaindex": {
"command": "uvx",
"args": ["narrative-intelligence-mcp"],
"env": { "NARRATIVE_API_KEY": "your-api-key" }
}
}
}
- Save the file, then relaunch Claude Desktop
uv must be installed — run in terminal: curl -LsSf https://astral.sh/uv/install.sh | sh
Getting started
Paste this at the start of your conversation to get the best results:
Example prompts
- "What narratives are driving NVDA this week?"
- "Analyze narrative risk for my portfolio: NVDA 30%, AAPL 25%, TSLA 20%, MSFT 25%"
- "Compare sentiment trends for GOOGL and META over the last 30 days"
- "What are the key narrative shifts in TSLA's latest daily topics, and what do the sentiment and behavioral pattern signals suggest?"
Narrative insight prompt
For a full narrative analysis similar to the Playground insight view:
Also available on
Install directly from your preferred MCP agent platform:
Full documentation and package source
AletaIndex / aletaindex-fin-narratives