> ## Documentation Index
> Fetch the complete documentation index at: https://docs.gildea.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Changelog

> API changes, deprecations, and migration paths

This page tracks changes to the Gildea API. Each entry has:

* **Date**: when the change was announced or shipped
* **Status**: `Announcement` (heads-up only), `Deprecated` (still works, will be removed), `Shipped` (now live), or `Sunset` (removed)
* **Affected**: the endpoint, response field, or parameter that changed
* **Migration**: what consumers need to do, when there is something to do

For breaking changes, Gildea uses a three-phase timeline:

1. **Announcement**: change announced; old behavior still works
2. **Soft sunset**: old behavior continues but with deprecation headers / nulled fields
3. **Hard cutover**: old behavior removed

Check this page before upgrading.

***

## 2026-08-15

**Podcast sources: every high-signal segment is now its own signal**

**Status:** Shipped · **Affected:** podcast-sourced signals everywhere they appear (`citation.url`, card `title`, signal volume)

Previously, each podcast episode contributed a single signal: the one highest-signal segment. Now every segment that clears the quality gates becomes its own signal. Segments from the same episode differ by URL and title:

* **`citation.url` carries the exact audio span**: `?t=<start>&end=<end>` in integer seconds, e.g. `...watch?v=abc&t=1372&end=1818`. The URL is self-describing: this signal's source is seconds 1372 to 1818 of this episode. On YouTube-hosted episodes, opening the link seeks playback to the span's start.
* **Titles are `Episode — Chapter`** (e.g. "Tokens Are the New Dollars | Stripe with a16z — Agentic Commerce: The Missing Primitives"), so sibling segments are distinguishable in listings.
* **Verification pattern**: fetch the public audio and listen from `t`. The span bounds are the evidence locator, complementing `evidence_preview`.

Podcast coverage also expanded, so expect meaningfully more podcast-sourced signals per day. No endpoint or response-shape changes; segments ingested before 2026-08-15 keep their episode-level URLs.

***

## 2026-08-13

**`related_entities` capped at top 25**

**Status:** Shipped · **Affected:** `related_entities[]` in `GET /v1/entities/{name_or_id}`

Entity profiles now return the **top 25 co-occurring entities** by `co_occurrence_count` instead of the full list. Broad entities co-occur with most of the corpus: the largest profiles carried 500+ related entities and tens of KB of long tail that says little and blows the context budget of agent clients reading profiles over MCP. The entry shape is unchanged.

***

## 2026-08-11

**`evidence` → `evidence_preview`**

**Status:** Shipped · **Affected:** `unit.evidence` in `GET /v1/signals/{id}` and `GET /v1/search`

The unit field `evidence` is renamed **`evidence_preview`**, and the per-snippet preview cap drops from 100 to 50 characters. Same shape inside (`snippets[]` of `{ text, truncated }`). The rename says what the field is: a short verbatim locator into the source, deliberately not the full stored passage. Verification runs through `citation.url`.

***

## 2026-06-18

**Response v2: flat units, role axis, semantic naming**

**Status:** Shipped · **Affected:** `GET /v1/signals`, `GET /v1/signals/{id}`, `GET /v1/search`, entity `content_type_mix`

A single redesign of the `/v1` response shapes. This is the `/v1` contract going forward.

* **Signal detail is a flat `units[]`.** The nested `decomposition` tree (thesis/arguments/claims buckets, nested `sentences[]`, the `unit` wrapper) is gone. Each unit is `{ id, role, text, argument_id?, entities?, verification?, evidence? }`.
* **`role` axis** replaces `unit.type`: `thesis | synopsis | argument | claim`. Reconstruct prose by role; group `argument` units by `argument_id`. List position is the order (no index field).
* **`content_type`** values are now `analysis` | `event` (was `factual_event`); entity `content_type_mix` keys follow.
* **Card** carries the central statement whole as `thesis` (analysis) / `synopsis` (event). The old `development` field and the `argument_count` / `argument_headlines` previews are removed.
* **`domain`** is now a flat field (was `source: { domain }`).
* **`verified_text_unit_count` → `verified_unit_count`** (equals `len(units)`).
* **Evidence is returned by default** on signal detail; the `?include=evidence` parameter is removed.
* **Search hits** nest the byte-identical unit object: `{ unit, citation, relevance_score }`, with `verification` / `evidence` inside `unit`, `unit.type → role`, and inline evidence `snippets` (the `snippet_count` field and the `diagnostics` block are gone). The search filter is now `role=` (was `type=sentence|claim`).
* **SDK** bumped to **0.8.0** for the new shapes.

***

## 2026-06-14

**Better rate-limit signals (additive)**

**Status:** Shipped · **Affected:** all endpoints (429 responses + rate-limit headers)

Non-breaking improvements so clients can pace and back off accurately:

* **`X-RateLimit-Reset-Minute` / `X-RateLimit-Reset-Monthly`** headers added to every authenticated response (unix epoch seconds until each window resets).
* **`429` responses now carry the full `X-RateLimit-*` header set** (previously only `Retry-After`), so a throttled client can see which window was hit and when it clears.
* **`Retry-After` is now computed from the actual window reset** instead of a fixed value: the per-minute value ranges 1-60s, and the monthly value reflects the real reset rather than a misleading constant.
* **`retry_after` and `reset` are echoed into the `429` JSON body**, so clients that only parse the body (not headers) can still back off correctly.

No action required; these are additive.

***

## 2026-06-12

**List text filters renamed; search `entity` accepts names**

**Status:** Shipped · **Affected:** `GET /v1/signals`, `GET /v1/entities`, `GET /v1/search`

Two consistency changes so a parameter name always means one thing:

* **`q` is now reserved for semantic search.** On the list endpoints the literal text filter has been renamed to match what it does: `GET /v1/signals` uses `keyword` (was `q`), `GET /v1/entities` uses `name` (was `q`). `q` continues to mean a natural-language semantic query, and only `GET /v1/search` has it. The SDK and MCP tools follow the same rename (`signals.list(keyword=…)`, `entities.list(name=…)`).
* **`GET /v1/search?entity=` now accepts a display name** in addition to a `gld:/…` public ID, matching the signals filter. Names resolve to the family-level canonical entity; pass the public ID when you need guaranteed precision.

**Migration:** Update `GET /v1/signals?q=` → `?keyword=` and `GET /v1/entities?q=` → `?name=` (and the matching SDK/MCP keyword args). The old `q` parameter on these two endpoints is no longer read; requests still succeed but the filter is silently ignored, so check any list call that relied on `q`. No change required for `GET /v1/search`.

***

## 2026-04-28

**Improved analysis extraction (v4)**

**Status:** Shipped · **Affected:** Analysis signals (`content_type=analysis`). Event signals are unaffected.

Analysis articles ingested from this date forward use a refreshed extraction pipeline:

* Each article now decomposes into 3-6 atomic supporting arguments (vs. 1 broader argument previously)
* Claims are extracted at the article level rather than under a single argument, removing the constraint that previously limited claim count

The net effect is denser content per article: more arguments and more claims per signal.

Articles ingested before 2026-04-28 retain their previous extraction. The API response shape is identical across vintages.
