# Versioning and deprecation

How the Signal API changes over time, and the commitments that let you build against it without watching for surprises. The short version: additive changes never break you, breaking changes get a new version, and anything we retire is announced long in advance.

## Additive by default

Most changes are additive and ship on the current version with no version bump and no action from you:

- a new optional request field
- a new field on a response object
- a new stream template
- A new `response_action` value in the cue vocabulary
- a new error code on an existing status

Build tolerant and these are free: ignore response fields you do not recognize, and do not hard-code a closed list of templates, actions, or error codes. The [cue response](https://uphealth.us/docs/concepts-response) is documented as a minimum shape, not a maximum.

## Breaking changes

A change that could break a tolerant integration — removing or renaming a field, changing a type, tightening validation, or altering the meaning of an existing value — ships under a **new version** (a new path prefix), never silently on the current one. The version you integrated against keeps behaving the way it did the day you shipped.

## Deprecation and Sunset

When a version or a documented field is on a path to retirement, two things happen well before it goes away:

- Responses carry a `Sunset` response header (RFC 8594) with the date the behavior is scheduled to change, so a deprecation is detectable in code, not just in a blog post.
- We give **six to twelve months** of notice and email the contact on every affected key before anything is removed.

Nothing in v1 is deprecated today. This is the commitment for when something eventually is.

## Forward-compatible by design

The cue vocabulary is the live proof of the additive policy. The set of `response_action` values grows over time, and the API is deliberately tolerant of that growth: a well-formed but unrecognized value is **accepted** (a `200` ), folded to the `acknowledge` class for scoring, and echoed back to you as `normalized_action` so you can see what happened. Only a malformed value returns `422 invalid_feedback` . So when you read a `response_action` you do not recognize, treat it as `acknowledge` — a low-signal acknowledgement — and your integration keeps working as the vocabulary widens. The full rule is in [Cues & feedback](https://uphealth.us/docs/concepts-cues).

## Changelog and status

Every shipped change is recorded in the [changelog](https://uphealth.us/signal/changelog) — the API, template, and webhook version logs in one place. Current operational status across every surface is on the [status page](https://uphealth.us/status).

- [What changed](https://uphealth.us/signal/changelog) — The API, template, and webhook version logs — every shipped change in one place.
- [Live status](https://uphealth.us/status) — Operational status across Signal, Reach, Compass, and the member surface.
- [Cues & feedback](https://uphealth.us/docs/concepts-cues) — The response_action vocabulary and the forward-compatible tolerance in full.

---

_Uphealth Signal developer docs · [View on uphealth.us](https://uphealth.us/docs/versioning) · OpenAPI spec: https://uphealth.us/openapi/signal-v1.yaml · Verified against API v1 on 2026-07-22._
