Skip to content

docs(api-reference): publish the API deprecation policy - #2832

Merged
aaronmichaelacosta merged 7 commits into
mainfrom
APPEX-956/deprecation-policy
Sep 26, 2026
Merged

aaronmichaelacosta merged 7 commits into
mainfrom
APPEX-956/deprecation-policy

Conversation

@aaronmichaelacosta

Copy link
Copy Markdown
Contributor

What this adds

A Deprecation Policy page for the public API, sitting next to the changelog in both versions:

  • /api-reference/v1/Deprecation-Policy
  • /api-reference/v2/Deprecation-Policy

It answers one customer question: how much warning do I get before a Semgrep API change breaks my integration? Short version — stable endpoints get 6 months' notice for a breaking change, beta gets 30 days, experimental gets none, and undocumented endpoints aren't covered at all. At the deadline the endpoint returns 410 Gone rather than quietly serving wrong data.

The text is the customer-facing half of the policy drafted in APPEX-956. The internal appendix — notice channels, the 410-vs-301 decision record, known gaps — is not published.

One change from the draft

The policy was written before we decided to ship a changelog, so its "how do I find out what's deprecated" list had no way for a customer to be told proactively — only the reference, response headers, and emailing support. It now leads with the changelog and its RSS feed, which records every deprecation on the day it ships.

Notes for review

  • The body lives in a snippet imported by both version pages, so v1 and v2 can't drift apart.
  • Omitted on purpose: the in-app banner and admin email that the draft names as commitments. Neither exists yet, so publishing them would promise channels we can't serve.
  • Still needs Product and Legal/Compliance sign-off per the APPEX-956 checklist — this is a public commitment, so please don't merge on a docs review alone.

Test plan

  • npx mintlify@latest validate passes

Stacked on #2796 — this page links to the changelog pages that PR adds, so it should merge after it.

aaronmichaelacosta commented Sep 3, 2026 •

Copy link
Copy Markdown
Contributor Author

Comment thread docs/api-reference/v1/Deprecation-Policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated

@abhijna abhijna left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi! Thanks for writing this doc. Made some style and voice changes to sync with our technical docs guide. Please lmk if you have any questions

Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
@connorg
connorg requested a review from andy-r2c September 4, 2026 18:28
@connorg

connorg commented Sep 4, 2026 •

Copy link
Copy Markdown
Contributor

@aaronmichaelacosta I've asked @andy-r2c to take a first review from the PM side and asked him to let me know when it's ready for me to give a final look. I want to be sure we're aligned from both the Product and Eng side of things before we publish.

Thank you for writing this up, also!

aaronmichaelacosta added a commit that referenced this pull request Sep 4, 2026
Takes all twelve suggestions from the review on #2832 verbatim: the intro
and summary sentences, the maturity table's header and all three rows, the
undocumented-endpoints paragraph, the security and legal exception (now
two paragraphs), the "Identify deprecated endpoints" heading, and the
four-bullet list in its label-prefixed form.

Two of the twelve needed a judgement call rather than a substitution:

- One was a question -- "Do we add callouts in the API docs? If so, this
  info would benefit from being in a callout box." We do; <Note> appears
  152 times in this repo. The summary paragraph is now a <Note>, using the
  suggested wording.

- The frontmatter description suggestion was left on the v1 page, but v1
  and v2 are deliberate duplicates importing the same snippet, so applying
  it to one only would have made them diverge. Both are updated.

Style and voice only. Nothing here changes what the policy commits to,
including the six-month window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aaronmichaelacosta added a commit that referenced this pull request Sep 4, 2026
Takes all twelve suggestions from the review on #2832: the intro and
summary sentences, the maturity table's header and all three rows, the
undocumented-endpoints paragraph, the security and legal exception (now
two paragraphs), the "Identify deprecated endpoints" heading, and the
four-bullet list in its label-prefixed form.

Two of the twelve needed a judgement call rather than a substitution:

- One was a question -- "Do we add callouts in the API docs? If so, this
  info would benefit from being in a callout box." We do; <Note> appears
  152 times in this repo. The summary paragraph is now a <Note>, using the
  suggested wording.

- The frontmatter description suggestion was left on the v1 page, but v1
  and v2 are deliberate duplicates importing the same snippet, so applying
  it to one only would have made them diverge. Both are updated.

