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

# Breaking changes

> A log of breaking API contract changes. Integrators should subscribe to this page.

This page records breaking changes to the Membership.io API contract. Non-breaking additions (new endpoints, new optional fields, new SSE event types) are not listed here — consult the [endpoint inventory](/reference/endpoint-inventory) and the [generated API reference](/openapi/mio-openapi.json) for additions.

***

## 2026-08-06 — Replying to a reply is rejected (MIO-2963)

`POST /api/v1/comments` now enforces two-level comment threading. A request whose `parent_comment_id` points at a comment that is itself a reply previously succeeded with `201`; it now fails with `422` and code `nested_reply_not_allowed`.

**What changed:**

* `parent_comment_id` must reference a **root** comment (one with no parent of its own). Referencing a reply returns `422` / `nested_reply_not_allowed`.
* `comment_count` on discussions and content nodes is recomputed on deploy to exclude replies nested deeper than one level, which previously inflated it. A discussion's `comment_count` may drop with no content deleted.
* Deleting a root comment now decrements `comment_count` by that comment plus its replies that had not already been deleted, rather than by 1.

**How to migrate:**

Thread replies against the root comment's id — when a user replies to a reply, send that reply's own `parent_comment_id` (its root), not the reply's id. Treat `422` / `nested_reply_not_allowed` as a client-side threading bug rather than surfacing it to the user. Do not treat a one-time `comment_count` decrease as content loss.

***

## 2026-06-18 — `GET /api/users` is now team-scoped (MIO-1253)

`GET /api/users` now requires team context. Without it the endpoint returns `400` with code `team_context_required`.

**What changed:**

* Requests must supply an `X-Team-ID` header **or** use a JWT that carries a `team_id` claim.
* Requests made with a plain API key (no team claim) are rejected with `403` — use a contact-scoped or team-scoped JWT instead.
* Responses are filtered to the team identified by the header/claim; contacts belonging to other teams are not returned.

**How to migrate:**

Add `X-Team-ID: <your-team-id>` to all `GET /api/users` requests, or switch to a JWT that includes a `team_id` claim.

See [Tenancy](/concepts/tenancy) for how team context flows through the API.

***

## 2026-06-18 — JSON:API `type` renames (MIO-1257)

Two resource `type` values were renamed to the snake\_case + plural contract that governs the entire API surface:

| Endpoint                                   | Old `type` value  | New `type` value             |
| ------------------------------------------ | ----------------- | ---------------------------- |
| `POST /activity` response                  | `activity_event`  | `activity_events`            |
| `GET /discussions/{id}/reactions` response | `reaction_groups` | `discussion_reaction_groups` |

**How to migrate:**

Update any client-side deserialization that matches on the literal `type` string. The data shape (attributes, relationships) is unchanged — only the `type` value differs.

**No deprecation window:** this was a clean alpha cut-over. **No `Sunset` or `Deprecation` headers were emitted** — the old `type` values stopped being served at deploy time. If your integration broke on 2026-06-18, update the `type` strings above and redeploy.
