---
title: "Get a news article by UID"
method: GET
path: "/api/news/{uid}/"
tags: ["news"]
---

# Get a news article by UID

`GET /api/news/{uid}/`

## Path parameters

- `uid` string, required

## Response `200`

A single enriched article.

- RichNewsArticle
  - `original` OriginalArticle, required — The article as fetched from the source. `raw_text` is intentionally NOT exposed here.
    - `id` integer
    - `uid` string, required
    - `title` string, required
    - `url` string, uri, required
    - `time_published` string, date-time, required
    - `authors` string[]
    - `summary` string, required — AI-generated summary safe to redistribute.
    - `banner_image` string, uri, nullable
    - `source` string, required
    - `source_domain` string
    - `topics` Topic[]
      - `topic` string, required
      - `relevance` number, float, required
    - `tickers_sentiment` object[]
    - `ownership_form` 'direct' | 'indirect', nullable — SEC Form 4 insider rows only — the holding pool the transaction touched. `null` for non-insider news. A single Form 4 can surface a `direct` and an `indirect` leg of the same plan as two separate articles (same filing URL, same date); they are distinct economic events, so SUM them rather than dedupe by URL/accession.
    - `created_at` string, date-time — When AlphaAI received the article — NOT its publish time (that is `time_published`). Use it to judge how fresh a pickup is. Do not build "what's new" polling on this field; that is what `sort=ingested` on `/api/news/` and `/api/news/insider/` is for.
    - `updated_at` string, date-time — Last time the stored article row was touched (including internal maintenance). Informational only.
  - `enrichment` EnrichedArticle, required
    - `category` 'earnings' | 'mergers_acquisitions' | 'regulation' | 'macro_economy' | 'sector_analysis' | 'market_movers' | 'technology' | 'commodities' | 'crypto' | 'ipo' | 'geopolitics' | 'insider' | 'corporate_actions' | 'other' — `market_movers` is for articles whose subject IS a notable price move ("AMD up 5% today"); `sector_analysis` is genuine sector-level analysis; `insider` covers SEC Form 4 insider transactions only. SEC 8-K filings categorize by their primary item: an earnings release (Item 2.02) is `earnings`, a completed acquisition or disposition (Item 2.01) is `mergers_acquisitions`, and the remaining events (material agreements, debt, executive changes, annual-meeting results) are `corporate_actions`.
    - `tickers` string[] — Validated tickers the article mentions — only symbols present in `/api/symbols/` survive enrichment-time verification against the article text. Mirrors `ai_trading_insights.ticker_analysis[].ticker`.
    - `relevance_score` integer — How much trading value the article itself carries (rates the article, not the company; deterministic — same article, same score): 1–2 no trading relevance · 3–4 derivative content about already-known events · 5–6 macro/sector datapoints, minor-but-real company news · 7–8 real company news with a fresh catalyst · 9–10 primary, material, newly disclosed. SEC Form 4 rows are scored from the transaction itself (size, buy vs. sell, 10b5-1 plan or not) rather than by the model.
    - `ai_trading_insights` AITradingInsights
      - `ticker_analysis` TickerAnalysis[]
        - `ticker` string
        - `relevance_context` string
        - `impact_analysis` ImpactAnalysis
          - `summary` string
          - `sentiment` 'positive' | 'neutral' | 'negative'
          - `price_impact_prediction` string
          - `confidence` 'high' | 'medium' | 'low'
          - `reasoning` string
      - `news_trading_value` NewsTradingValue
        - `actionability_score` 'high' | 'medium' | 'low' | 'negligible'
        - `information_novelty` integer — How much NEW information the article carries (1–10), kept separate from relevance: a mega-cap post-earnings recap is high relevance but low novelty. 0 on rows enriched before the field existed.
        - `timing_relevance` string
        - `market_sentiment_alignment` string
        - `estimated_read_time` string
      - `indirect_market_effects` IndirectMarketEffects
        - `sector_implications` string
        - `regional_market_impact` string
        - `global_market_relevance` string
      - `alternative_perspectives` AlternativePerspectives
        - `contrarian_view` string
        - `overlooked_factors` string
    - `news_context_enhancement` NewsContextEnhancement
      - `background_context` string
      - `impact_analysis` string
      - `key_entities` KeyEntity[]
        - `name` string
        - `type` string
        - `description` string
      - `market_relevance_summary` string
      - `estimated_read_time_minutes` integer
  - `story_id` string, nullable — Populated whenever the response is story-collapsed — `?collapse=story` on `/api/news/`, and always on `/api/news/trending/`. The `uid` of this story's representative article — equal to this item's own `original.uid`, and resolvable via `/api/news/{uid}/`. `null` in the default (uncollapsed) feed.
  - `sources_count` integer, nullable — Story-collapsed responses only. Number of distinct outlets (source domains) covering this story; the same outlet running it more than once counts once. Most stories are carried by a single outlet, so this is usually 1. Treat a value above 1 as the signal, not the number itself. May exceed the length of `sources`, which is capped at 10. `null` in the default feed.
  - `sources` string[], nullable — Story-collapsed responses only. Distinct source domains covering this story, in first-appearance order, capped at 10. `null` in the default feed.
  - `insider` InsiderEvent — Structured SEC Form 4 event: the aggregate of the news row's whole transaction group (one row fronts a filing's non-derivative trades of one type and holding form, so a 10b5-1 ladder is ONE event). `shares` and `total_value_usd` are group sums; `avg_price_usd` is the value-weighted average over priced tranches. Money and share fields are decimal STRINGS to preserve precision.
    - `side` 'buy' | 'sell' | 'other', required — Signal label from the transaction code: `buy` (P, open-market purchase), `sell` (S, open-market sale), `other` for everything else — including D (sale to the issuer: a buyback/redemption, not an open-market disposition). Use `transaction_code` for your own mapping.
    - `transaction_code` string, required — Raw SEC Form 4 transaction code (`P`, `S`, `D`, …).
    - `shares` string, required — Total shares across the event's tranches (decimal string).
    - `avg_price_usd` string, nullable — Value-weighted average price per share over priced tranches. `null` when the filing prices no tranche.
    - `total_value_usd` string, nullable — Total USD value across priced tranches (a lower bound when some tranches are unpriced). `null` when no tranche is priced.
    - `is_10b5_1` boolean, required — True when any tranche executed under a pre-arranged 10b5-1 plan.
    - `insider_name` string, required
    - `insider_title` string, required
    - `is_officer` boolean, required
    - `is_director` boolean, required
    - `is_ten_percent_owner` boolean, required
    - `transaction_date` string, date, required — Date of the group's last fill (a ladder can span days).
    - `filed_at` string, date-time, required — When EDGAR accepted the filing (UTC). Compare against `transaction_date` for your own lateness rule.
    - `late_filing` boolean, required — The filing missed the SEC's two-business-day deadline (Rule 16a-3(g)). Computed on Eastern dates, since EDGAR accepts filings until ~22:00 ET, and with one weekday of slack so a trade in a holiday week is not flagged: true when more than three weekday-days separate `transaction_date` from the filing. About 3% of events carry it; the long tail is catch-up filings covering trades from years earlier.

## Other responses

- `401` — Missing or invalid API key.
- `404` — No item with that identifier.
- `429` — Rate limit exceeded — either the per-minute burst cap or the per-day volume cap. The `Retry-After` header tells you how long to wait (a burst block is short, ≤60s; a day-cap block is capped at 3600s — the true reset is `X-RateLimit-Reset`). The `X-RateLimit-*` trio shows the daily volume budget. The body's `extra` names your tier, its `limit_per_minute` / `limit_per_day`, `retry_after_seconds`, and — below Pro — an `upgrade` block with the higher tiers' caps and the pricing URL.

---

[API](https://skmtc.net/alphai/apis/alphai-rest-api.md) · [All operations](https://skmtc.net/alphai/apis/alphai-rest-api/llms.txt) · [OpenAPI document](https://skmtc-service-staging.skmtc.workers.dev/v1/apis/alphai/alphai-rest-api/versions/2f34f38bad24/schema)
