Guide

API Changelog: Best Practices to Ship Changes Without Breaking Integrations

How to run an API changelog your integrators actually trust — versioning, deprecation headers, Stripe and Twilio patterns, and what to put in the feed.

Photo of ReleaseGlow TeamReleaseGlow Team
April 23, 2026
12 min read

A product changelog tells users what changed. An API changelog tells integrators whether their production is about to break. Same word, completely different document.

If your API has more than a handful of customers, the changelog isn't marketing copy — it's a contract. Every line of it is read by someone with a deploy-on-call rotation, and the cost of getting it wrong is a Sev-2 at 3 a.m. on the other side of the world. This guide is the operating manual: what to put in, how to version it, how to signal breaking changes without paging your entire customer base, and how the Stripes and Twilios of the world do it.

Ship an API changelog your integrators trust

ReleaseGlow generates API-specific feeds, deprecation notices, and webhooks for downstream consumers — from one source of truth.

TL;DR

  • An API changelog is a contract, not a release note. Treat breaking changes as incidents-in-waiting.
  • Three change classes only: breaking, additive, fix. If a change doesn't fit, you're underspecifying.
  • Ship deprecation via headers (RFC 8594 Deprecation and Sunset), not just a blog post.
  • Include dated entries, affected endpoints, request/response diffs, and migration paths — every time.
  • Give integrators a machine-readable channel (RSS, webhook, OpenAPI diff) on top of the human-readable page.

Product changelog vs API changelog

They share a name and almost nothing else.

| | Product changelog | API changelog | |---|---|---| | Reader | End users, champions, prospects | Developers integrating your API | | Purpose | Announce value, drive activation | Prevent integration breakage | | Tone | Benefit-led, friendly | Precise, technical, predictable | | Cadence | Weekly or bi-weekly, marketing-aligned | Per-change, shipped with the change | | Failure mode | Low engagement | Production outage on a customer's stack | | Must include | Benefit, screenshot, CTA | Endpoints affected, request/response diff, migration path, deprecation date |

The confusion is expensive. Teams who run both off the same template end up with product changelogs that bore developers and API changelogs that hide breaking changes behind "we've made some improvements." Separate the two from day one.

The three change classes

Every API change fits into exactly three buckets. Labeling is not decoration — it's the primary signal integrators scan for.

Breaking

Anything that can return 500 on code that used to return 200. Removing a field, renaming an endpoint, tightening validation, changing response shape, changing auth requirements, reducing rate limits. Also: changes that the spec allows but that a reasonable integrator didn't expect — enum value additions to strict consumers, default value changes, error code renames.

Breaking changes require advance notice, a migration path, and ideally a transition window where both the old and new behavior work in parallel.

Additive

New endpoints, new optional fields, new enum values that don't narrow existing responses, higher rate limits, new webhooks. The rule: existing code keeps working without any modification. Additive changes ship immediately and get a single-line entry in the changelog.

Fix

Bug fixes that align behavior with the documented spec. A field that was documented as required but was optional in practice. A rate-limit header that returned the wrong unit. Be careful: if customers have built around the bug, fixing it is technically a breaking change. Treat it as such when in doubt.

The silent-breaking trap

A "fix" that customers have built around is a breaking change. Before shipping, run a quick query on logs: is anyone relying on the buggy behavior? If yes, announce the fix as breaking, give 30+ days notice, and keep the old behavior toggleable via a header or version parameter during the migration window.

What to put in every entry

An API changelog entry has six fields. Skip any of them and you've underspecified the change.

  1. Date — ISO 8601, UTC. Not "last Tuesday", not "April 2026".
  2. Change classBREAKING, ADDITIVE, or FIX. Uppercase. Unambiguous.
  3. Affected endpoints or resources — list them explicitly. POST /v2/charges, GET /v2/customers/{id}. Not "the charges API".
  4. What changed — the request or response diff. Show the before and after.
  5. Why — one sentence. Context reduces confusion and support load.
  6. Migration path (breaking only) — the exact steps to update. Preferably copy-pasteable code.

A good entry:

## 2026-04-18 · BREAKING · POST /v2/payments

**What changed:** The `amount` field now rejects values below 50 (previously 1).
Requests with `amount < 50` will return `400 invalid_amount`.

**Why:** Sub-50-cent charges were failing downstream at the processor 87% of the
time. Moving validation to our API improves error clarity.

**Migration:** If you create charges below 50 cents, aggregate them before
calling the API. Example in Node:

    const cents = items.reduce((s, i) => s + i.cents, 0);
    if (cents < 50) throw new Error('Below minimum');
    await stripe.charges.create({ amount: cents, ... });

**Sunset date for old behavior:** 2026-07-18 (90 days from this entry).

That entry tells a developer on a Monday morning exactly what to do before Friday's sprint. An entry that says "improved validation on the charges endpoint" tells them nothing and will generate three support tickets.

How Stripe, Twilio, GitHub, and OpenAI do it

The leaders all solve the same problem with slightly different trade-offs. Studying them is the fastest way to calibrate your own approach.

Stripe — versioned API, dated releases

Every API version is a date (2024-06-20, 2025-01-27). Account owners pin a version; breaking changes only apply when they upgrade. The changelog lists each version with a bulleted breakdown of what's different. This is the gold standard if your API has heterogeneous enterprise usage — some customers freeze for years, others track latest.

Cost: you maintain multiple versions in parallel. Significant engineering overhead, justified only if your customers actually use the pinning.

Twilio — per-product changelogs, deprecation headers

