> For the complete documentation index, see [llms.txt](https://docs.heron-intelligence.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.heron-intelligence.com/documentation/changelog.md).

# Changelog

All notable changes to the Heron Intelligence Data Product API will be documented in this file.

The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## \[Unreleased]

### Changed — Evasion v0.3 — 2026-10-13 — **breaking**

* [**Evasion**](/api-reference/api-reference/evasion.md) analyses:
  * `company_id` is replaced by a `company` object: `{ company_id, company_name, stock_ticker }`.
  * `ai_generated` is removed from analyses and exchanges. Every verdict is a language model's judgement; the [Provenance](/api-reference/api-reference/evasion.md#provenance) section says so and that has not changed.
  * `call.fiscal_quarter` is removed: it duplicated `call.fiscal_period`. The `fiscal_quarter` **filter** is removed too and replaced by `fiscal_period`, an exact match on `call.fiscal_period` (so `"5"` and month values can be filtered on). A request that still sends `fiscal_quarter` returns **`422`** instead of being silently ignored.
  * New `call.call_kind`: `earnings_call`, `fixed_income`, `investor_event` or `other`. Fixed-income sessions and investor days were typed as earnings events, so `call_type` alone could not tell them apart.
  * `historical_average_evasive_ratio` now covers **earnings calls only**, and identical same-day duplicates count once. A fixed-income session or investor event carries the earnings-call average as of its date but does not feed it. Values moved on 1,784 analyses of 33 companies.
  * `company_ticker` is case-insensitive, and a ticker that more than one company carries now returns **`409`** with the candidates instead of mixing their analyses. Use `company_id`.
  * Field definitions rewritten for the published spec. `topics` overlap and do not sum to the call, and `outlier` / `outlier_predictive` are documented with their actual definitions.
  * The `outlier` definition no longer claims to be reproducible from this API's data: Paragon computes it, its KDE bandwidth and call population are not published, and a recomputation matches most flags but not all.

### Documentation — 2026-09-17

* [**Data Providers**](/documentation/data-providers.md) — new canonical page defining the four research datasets (`Blue Heron`, `Paragon`, `Heron AI`, `Heron AI Events`), how each surface references them, how entitlement differs from coverage, and how to report provenance to an end user.
  * The REST API filters by provider **id** (`data_source_provider_ids`, resolved from `GET /api/v1/data-sources`); the MCP server filters by provider **name** (`data_provider_names`). The two are not interchangeable.
  * Documents two known server-side defects pending a fix: `provenance_note` on transcript-list responses merges `Heron AI Events` into `Heron AI`, labels `Paragon` as a third-party provider, and reports page-scoped counts without disclosing the scope; and `list_data_providers` still returns `produced_by: "third_party"` with a pre-acquisition description for `Paragon`. Neither field should be surfaced verbatim.
* [**MCP Server**](/overview/mcp.md) — documents the full 33-tool surface across five families, the efficiency contracts, transcript-content selectors, watchlists, drops, and which of `get_company_overview` / `get_recent_transcripts` is authoritative for a coverage total.
* [**Interviews**](/api-reference/api-reference/interviews.md) — full filter and response-field reference. `due_diligence_type` is the MDD/BDD filter; the response's `call_type` is free text and is not that value.
* [**Watchlist**](/api-reference/api-reference/watchlist.md) — clarifies that the REST endpoints manage the watchlist **record** only. No REST endpoint exposes or edits company membership.
* [**Data Sources**](/api-reference/api-reference/data-sources.md) — response shape (`id`, `name`), and the id → `data_source_provider_ids` flow.
* [**Data Models**](/documentation/data-models.md) — adds the shared pagination envelope, every enumerated field, and the nullable fields worth guarding.
* [**Error Handling**](/documentation/error-handling.md) — adds `201` / `204` success codes, the `422` `detail[]` shape, why cross-scope reads return `404` rather than `403`, and why a provider-filtered empty result is not an absence of coverage.
* [**Research Request**](/api-reference/api-reference/research-request.md) — names the three intake steps (Research Brief → Setup Configuration → Focus Areas) and maps them to `current_step`.
* **Heron Intelligence Skill** — corrected provenance handling, count authority and entitlement-aware empty results; added coverage for the batch resolvers, transcript selectors, watchlists and drops.

***

## \[1.6.0] - 2026-05-29

### Added

* **Sandbox environment** (`https://api-sandbox.heron-intelligence.com`)
  * A non-production environment with the same endpoints and `x-api-key` authentication as production, for safely building and testing integrations against non-production data.
  * Sandbox API keys are issued separately and scoped to the sandbox. Request one from the Heron Intelligence team.
  * See [Sandbox Environment](/api-reference/api-reference/sandbox.md).

## \[1.5.0] - 2026-05-26

### Changed

* **Research Requests** (`POST /api/v1/operations/research-request`) — **breaking**
  * Response is now a slim confirmation: `{ name, status, research_id }`. Use the new `GET /research-request/{research_id}` to fetch the full project.
  * New optional request field `template` — when set to `bdd`, `mdd`, or `public_records`, only the template's required variable fields are read from the payload; every other field is replaced by the template's canonical content.
    * `bdd` requires `company_id`, `deadline`.
    * `mdd` requires `executive_names`, `deadline`.
    * `public_records` requires `company_id`, `deadline`.
  * Missing required variables for a chosen template return `422` with a `missing_fields` array.
* **Research Requests** (`GET /api/v1/operations/research-request`) — **breaking**
  * Now returns a paginated list of lightweight summary items via the standard `PaginatedResponse` envelope (`data`, `pagination`).
  * New query parameters: `page` (default 1), `per_page` (default 20, max 100), `status` (optional filter), `scope` (`user` default, or `firm` to span every API key of the same firm).
  * Each list item is a summary (`name`, `status`, `research_id`, `created_at`, `updated_at`). For the full project, hit the new detail endpoint.

### Added

* **Research Requests** (`GET /api/v1/operations/research-request/{research_id}`)
  * Returns the full project detail, including a `transcripts[]` array of every transcript delivered against the project so far.
  * Excludes internal `id` and `user_id` fields.
  * Cross-scope access (other firm / other user when `scope=user`) returns `404`.
* **Webhooks** (`POST /api/v1/webhooks`, `GET /api/v1/webhooks`, `DELETE /api/v1/webhooks/{subscription_id}`)
  * Register a URL to receive event deliveries. Signing secret is returned exactly once at creation.
  * Deliveries are POSTs signed with HMAC-SHA256 over the raw body (`X-Webhook-Signature: sha256=<hex>`), with the event type echoed in `X-Webhook-Event`.
  * First event published: `research_request.transcript_added` — fires once per transcript added to one of your projects.
  * Retry policy: up to 3 attempts with exponential backoff (1s / 4s / 16s) on `5xx`, `408`, `429`, and transport errors. `4xx` (other) terminates without retry.
  * See [Webhooks](/api-reference/api-reference/webhooks.md) for the full delivery contract and verification examples.

***

## \[1.4.0] - 2026-05-18

### Changed

* **Research Requests** (`POST /api/v1/operations/research-request`, `GET /api/v1/operations/research-request`) — **breaking**
  * Step 3 renamed from **Topics & Questions** to **Focus Areas**; the intake flow is now **Research Brief → Setup Configuration → Focus Areas**
  * **Removed** request and response fields:
    * From Step 2: `quality`, `call_tone`, `executive_rating`
    * From Step 3: `system_proposed_topics`, `system_proposed_questions`, `user_added_topics`, `user_added_questions`
  * **Added** request and response field:
    * `user_added_focus_areas` *(string array)* — replaces the four removed Step 3 fields

***

## \[1.3.0] - 2026-04-17

### Changed

* **Research Requests** (`POST /api/v1/operations/research-request`, `GET /api/v1/operations/research-request`)
  * Redesigned intake flow from a single flat form to a 3-step structure: **Research Brief → Setup Configuration → Topics & Questions**
  * `POST` now only requires `research_objective`; all other fields are optional
  * Request and response schemas updated to reflect the new field structure (removed `project_title`, `research_questions`, `num_interviews_min/max`, `project_method`, `project_type`, `stop_date`, `deliverables`)
  * Response now includes project lifecycle fields: `current_step`, `status`, `brief_status`, `brief_readiness_level`, `research_id`, `campaign_id`, `ai_led`, `human_led`
  * `estimated_interview_volume` accepts `1-10 | 11-25 | 25+ | bh-advice`
  * `willingness_to_pay` accepts `yes | no | define-with-sales`

***

## \[1.2.1] - 2026-04-15

### Added

* **People** (`GET /api/v1/people`)
  * Search people by `name` or `title` (partial, case-insensitive), or by associated company via `company_id` / `company_name`
  * Each result returns the person's `person_id`, `full_name`, `title` and `bio`, plus every published transcript they appear in with `call_date`, `post_date`, `call_type`, `project_affiliation` and associated companies
  * Paginated via the standard `PaginatedResponse` envelope; `ordering` accepts a field name with an optional `-` prefix
  * See [People](/api-reference/api-reference/people.md)

***

## \[1.2.0] - 2026-04-13

### Added

* **Data Sources** (`GET /api/v1/data-sources`)
  * Returns the list of data source providers accessible to the authenticated client
  * Defaults to Blue Heron provider when no sources are explicitly configured
* **Watchlist** (`POST /api/v1/watchlist`, `GET /api/v1/watchlist`, `GET /api/v1/watchlist/{watchlist_id}`, `PATCH /api/v1/watchlist/{watchlist_id}`)
  * Create watchlists linked to the client's consumption user and firm
  * List all watchlists visible to the authenticated client (own user, own firm, or public)
  * Retrieve a single watchlist by ID with ownership/public-access check
  * Partially update a watchlist — restricted to the owning user or firm

***

## \[1.0.0] - 2024-01-15

### Initial Release

#### Added

* **Health Check** (`GET /api/v1/health`)
  * Returns API status, service name, and timestamp
  * No authentication required
  * Supports monitoring and load balancer health checks
* **Companies** (`GET /api/v1/companies`, `GET /api/v1/companies/{company_id}`)
  * Search and filter companies by name, ticker, exchange, and ID
  * Supports ordering and pagination
* **Interviews** (`GET /api/v1/interviews`, `GET /api/v1/interviews/{transcript_id}`)
  * Retrieve interview transcripts with full metadata
  * Filter by company, date range, call type, and transcript length
  * Aliased at `/api/v1/transcripts` and `/api/v1/transcripts/{transcript_id}`
* **Research Requests** (`POST /api/v1/operations/research-request`, `GET /api/v1/operations/research-request`)
  * Submit new research requests with project specifications and deliverables
  * Retrieve all research requests associated with your account
