# Changelog

Changes to the REST API and the MCP server. Version 1 only grows: new operations, parameters and fields are added; nothing is removed or renamed without a new version and a notice here first.

The version is in the OpenAPI document (`info.version`) and in the MCP server's `serverInfo`.

## 2026-10-21 — monthly quota, the Max plan

The API now has two counters per account, shared by every key, REST and MCP together: the one-minute window it already had and a calendar-month quota. Both come from the plan.

### Added with the monthly quota

- **Monthly quota** by plan: 10,000 requests a month on Pro, 50,000 on Max (UTC calendar month; a contract may have no monthly limit). A refused request counts against neither counter.
- **`X-Quota-Limit`, `X-Quota-Remaining`, `X-Quota-Reset`** on every authenticated response, next to the `X-RateLimit-*` headers of the minute window.
- **`quota_exceeded`** as `error.code` on a `429` whose `error.type` is `rate_limit`, with `Retry-After` set to the 1st of next month; the minute window keeps `rate_limit_exceeded`. MCP tool errors name the counter that refused.
- **EarlyWave Max**: 300 requests a minute and 50,000 a month; Pro stays at 60 a minute and now 10,000 a month. Settings › API & MCP shows the month's count and reset date.

### Changed with the monthly quota

- The rate limit is set by the plan (60 a minute on Pro, 300 on Max) rather than one default for every account.

## 2026-10-19 — v1.1.0

The contract is now declared once and published as OpenAPI 3.1 at [`https://api.earlywave.ai/api/v1/openapi.json`](https://api.earlywave.ai/api/v1/openapi.json). REST and MCP serve the same operations.

### Added

- **18 operations**, each a REST `GET` and an MCP tool of the same name as its `x-mcp-tool`.
- **Trend filters** on `GET /trends` (`list_trends`): `country` (the story is about it), `publisher_country`, `category`, `stage`, `reach`, `since_hours`, `query`, and `sort` (`signal`, `recent`, `sources`).
- **`GET /trends/{trend_id}/articles`** (`get_trend_articles`): every article of a trend with its source and country, newest or oldest first.
- **`GET /trends/{trend_id}/coverage`** (`get_trend_coverage`): publisher countries and languages, and the last 7 days hour by hour.
- New trend fields: `url` (the trend page), `reach`, `subject_countries`, `publisher_countries`; on one trend, `publisher_languages`.
- **Named keys with scopes**: several keys per account, each with a name and the scopes `rest` and/or `mcp`, created and revoked in Settings › API & MCP. Keys are stored hashed and shown once (`ew_live_…`).
- `X-Request-Id` on every response; `X-RateLimit-Limit`, `X-RateLimit-Remaining`, `X-RateLimit-Reset` on every authenticated one; `Retry-After` on `429`.

### Changed

- **Errors** are now `{"error": {"type", "code", "message"}}` with a stable `type` and the matching HTTP status. Invalid parameters answer `400` with every problem in `details`.
- **Paging is the same on every list**: `limit` from 1 to 100 (it was capped at 20), default 20, `offset`, and `has_more` in the answer.
- **Trends are the whole catalogue**: `list_trends` no longer depends on the account's feeds, and its `total` is the number of matching trends.
- **MCP**: the server is named `earlywave` and is stateless — each `POST /mcp` stands alone, so there is no session to keep. `GET` and `DELETE` answer `405`. Tools now receive their arguments and advertise them in their input schema.
- The rate limit (60 requests per minute per account by default) is counted once across REST and MCP and across all servers.

### Compatibility

- Keys created before this release (`sk-smrz_…`) keep working, with the scope of the surface they were made for.
- Every tool name of the previous MCP server is still there.
- If you parsed `error` as a string, read `error.message` instead.
- In `get_trend`, each of `sources` now has `url` (it was `canonical_url`).

---
Source: https://www.earlywave.ai/developers/docs/changelog · All docs: https://www.earlywave.ai/llms.txt