Twilio segments changelogs by product (Voice, Messaging, Video). Each has its own feed and RSS. Breaking changes ship with X-Twilio-Deprecation response headers starting 6 months before sunset. The headers are machine-readable, so integrators can alert on them in monitoring.

Cost: you need discipline to keep product boundaries clean. Good fit if your API has clearly separable surface areas.

GitHub REST API — header-driven migration

GitHub uses the X-GitHub-Media-Type and Accept headers for opting into preview versions of the API. Breaking changes are announced on the blog and in the OpenAPI spec, with a clear timeline. The Deprecation response header lights up before sunset.

Cost: relies on developers reading headers. Works because GitHub's audience is developer-first.

OpenAI — dated model versions plus an API changelog

OpenAI's API changes get dated entries in their changelog. Model versions (gpt-4o-2024-08-06) carry semantics: pinning to a specific date means your code won't shift underneath you. This is effectively Stripe's pattern applied to AI model behavior.

Cost: high. The pinning infrastructure and the commitment to keep old versions live is expensive.

Versioning strategies

Pick one, write it down in your API docs, and stick to it.

URI versioning (/v1, /v2)

Simple, visible, easy to route. Every major version is a new tree. Downside: bumping to /v2 because of a single breaking field change is heavy. Good default for most SaaS APIs.

Header versioning (API-Version: 2026-04-23)

Fine-grained, invisible in the URL. Requires discipline on the client side to set the header. Matches Stripe's pattern.

Query parameter versioning (?version=2)

Rare in production. Tends to break caching. Avoid.

Whatever you pick, your changelog must say clearly which versions each entry applies to. "Affects v2 only" or "Affects all versions" — not "affects the API".

Keep your API changelog in one place

Generate dated entries, tag them by version, and syndicate to RSS, webhooks, and your docs widget — automatically from your pipeline.

Deprecation the right way

Deprecation isn't a blog post. It's a three-channel protocol: the changelog entry, the response headers, and a programmatic notification to account owners.

The Deprecation and Sunset response headers

RFC 8594 defines the Sunset HTTP response header. RFC 9745 adds Deprecation. Together they let you ship machine-readable deprecation notices every time a deprecated endpoint is hit:

HTTP/1.1 200 OK
Deprecation: Wed, 23 Apr 2026 00:00:00 GMT
Sunset: Thu, 23 Jul 2026 00:00:00 GMT
Link: <https://api.acme.com/changelog/2026-04-23>; rel="deprecation"

An integrator who's monitoring response headers will catch the deprecation before their deploy breaks. A team that isn't will hit the sunset date and get a 410 Gone. Either way, you've fulfilled your obligation.

Who to notify programmatically

For breaking changes on APIs with production customers, the changelog is the floor. On top of it, ship:

  • An email to every technical contact on every account using the affected endpoints in the last 30 days.
  • A webhook event to every integrator's configured webhook URL with the deprecation metadata.
  • A banner in the developer dashboard for logged-in users whose traffic touches the endpoint.

Sales-led SaaS companies underestimate how many of their customers will never open an email. Header + webhook is what gets through.

Formats: OpenAPI diff, RSS, and the human-readable page

Three surfaces for the same information.

The human-readable changelog page

A URL like /api/changelog rendered server-side, indexable by Google, skimmable by a developer landing from a Slack link. Reverse-chronological, filterable by version, searchable. This is what gets linked in support tickets.

The RSS/Atom feed

See our guide on changelog RSS feeds for the full setup. For APIs, the feed carries the same six fields per entry. Developers subscribe in Feedly or pipe into Slack via the built-in RSS integration.

The OpenAPI diff

If you publish an OpenAPI spec (you should), every change to the spec is a structured diff. Tools like oasdiff compute the diff automatically and emit a machine-readable report. Publish that diff alongside each release — integrators' CI pipelines can consume it to fail their own builds if a dependency has a breaking change.

The holy trinity is: human page for humans, RSS for feed consumers, OpenAPI diff for CI. All three generated from the same source of truth. None of them created by hand.

Common pitfalls

Bundling breaking changes into "improvements"

Marketing-flavored copy in an API changelog ("we've improved the validation layer!") hides breaking changes from the scanning-for-BREAKING readers. If it can break code, the word BREAKING goes in the entry title. No exceptions.

Changing the meaning of existing enum values

status: "processing" used to mean queued, now means in-flight. Even if the field name didn't change, every integrator who has a switch statement on status just got silently broken. Treat enum semantic changes as breaking.

Shipping the changelog after the change is live

The changelog entry must go out with the release, not 24 hours later. Tooling should couple the two: the same deploy that changes API behavior publishes the entry.

Not dating the sunset

"We'll deprecate this endpoint soon" is not a plan. Every deprecation needs a date, and the date needs to be in the future by enough to let integrators reasonably migrate (30 days for trivial changes, 90 for material ones, 180+ for schema-level breaks).

Embed the changelog in your docs

The highest-performing API changelogs are embedded directly in the developer docs. A persistent sidebar widget showing the last 5 entries, filterable by version, one click to the full changelog page. Developers read docs; they don't visit your marketing site. Put the changelog where the reading already happens.

FAQ

Wrap-up

An API changelog is a log, not a blog. Reverse-chronological, machine-readable, classification-heavy, unambiguous about what broke and what to do about it. Build it like you'd build the API itself: contracted, versioned, tested, and automated end-to-end. Integrators who trust your changelog will forgive the occasional breaking change. Integrators who don't will churn the moment a better-documented alternative shows up.

Dates. Classes. Diffs. Migration paths. Deprecation headers. Repeat every time. That's the whole discipline.