# Market Mood API

> SentiSense's proprietary fear and greed index plus the market-wide sentiment rollups: a 0-100 composite score, per-sector tone versus the market, and daily sentiment breadth.

Base URL: `https://app.sentisense.ai/api/`
Tier: Free (API key required)

All API access requires an API key via the `X-SentiSense-API-Key` header. Keys look like `ss_live_...`.

> SDKs: [Python](https://github.com/SentiSenseApp/sentisense) · [Node](https://github.com/SentiSenseApp/sentisense-node#market-mood)

## Overview

Market Mood is SentiSense's proprietary 0-100 composite that blends six sub-signals (social sentiment, market direction, risk appetite, social momentum, S&P 500 trend, options flow) into a single fear-or-greed score plus a phase label. The endpoint returns the latest score, the daily history, the per-signal breakdown, and per-sector aggregations so you can compare a sector's mood against the broader market.

Market Mood is SentiSense's own fear-and-greed index for the US stock market. The same reading is also served in the shared index envelope at `/api/v1/indexes/market-mood`; see the [Indexes API](/docs/api/indexes/).

Two companion rollups on this page describe the same market from the news-and-social tone side rather than the composite-score side: `/api/v1/sentiment/sectors` ranks the 11 GICS sectors against the market's own tone, and `/api/v1/sentiment/breadth` gives the daily bullish/neutral/bearish split of the covered stock universe. All three are precomputed daily snapshots on the same pipeline cadence.

**Use cases:**
- Build a top-of-page fear/greed gauge for your own dashboard
- Track regime changes (Greed -> Neutral -> Fear) on a 6-month rolling window
- Compare sector-level moods to spot rotation (e.g. Technology in Greed while Energy in Fear)
- Plot any of the six sub-signals on its own time series
- Render a sector heatmap colored by tone relative to the market, not by absolute tone
- Chart sentiment breadth as the tone analogue of an advance/decline line

**Versioning:** this page spans two API versions. Market Mood lives at `/api/v2/market-mood` (v2, not the `/api/v1/...` prefix used by most other endpoints); the two sentiment rollups live under `/api/v1/sentiment/`.

**Access:** send your API key on every call. All three endpoints are available on every tier (no PRO gating). Requests count against your monthly quota and per-minute rate limit.

Examples in curl, Python, Node and an AI agent: [Fear and Greed Index API](/blog/fear-and-greed-index-api/).

---

## GET /api/v2/market-mood

Returns the current Market Mood composite, the daily history over the requested window, the per-signal breakdown, and per-sector summaries.

**Parameters:**

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| `days` | int | No | 180 | Days of history to return |

**Example Request:**

```bash
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
  "https://app.sentisense.ai/api/v2/market-mood?days=90"
```

```python
from sentisense import SentiSenseClient

client = SentiSenseClient(api_key="ss_live_YOUR_KEY")
result = client.get_market_mood(days=90)
print(f"Score: {result['market']['currentScore']} ({result['market']['phase']})")
print(f"Weekly change: {result['market']['weeklyChange']}")
for signal in result["market"]["signals"]:
    print(f"  {signal['label']}: {signal['value']} (week change: {signal['change']})")
```

**Response Schema:**

| Field | Type | Description |
|-------|------|-------------|
| `market.currentScore` | double | Latest composite score, 0-100 (null if no data) |
| `market.phase` | string | Plain-text phase label derived from the score. One of seven bands: `"Extreme Fear"` (0-15), `"Fear"` (16-30), `"Anxiety"` (31-45), `"Neutral"` (46-55), `"Optimism"` (56-70), `"Greed"` (71-85), `"Extreme Greed"` (86-100); `"---"` when the score is null |
| `market.weeklyChange` | double | Composite score change vs ~7 days ago (null when insufficient history) |
| `market.signals` | array | Per-signal breakdown. Up to 6 entries; only signals present in the latest reading are listed, so match on `key`, not array position |
| `market.history` | array | Daily history points |
| `sectors` | object | Map of sector name to sector summary (currentScore, phase, weeklyChange) |

**Signal entry:**

| Field | Type | Description |
|-------|------|-------------|
| `key` | string | One of `social_sentiment`, `market_direction`, `fear_gauge`, `social_momentum`, `spy_trend`, `options_flow` |
| `label` | string | Human-readable label (e.g. `"Social Sentiment"`, `"S&P 500 Trend"`) |
| `value` | double | Latest value of this sub-signal, 0-100 |
| `change` | double | Change vs ~7 days ago (null when insufficient history) |

**History point:**

| Field | Type | Description |
|-------|------|-------------|
| `date` | string | New York date in `YYYY-MM-DD` format |
| `timestamp` | long | Epoch milliseconds for the data point |
| `score` | double | Composite score for that day |
| `socialSentiment` | double | Social sentiment sub-signal value. Null on days the signal had no reading, so guard the sub-signals rather than assuming every history row is fully populated |
| `marketDirection` | double | Market direction sub-signal value |
| `fearGauge` | double | Risk appetite sub-signal value (inverse-VIX; field name retained for compatibility) |
| `socialMomentum` | double | Social momentum sub-signal value |
| `spyTrend` | double | S&P 500 trend sub-signal value |
| `optionsFlow` | double | Options flow sub-signal value |

**Sector summary:**

| Field | Type | Description |
|-------|------|-------------|
| `currentScore` | double | Latest composite score for the sector |
| `phase` | string | Plain-text phase label |
| `weeklyChange` | double | Score change vs ~7 days ago (null when insufficient history) |

**Example Response:**

```json
{
  "market": {
    "currentScore": 62.4,
    "phase": "Optimism",
    "weeklyChange": 4.2,
    "signals": [
      { "key": "social_sentiment", "label": "Social Sentiment", "value": 58.3, "change": 1.5 },
      { "key": "market_direction", "label": "Market Direction", "value": 70.0, "change": 5.0 },
      { "key": "fear_gauge", "label": "Risk Appetite", "value": 55.0, "change": -2.1 },
      { "key": "social_momentum", "label": "Social Momentum", "value": 60.5, "change": 3.0 },
      { "key": "spy_trend", "label": "S&P 500 Trend", "value": 68.2, "change": 6.0 },
      { "key": "options_flow", "label": "Options Flow", "value": 57.0, "change": 1.2 }
    ],
    "history": [
      { "date": "2026-04-01", "timestamp": 1775016000000, "score": 55.0, "socialSentiment": null, "marketDirection": 60.0, "fearGauge": 55.0, "socialMomentum": 50.0, "spyTrend": 60.0, "optionsFlow": 57.0 }
    ]
  },
  "sectors": {
    "Information Technology": { "currentScore": 70.5, "phase": "Greed", "weeklyChange": 3.2 },
    "Financials":             { "currentScore": 48.0, "phase": "Neutral", "weeklyChange": -1.5 }
  }
}
```

---

## GET /api/v1/sentiment/sectors

Returns the per-sector sentiment rollup behind the [/sentiment](https://app.sentisense.ai/sentiment) page: the 11 GICS sectors compared against the overall market's news-and-social tone.

Financial news carries a structural positive skew as a genre, so an absolute sector reading is bullish on most days and separates sectors poorly. The comparable value is `consensusVsMarket`, the signed gap between a sector's own bullish-versus-bearish mention balance and the market's. A negative value means the sector is running cooler than the market, not that it is bearish.

**Parameters:** none.

**Example Request:**

```bash
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
  "https://app.sentisense.ai/api/v1/sentiment/sectors"
```

**Response Schema:**

| Field | Type | Description |
|-------|------|-------------|
| `schemaVersion` | string | Snapshot schema version |
| `generatedAt` | long | Epoch seconds for when the rollup was computed |
| `asOf` | string | New York calendar day the snapshot represents, `YYYY-MM-DD` |
| `narrative` | string | One-line templated summary (most and least bullish sector, plus covered stock count) |
| `marketConsensusRatio` | double | The whole covered universe's directional-consensus ratio for the window, bounded (-1, 1). This is the baseline each sector's `consensusVsMarket` is measured against |
| `sectors` | array | One row per GICS sector |

**Sector row:**

| Field | Type | Description |
|-------|------|-------------|
| `sector` | string | GICS level-1 display name (e.g. `"Information Technology"`) |
| `meanSentiment` | double | Mean sentiment polarity across covered member stocks, `[-1, 1]` |
| `label` | string | Tone label for `meanSentiment`: `"Bullish"`, `"Neutral"`, or `"Bearish"` |
| `meanScore` | double | Mean SentiSense Score across covered members (conviction-weighted, signed, open-ranged) |
| `scoreLabel` | string | Band label for `meanScore` |
| `consensusRatio` | double | The sector's own directional-consensus ratio over summed member bullish and bearish mention counts, bounded (-1, 1) |
| `consensusVsMarket` | double | `consensusRatio` minus `marketConsensusRatio`. Positive means the sector runs hotter than the market over the same window, negative means cooler |
| `consensusLabel` | string | Band label for `consensusVsMarket`: `"Hotter than market"`, `"In line with market"`, or `"Cooler than market"` |
| `bullMentions` | long | Summed bullish member mentions for the window |
| `bearMentions` | long | Summed bearish member mentions for the window |
| `stockCount` | integer | Member stocks that had a sentiment reading (confidence cue) |
| `totalMentions` | long | Summed mention volume across those stocks (confidence cue) |
| `topStock` | object | Most bullish member stock, as a stock reference |
| `bottomStock` | object | Most bearish member stock, as a stock reference |

**Stock reference** (`topStock`, `bottomStock`):

| Field | Type | Description |
|-------|------|-------------|
| `ticker` | string | Member stock ticker |
| `value` | double | That stock's sentiment polarity, `[-1, 1]` |

**Example Response** (one sector shown):

```json
{
  "schemaVersion": "1.0",
  "generatedAt": 1785597251,
  "asOf": "2026-08-01",
  "narrative": "As of 2026-08-01, Information Technology is the most bullish sector and Communication Services the least bullish by conviction-weighted SentiSense Score, across 959 covered US stocks.",
  "marketConsensusRatio": 0.3204,
  "sectors": [
    {
      "sector": "Information Technology",
      "meanSentiment": 0.1735,
      "label": "Bullish",
      "meanScore": 3.4609,
      "scoreLabel": "Neutral",
      "consensusRatio": 0.2861,
      "consensusVsMarket": -0.0343,
      "consensusLabel": "In line with market",
      "bullMentions": 6117,
      "bearMentions": 3395,
      "stockCount": 163,
      "totalMentions": 882,
      "topStock": { "ticker": "AMBA", "value": 0.8235 },
      "bottomStock": { "ticker": "KN", "value": -0.3 }
    }
  ]
}
```

---

## GET /api/v1/sentiment/breadth

Returns market-wide sentiment breadth: the daily share of the covered US stock universe leaning bullish, neutral, or bearish. It is the tone analogue of an advance/decline line, where each covered stock casts one vote by its mean sentiment.

Each bucket carries the same classification under two weightings. The stock-weighted fields (`bullish`/`neutral`/`bearish` and their `*Pct`) give one vote per stock; the mention-weighted fields (`*MentionPct`) weight those votes by each stock's mention volume. When the two disagree, a small number of heavily covered names is carrying the tone.

**Parameters:** none.

**Example Request:**

```bash
curl -H "X-SentiSense-API-Key: ss_live_YOUR_KEY" \
  "https://app.sentisense.ai/api/v1/sentiment/breadth"
```

**Response Schema:**

| Field | Type | Description |
|-------|------|-------------|
| `schemaVersion` | string | Snapshot schema version |
| `generatedAt` | long | Epoch seconds for when the rollup was computed |
| `asOf` | string | New York calendar day the snapshot represents, `YYYY-MM-DD` |
| `minMentions` | integer | Minimum mention volume for a stock to count toward breadth (confidence floor) |
| `latest` | object | Today's bucket, repeating the newest entry in `series` |
| `series` | array | Backfilled daily history, oldest to newest, for a distribution chart |

**Bucket** (`latest` and each `series` entry):

| Field | Type | Description |
|-------|------|-------------|
| `date` | string | New York calendar day for this bucket, `YYYY-MM-DD` |
| `coveredStocks` | integer | Stocks with a reading that cleared `minMentions`. This is the breadth denominator |
| `totalMentions` | long | Summed mention volume across those stocks |
| `bullish` | integer | Covered stocks classified bullish |
| `neutral` | integer | Covered stocks classified neutral |
| `bearish` | integer | Covered stocks classified bearish |
| `bullishPct` | double | Bullish share of covered stocks, percent `[0, 100]` |
| `neutralPct` | double | Neutral share of covered stocks, percent |
| `bearishPct` | double | Bearish share of covered stocks, percent |
| `netBreadth` | double | `bullishPct` minus `bearishPct`, in percentage points `[-100, 100]` |
| `bullishMentionPct` | double | Bullish share of mentions rather than of stocks, percent |
| `neutralMentionPct` | double | Neutral share of mentions, percent |
| `bearishMentionPct` | double | Bearish share of mentions, percent |
| `sentimentDispersion` | double or null | Population standard deviation of per-stock sentiment polarity (`-1` to `1`) across the covered stocks. High means stocks disagree with each other, low means one shared mood. Null when fewer than two stocks are covered |

**Example Response** (one history bucket shown):

```json
{
  "schemaVersion": "1.0",
  "generatedAt": 1785597251,
  "asOf": "2026-08-01",
  "minMentions": 5,
  "latest": {
    "date": "2026-08-01",
    "coveredStocks": 266,
    "totalMentions": 3063,
    "bullish": 137,
    "neutral": 64,
    "bearish": 65,
    "bullishPct": 51.5,
    "neutralPct": 24.06,
    "bearishPct": 24.44,
    "netBreadth": 27.06,
    "bullishMentionPct": 55.21,
    "neutralMentionPct": 20.37,
    "bearishMentionPct": 24.42,
    "sentimentDispersion": 0.1837
  },
  "series": [
    {
      "date": "2026-07-02",
      "coveredStocks": 218,
      "totalMentions": 2619,
      "bullish": 102,
      "neutral": 62,
      "bearish": 54,
      "bullishPct": 46.79,
      "neutralPct": 28.44,
      "bearishPct": 24.77,
      "netBreadth": 22.02,
      "bullishMentionPct": 46.54,
      "neutralMentionPct": 28.45,
      "bearishMentionPct": 25.01,
      "sentimentDispersion": 0.1712
    }
  ]
}
```

## Notes

- The `phase` label (for both the market and each sector) maps from the score across seven bands: Extreme Fear (0-15), Fear (16-30), Anxiety (31-45), Neutral (46-55), Optimism (56-70), Greed (71-85), Extreme Greed (86-100).
- Market Mood is recomputed several times each US trading day, with the last pass in the evening Eastern time, so a day's reading settles after the close. It is not a live tick; check the `history` dates to see the freshness of the latest point.
- The six sub-signals are documented in the SentiSense methodology pages on the main site.
- Sector keys (e.g. `Information Technology`, `Financials`) follow the GICS level-1 sector taxonomy on both `/api/v2/market-mood` and `/api/v1/sentiment/sectors`; the exact set on Market Mood is whatever has been computed for the requested window.
- The two sentiment rollups are precomputed daily snapshots written by the same pipeline, on the same cadence as Market Mood. Reading them never recomputes, so `generatedAt` is the freshness signal. Before the first pipeline run of a new snapshot they return an empty shape (`sectors: []`, or no `latest` and an empty `series`) rather than an error.
- Null fields are omitted from the two sentiment rollups rather than serialized as `null`, so treat any field in the tables above as optional.
- `consensusRatio` and `consensusVsMarket` are tone ratios, not SentiSense Scores. They use their own classifier and must not be read with the Score bands; the two quantities are on different scales.
- For per-stock sentiment time series, use the [Metrics API](/docs/api/metrics/). For the ranked most-bullish and most-bearish stock lists, use the `sentiment-leaderboard` and `sentiment-movers` [trackers](/docs/api/trackers/).