The undocumented-endpoints suggestion carried a double space after its
first period, which is dropped as a typo rather than reproduced.

Style and voice only. Nothing here changes what the policy commits to,
including the six-month window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@aaronmichaelacosta
aaronmichaelacosta force-pushed the APPEX-956/deprecation-policy branch 2 times, most recently from 9400249 to 691f1ba Compare September 8, 2026 17:17
@aaronmichaelacosta
aaronmichaelacosta force-pushed the api-changelog-from-openapi branch from d413c13 to e15c480 Compare September 8, 2026 17:27
@aaronmichaelacosta
aaronmichaelacosta force-pushed the APPEX-956/deprecation-policy branch from 691f1ba to 547a2d0 Compare September 8, 2026 17:27
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated

@connorg connorg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I gave this a closer read after our review meeting.

The overall direction of my comments is the same, and I've tried to clearly note which would be blocking and which wouldn't.

I did become more concerned about the absolute-ness of the exception language and think we'd do better to soften it a touch.

Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx
@aaronmichaelacosta
aaronmichaelacosta force-pushed the APPEX-956/deprecation-policy branch from f13765c to 37ee39b Compare September 21, 2026 17:10
@aaronmichaelacosta
aaronmichaelacosta changed the base branch from api-changelog-from-openapi to graphite-base/2832 September 22, 2026 21:52
aaronmichaelacosta added a commit that referenced this pull request Sep 22, 2026
Takes all twelve suggestions from the review on #2832: the intro and
summary sentences, the maturity table's header and all three rows, the
undocumented-endpoints paragraph, the security and legal exception (now
two paragraphs), the "Identify deprecated endpoints" heading, and the
four-bullet list in its label-prefixed form.

Two of the twelve needed a judgement call rather than a substitution:

- One was a question -- "Do we add callouts in the API docs? If so, this
  info would benefit from being in a callout box." We do; <Note> appears
  152 times in this repo. The summary paragraph is now a <Note>, using the
  suggested wording.

- The frontmatter description suggestion was left on the v1 page, but v1
  and v2 are deliberate duplicates importing the same snippet, so applying
  it to one only would have made them diverge. Both are updated.

The undocumented-endpoints suggestion carried a double space after its
first period, which is dropped as a typo rather than reproduced.

Style and voice only. Nothing here changes what the policy commits to,
including the six-month window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@aaronmichaelacosta
aaronmichaelacosta force-pushed the APPEX-956/deprecation-policy branch from 37ee39b to adb9a7d Compare September 22, 2026 21:52

@connorg connorg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd make the following small changes, then ship. Will elaborate on slack

Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated
Comment thread docs/snippets/api-deprecation-policy.mdx Outdated

@connorg connorg left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Thanks for rolling with the punches, Aaron.

aaronmichaelacosta and others added 3 commits September 25, 2026 20:30
Adds a Deprecation Policy page alongside the changelog in both API
versions, from the customer-facing half of the APPEX-956 policy doc. The
internal appendix (notice channels, the 410-vs-301 decision record, open
gaps) is not published.

The body lives in a snippet imported by both version pages. Terms-of-Use
duplicates its one sentence per version, but 30 lines of policy would
drift, and the repo already shares longer content this way (see
snippets/metrics.mdx).

One content change from the source doc: it was written before we decided
to publish a changelog, so "Finding out what is deprecated today" had no
push channel -- only the reference, response headers, and support. It now
leads with the changelog and its RSS feed, which records every deprecation
tagged Deprecated on the day it ships.

Deliberately not carried over: the in-app banner and admin email named in
the internal appendix. Neither exists yet (appendix gap 4), so publishing
them would commit us to channels we cannot serve. The invented
/api/migrations/<resource> URL (gap 5) appears only in the appendix and is
not published either.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Stable endpoints had two clocks: 6 months for a breaking change, 3 months
for removing an already-deprecated optional field. The short one does not
survive contact with how the clock actually starts.

Per styleguide 13.2 the clock only runs once the notice is public --
`Deprecation` and `Sunset` headers live, spec marked. A field marked
deprecated with no sunset date has therefore started no clock at all, so
the 3 months would be the entire notice a customer gets, not a follow-on
to time already served. That is half the window for something oasdiff
rates `response-optional-property-removed` at WARN, potentially breaking:
"optional" says the server may omit the field, not that nobody reads it.

