Atribu
API Reference

Deprecation policy

What happens before an endpoint changes or goes away, and how you find out

Two companies build products on this API. This page is the commitment we make to them about what a removal looks like — stated so that a change you did not plan for cannot reach you as an outage.

The commitment

An operation we intend to remove is announced at least 90 days before it stops answering. Not 90 days before we decide; 90 days before the last request succeeds.

That window is enforced, not promised. Setting a removal date closer than 90 days after the deprecation notice fails the build — validateRouteSunset in services/api/src/routes/manifest.ts refuses the pair, and a deprecation with no date yet is the supported way to say going away, date to be decided.

Nothing is removed silently. Every deprecation appears in the changelog, in the response headers below, and in the OpenAPI document, all derived from one field on the route. There is no separate list anyone has to remember to update.

How you find out, without asking

A deprecated operation answers exactly as it did before — same status, same body — and adds three standard headers:

Deprecation: @1789689600
Sunset: Wed, 02 Dec 2026 00:00:00 GMT
Link: </api/v1/goals/definitions>; rel="successor-version"
  • Deprecation (draft-ietf-httpapi-deprecation-header) — a unix timestamp, prefixed @, of the moment the notice took effect. Present on every deprecated operation.
  • Sunset (RFC 8594) — an HTTP-date. The operation is expected to stop answering at or after this instant. Absent when no removal date has been decided, which is a real and common state: the warning is live, the clock is not running.
  • Link with rel="successor-version" — where to go instead. Present whenever a replacement exists. Absent when the capability is genuinely going away rather than moving.

Log these three, do not parse the body for them. They arrive on every response from the affected operation, including error responses, so a single client-side check on any call catches the notice — you do not have to be watching this page.

The same three facts are in the published spec: a deprecated operation carries deprecated: true and an x-atribu-sunset extension in openapi.json, so a codegen tool sees the notice without a live request.

What counts as a breaking change

These get the 90-day notice and a Breaking entry in the changelog:

  • removing an operation, or a field from a response;
  • narrowing what an existing parameter accepts;
  • changing the TYPE of a response field, including a field that gains null — a value that was always a number and is now sometimes null breaks arithmetic that never had a guard;
  • changing the meaning of a value without changing its name;
  • adding a required parameter to an existing operation;
  • requiring a scope an existing credential does not hold.

These do not, and can ship any day:

  • adding an operation;
  • adding an optional parameter;
  • adding a field to a response — write your client to ignore fields it does not know; we add them regularly;
  • adding a value to an enumerated field whose documented meaning is "one of at least these" — check your parser's default branch;
  • performance, wording of a message, or anything behind a flag that is off for you.

A security fix is the one exception, and it is a real one. Closing a hole that lets a credential reach data it was never granted takes effect when the fix ships. #1152 and #1154 are both worked examples: an mcp:read token that could create workspaces stopped being able to, and a webhook target pointing at a private address stopped being delivered to, on the day each fix landed. Both are in the changelog marked Breaking, with what to change.

What we ask of you

  • Ignore unknown response fields. A strict parser turns every additive change into an outage on your side.
  • Do not depend on key order, on the exact wording of message, or on a request_id format. Branch on error.code; it is the stable half of the envelope.
  • Read X-RateLimit-Remaining and X-RateLimit-Reset rather than discovering your ceiling as a 429.
  • Keep one contact address current with us. A deprecation that only exists in a header nobody logs is a notice in name only, and we would rather email you.

When something is already broken

If an endpoint you rely on is failing right now, that is an incident, not a deprecation: see the incident runbook for what we do, including the kill-switch we hold and when we use it. The SLO states what "working" means in numbers.

On this page