Core Features

Multi-Engine

AFINN for speed, multiple Ollama cloud models, Claude for accuracy. Pick one or compare all.

📰

4 News Sources

Finnhub, AlphaVantage, Google News, Yahoo. Merge and deduplicate with source=all.

🗄️

2-Tier Cache

L1 memory + L2 Supabase. Same article never re-scored. Cached responses under 100ms.

🔗

RESTful + OpenAPI

Simple GET/POST endpoints. Full Swagger docs. Ready for RapidAPI distribution.

How We Score — Built for Trust

Every score is auditable. Every engine follows the same calibration standard. No black boxes.

📏

Canonical 7-Tier Scale

Not just Positive/Negative. Every engine maps to the same unified scale: Very Positive → Very Negative. Compare Claude vs Ollama vs AFINN apples-to-apples.

🧠

Chain-of-Thought Reasoning

LLMs extract facts, assess each one, then synthesize a score. Every result includes a reasoning string explaining WHY — not just a number.

🎯

Confidence Score

Every analysis includes a 0-1 confidence rating. High confidence = multiple clear signals. Low confidence = conflicting or limited data. Know when to trust.

Validation Layer

Outputs are range-checked and tier-validated. If a model says "Very Positive" but outputs +0.35, we catch the miscalibration before it reaches you.

📊

Multi-Dimensional

Polarity is just the start. We also score subjectivity, urgency, credibility, and market impact — because a Bloomberg breaking story is not the same as a blog rumor.

🔒

Never Re-Analyzed

Same article + same engine = same result, always. We store every analysis in our database. If it's been scored before, we serve the cached result — no wasted tokens, no drift.

Read Full Methodology →

Simple API, Powerful Results

// GET /api/sentiment/AAPL?engine=gpt-oss:120b-cloud&source=finnhub
{
  "ticker": "AAPL",
  "engine": "gpt-oss:120b-cloud",
  "combined": {
    "polarity": 0.42,
    "label": "Positive"
  },
  "articles": [
    { "title": "Evercore Hikes Apple PT...", "headline": { "label": "Positive" } },
    { "title": "Apple-OpenAI Alliance Frays", "headline": { "label": "Negative" } }
  ],
  "meta": { "cacheLayer": "L1" }
}
Try It Free →