One window for stable, whatever the change. Simpler to state, simpler to
honour, and it errs long on a public commitment.

Styleguide 13.1 transcribes this table and still carries the 3-month row;
that needs the same edit in semgrep-app. Its link to
api-deprecation-policy.md is also dangling -- that file does not exist in
that repo.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Takes all twelve suggestions from the review on #2832: the intro and
summary sentences, the maturity table's header and all three rows, the
undocumented-endpoints paragraph, the security and legal exception (now
two paragraphs), the "Identify deprecated endpoints" heading, and the
four-bullet list in its label-prefixed form.

Two of the twelve needed a judgement call rather than a substitution:

- One was a question -- "Do we add callouts in the API docs? If so, this
  info would benefit from being in a callout box." We do; <Note> appears
  152 times in this repo. The summary paragraph is now a <Note>, using the
  suggested wording.

- The frontmatter description suggestion was left on the v1 page, but v1
  and v2 are deliberate duplicates importing the same snippet, so applying
  it to one only would have made them diverge. Both are updated.

The undocumented-endpoints suggestion carried a double space after its
first period, which is dropped as a typo rather than reproduced.

Style and voice only. Nothing here changes what the policy commits to,
including the six-month window.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
aaronmichaelacosta and others added 4 commits September 25, 2026 20:30
Doubles the beta notice period from 30 days to 60. 30 days is a short
window for a customer to notice a deprecation, schedule the work, and ship
it -- particularly for teams on a monthly release train, where it can
amount to a single opportunity to react.

Stable stays at 6 months and experimental still promises nothing.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Connor's review, plus two accuracy fixes the 410 write-up turned up.

Reviewer-requested:

- Move the maturity-badge sentence above the table, so the question the
  table raises ("how do I know which one an endpoint is?") is answered
  before it is asked rather than after.
- State stable's window as 180 days. Beta was already in days, so the
  column no longer mixes units, and a month-length assumption cannot
  change what the commitment means.
- Rewrite the stable row, which said only "covered by this policy". Beta
  is covered too, so the cell distinguished nothing.
- Soften the exception. It claimed to be "the only exception" and named
  a legal obligation specifically; both are more absolute than we can
  actually promise. Same care, less cornering.
- Restore what counts as a breaking change, from the APPEX-956 draft.
  Split into what will not change without notice and what may change at
  any time, because the second half is what a caller has to build for --
  tolerate new fields, do not match on error strings.

APPEX-956 wanted that definition to be a link to the oasdiff ruleset in
APPEX-959, so it would be mechanical rather than prose. APPEX-959 is
cancelled, so prose is what is left.

Accuracy, found while writing the sunset section against the
implementation in semgrep-app#31680:

- The `Link` header is the machine-readable pointer, and it is omitted
  when a removal has no replacement. "Returns 410 with a machine-readable
  pointer to its replacement" promised it unconditionally.
- Document the sunset response itself: headers, body, and which parts are
  stable enough to parse. `error` wording is not.

semgrep-app#31680 is still a draft, so this must not publish before it
ships -- the page would describe a response nothing returns yet.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Two claims on this page were ahead of the generator, and both are now true
rather than aspirational.

"Tagged as Deprecated" described a chip in the Change column as though it
were a filter. The filter tag was "Non-breaking", so a reader who followed
this page's advice -- subscribe, watch for what will break you -- was told
to filter for exactly the thing that hid the notice. The generator now files
deprecations as potentially breaking, so say both: what the row is marked,
and which filter it survives.

Also say that the removal itself lands in the changelog. It did not
previously; a removal that served its full notice window produced no entry
at all, which made "the changelog records every deprecation" true and
"the changelog tells you when the endpoint went away" false.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@aaronmichaelacosta
aaronmichaelacosta force-pushed the APPEX-956/deprecation-policy branch from 44b2b08 to 3106672 Compare September 26, 2026 03:31
@aaronmichaelacosta
aaronmichaelacosta changed the base branch from graphite-base/2832 to main September 26, 2026 03:31
@aaronmichaelacosta
aaronmichaelacosta merged commit e0c34b9 into main Sep 26, 2026
8 of 10 checks passed
@aaronmichaelacosta
aaronmichaelacosta deleted the APPEX-956/deprecation-policy branch September 26, 2026 03:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants