---
title: "Per-ticker news-flow sentiment + attention"
method: GET
path: "/api/v1/equities/{symbol}/news-sentiment"
tags: ["Equities Indices"]
---

# Per-ticker news-flow sentiment + attention

`GET /api/v1/equities/{symbol}/news-sentiment`

Primary news-flow sentiment + attention for a ticker, entirely from Sugra-owned sources: GDELT tone + volume timelines and the 43-feed first-party RSS ingest, entity-linked via the SEC registrant name + former names (so coverage filed under an old name is still matched). This is editorial NEWS-FLOW sentiment, the defensible alternative to scraped social mention-counting - it does not capture retail crowd psychology or pre-news buzz. Cached 10min (GDELT's update cadence). Not investment advice.

## Path parameters

- `symbol` string, required — Company ticker symbol.

## Query parameters

- `timespan` string — GDELT lookback window.

## Response `200`

Sentiment (GDELT average document tone) and attention (coverage volume + first-party article count) time series for the company, plus recent first-party headlines.

- EnvelopeNewsSentimentData
  - `data` NewsSentimentData, required — DATA-9.6: per-ticker news-flow sentiment + attention from owned sources.
    - `symbol` string, required
    - `company_name` string, required
    - `former_names` string[]
    - `cik` string, nullable — SEC CIK of the resolved filer. Null when the registry could not be reached.
    - `match_basis` string — What the headlines were matched on. 'entity' = the registered legal name and its former names. 'symbol' = the bare ticker, used when the registry was unreachable; precision is lower, and much lower for tickers that are ordinary words (ALL, IT, ON, KEY, CAR, GO).
    - `entity_unavailable_reason` string, nullable — Null when the SEC registry answered. A reason string when it did not, in which case company_name falls back to the symbol and former_names is empty because it could not be looked up - not because the company never had another name (BUG-36).
    - `query` string, required — The entity query (current + former names) used.
    - `timespan` string, required
    - `sentiment` SentimentBlock, required
      - `latest_tone` number, nullable
      - `average_tone` number, nullable
      - `timeline` TimelinePoint[]
        - `date` string, required
        - `value` number, required
      - `scale` string, required
      - `unavailable_reason` string, nullable — Null when tone was measured. A reason string when the tone source could not be reached, so a null tone with a reason is never read as neutral sentiment (BUG-33).
    - `attention` AttentionBlock, required
      - `timeline` TimelinePoint[] — Coverage-volume time series.
        - `date` string, required
        - `value` number, required
      - `first_party_article_count` integer
      - `unavailable_reason` string, nullable — Null when coverage volume was measured. A reason string when the source could not be reached, so an empty series with a reason is never read as an absence of coverage (BUG-33).
    - `no_articles_matched` boolean, nullable — True only when the search ran on the RESOLVED entity, every source answered, and none of them had anything in the window. Null otherwise - including when match_basis is 'symbol', because that search ran on the bare ticker and finding nothing with it is not the same claim. An empty response without this flag was either not measured (see the unavailable_reason fields) or measured with a weaker query, and those mean different things: one is a fact about the company, the others are reasons to doubt.
    - `recent_headlines` NewsHeadline[]
      - `title` string, nullable
      - `source` string, nullable
      - `published` string, nullable
      - `url` string, nullable
    - `source` string
    - `note` string, required
  - `meta` SugraMeta, required — Metadata attached to every /api/v1/* response envelope.
    - `endpoint` string, required — Requested endpoint path.
    - `data_time` string, required — ISO 8601 UTC timestamp of the source data, not of the request.
    - `response_time` string, required — ISO 8601 UTC timestamp when this response was produced.
    - `provider` string, required — API name and version.
    - `source` string, nullable — Identifier of the primary upstream source used for this response.
    - `attribution` string, nullable — Human-readable attribution mandated by an upstream source (e.g. a securities regulator or self-regulatory organization). Present only on responses whose source requires the owner and source to be clearly identified. Do not remove or alter it when using the response.
    - `fallback_used` boolean, nullable — True when the primary source failed and a fallback produced the data.
    - `fallback_chain` string[], nullable — Ordered list of sources attempted, in the order they were tried.
    - `cached` boolean, nullable — True when this response was served from the internal cache.
    - `stale` boolean, nullable — True when the cached response was returned after the upstream rate-limited or errored. Clients can use this to detect degraded data.

## Other responses

- `400` — Invalid ticker symbol or timespan.
- `401` — Missing or invalid `x-api-key` header. JSON body with a stable `code` distinguishing `missing_api_key` (no header sent) from `invalid_api_key` (header sent, key not accepted); any other 401 source carries the generic `unauthorized` with its detail as `reason`. Plus `hint`. `plan` is always null on 401 - an unauthenticated request has no plan; quota exhaustion is 429, not 401.
- `404` — Symbol not resolvable to an SEC filer.
- `422` — Validation Error
- `429` — Daily rate limit exceeded. Check `X-RateLimit-Reset` for the next window.
- `502` — News-sentiment sources temporarily unavailable.
- `503` — Upstream source is temporarily unavailable. Retry after a short delay.

---

[API](https://skmtc.net/sugra/apis/sugra-api.md) · [All operations](https://skmtc.net/sugra/apis/sugra-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/sugra/sugra-api/revisions/a83e6a561bf2/schema)
