Sunset an integration gracefully by treating deprecation as a product launch in reverse: announce a versioned timeline early, run the old and new paths in parallel, and target outreach by actual usage instead of a blanket email. The mechanics are additive changes, Sunset and Deprecation headers, a dual-run window, and cohort-based nudges tied to real API calls.
Quick Answer: Don't kill an integration cold — version it, signal it in headers, run old and new in parallel for a defined window, and message usage-based cohorts on a fixed cadence with a migration guide in hand before you ever announce a date.
Every platform PM eventually inherits a connector nobody wants to own, a webhook payload shape that's aged badly, or an API version three majors behind. Killing it feels like housekeeping. To the developers depending on it, it's an outage with a countdown clock. The difference between a deprecation that builds trust and one that torches it is almost never the decision to sunset — it's the discipline of how.
Why Integration Sunsets Are Where Ecosystems Actually Lose Trust
Integration deprecations damage trust faster than almost any other PM decision because they break code a partner already shipped to their own customers, often with no warning built into their release cycle. A pricing change is negotiable; a silent breaking change is a production incident someone else has to explain to their boss.
Unlike a UI redesign, an integration lives inside someone else's system, frequently written by a developer who left the company two years ago. When you change a response shape or retire an endpoint, you're not asking your own team to adapt — you're asking a stranger's unmaintained cron job to survive. That's why deprecation is the least glamorous, highest-trust-risk work in the integrations and platform PM role, a theme covered more broadly in the complete guide to the integrations PM role.
The Trust Ledger Is Asymmetric
A smooth migration earns you almost nothing — developers expect APIs to evolve and rarely praise you for handling it well. A broken one, though, gets remembered specifically and shared publicly, in support tickets, Slack communities, and Hacker News threads about "vendor X breaking things without warning."
- Silent failures compound: a webhook that stops firing doesn't throw an error; it just goes quiet until someone notices missing data days later.
- Blast radius is invisible to you: you can see who called an endpoint last week, not who built a business process on top of it that only runs quarterly.
- Recovery cost is one-sided: your team spends an afternoon shipping the new version; a partner may spend a sprint re-testing an integration that "just worked" for three years.
That asymmetry is exactly why a formal API versioning strategy — not ad hoc patching — has to exist before you ever touch a breaking change.
Build an API Versioning Strategy That Makes Breaking Changes Rare
A sound versioning strategy minimizes the number of times you ever need a hard sunset by defaulting to additive, backward-compatible changes and reserving version bumps for genuinely incompatible shifts. Most "breaking changes" are actually avoidable if the schema and endpoint design leave room to grow.
The core discipline, borrowed from Postel's Law ("be liberal in what you accept, conservative in what you send") and formalized in specs like Stripe's and Google's API design guides, is to treat additive changes as always-safe and structural changes as always-versioned.
What Counts as Additive vs. Breaking
| Change type | Example | Safe without a version bump? |
|---|---|---|
| New optional field | Adding customer_segment to a response | Yes |
| New endpoint | Adding GET /v2/invoices/summary | Yes |
| New enum value | Adding status: "on_hold" | Usually, if consumers ignore unknown values |
| Renaming a field | full_name → display_name | No |
| Removing a field | Dropping legacy_id | No |
| Changing a field's type | amount from string to integer | No |
| Changing auth model | API key to OAuth2 | No |
| Changing default behavior | Pagination default from 100 to 20 | No |
The pattern: additive changes let existing clients ignore what they don't recognize; anything that changes the meaning or shape of what already exists forces a version. Contract-first design — deciding the shape of a response before you build the endpoint — catches most of these problems before a single external developer touches them.
Choosing a Versioning Scheme
- URI versioning (
/v1/,/v2/) — most explicit, easiest for partners to reason about, but multiplies routes to maintain. - Header versioning (
Accept-Version: 2026-01-01) — cleaner URLs, date-based versions (Stripe's approach) make it obvious how stale a client is. - Field-level versioning — rare, reserved for GraphQL-style schemas where deprecating a single field is possible without versioning the whole API.
For most platform teams, date-based header versioning combined with a small number of major URI versions gives partners both precision and simplicity. Whatever you choose, document it once in a public reference and never deviate — inconsistency is its own trust cost, separate from the deprecation itself.
Use Sunset Headers and Dual-Run Periods to Make Deprecation Machine-Readable
Sunset headers and a dual-run period turn a deprecation from a one-time email into a persistent, programmatic signal that developers' own tooling can detect automatically. This matters because emails get missed; response headers don't.
RFC 8594 defines the Sunset HTTP header specifically for this: a server returns a date after which a resource will stop being available, and well-behaved clients or monitoring tools can flag it automatically. Pair it with a Deprecation header (a draft IETF IANA spec many major platforms have already converged on) that fires the moment deprecation begins, well before the sunset date arrives.
The Header Pattern in Practice
Deprecation: true
Sunset: Sat, 31 Oct 2026 23:59:59 GMT
Link: <https://developer.example.com/migrate/v1-to-v2>; rel="deprecation"
Deprecationfires on every call to the old version starting the day you announce it — visible in logs immediately, not just in an inbox.Sunsetgives an exact, parseable shutdown date so automated dependency scanners (and increasingly, CI pipelines that check headers) can raise their own internal alerts.Linkwithrel="deprecation"points straight at your migration guide, so the signal and the fix sit next to each other.
Why the Dual-Run Period Is Non-Negotiable
A dual-run period — running old and new versions simultaneously for a defined window — is what actually makes the header credible. Announcing a sunset date without keeping the old version alive long enough to test against is functionally the same as no warning at all; nobody can validate a migration against an endpoint that's already gone.
Dual-run windows should scale with integration complexity and usage depth, not be a fixed 30 days for everyone:
| Integration type | Typical dual-run window | Why |
|---|---|---|
| Low-usage webhook, few partners | 30-60 days | Small blast radius, fast individual outreach |
| Core REST API, broad partner base | 90-180 days | Matches most partners' sprint-planning cycles |
| Embedded/OEM integration | 6-12 months | Partner's own customers need re-certification |
| Marketplace connector (app store listed) | Aligned to marketplace review cycle | Listing review adds its own lead time, a dynamic explored in why an app marketplace is an ecosystem, not just connectors |
Shorter windows are tempting because they reduce your maintenance burden faster, but they directly trade off against the maintenance debt you're trying to shed — a tension worth weighing against how to budget for integration maintenance debt before committing to a date.
Design a Deprecation Communication Cadence, Not a One-Time Announcement
A deprecation communication cadence works by treating the sunset date as the last touchpoint in a sequence, not the first — repeated, usage-targeted nudges at fixed intervals consistently outperform a single blanket announcement at catching partners before they're surprised.
Nielsen Norman Group's research on the "picture superiority" and repetition effects in interface communication applies directly here: a single email, even a well-written one, gets buried. Multiple touches across different channels and time horizons are what actually reach the developer who owns the integration, not just the account manager who forwards it.
The Cadence Skeleton
- T-minus 6 months (or dual-run start): Announcement. Public changelog entry, developer portal banner, and direct email to every credentialed integrator — not just active users.
- T-minus 3 months: Migration guide ships. A concrete, tested guide with request/response diffs, code samples in the top 2-3 languages your integrators use, and a clearly labeled "what breaks" section.
- T-minus 60/30/14/7 days: Usage-based nudges. Automated emails or in-dashboard alerts sent only to accounts still calling the deprecated version — see cohorting below.
- Sunset date: Final cutover. Old version returns
410 Gonewith a link to the migration guide in the response body itself, not just a bare error. - Post-sunset: Retro. Track how many accounts migrated cleanly vs. needed manual outreach — this becomes the baseline for calibrating the next deprecation's timeline.
Usage-Based Cohort Outreach
Segmenting outreach by actual API call volume and recency avoids the two failure modes of blanket communication: alarming inactive accounts unnecessarily, and under-communicating to your highest-risk active integrators.
- Cohort A — High volume, active this week: white-glove outreach, ideally a named contact, offer of a migration call.
- Cohort B — Moderate volume, active this month: targeted email with account-specific usage data ("you called
/v1/invoices4,200 times last week"). - Cohort C — Low volume, dormant 90+ days: standard automated nudge; flag internally as a candidate for a shorter deprecation window since blast radius is small.
- Cohort D — Zero calls in the lookback window: skip outreach, but keep them in the audit trail in case of reactivation.
This cohorting only works if your usage instrumentation is already good enough to answer "who calls this, how often, and how recently" on demand — a capability worth building well before your first deprecation, not scrambling for during one.
Build a Deprecation Runbook You Can Reuse Every Time
A reusable deprecation runbook works by converting the cadence and versioning rules above into a checklist with owners and dates, so each new deprecation is an execution exercise, not a fresh design project debated from scratch. Treat the first one you write as a template, not a one-off.
Core Runbook Components
| Component | Purpose | Owner |
|---|---|---|
| Timeline document | Dates for announcement, guide ship, nudges, cutover | Integrations PM |
| Migration guide | Diff of old vs. new contract, code samples, edge cases | PM + eng lead |
| Cohort list | Usage-segmented accounts with contact info | Data/analytics |
| Header implementation | Sunset/Deprecation/Link on every deprecated response | Platform eng |
| Support playbook | FAQ and escalation path for support teams fielding questions | Support lead |
| Rollback criteria | Conditions under which the sunset date slips | PM + eng lead |
Writing the Migration Guide
The migration guide is the artifact partners actually use, so it needs to answer three questions immediately: what changed, why, and exactly how to update a call. Structure it as a side-by-side diff — old request/response next to new — rather than prose describing the change abstractly.
Include a rollback or grace-period clause: if your usage data shows a meaningful cohort still hasn't migrated as the sunset date approaches, have a pre-agreed criterion (e.g., more than 15% of active accounts still on the old version at T-minus 14 days) for extending the window rather than improvising under pressure. Deciding that threshold before the countdown starts protects you from an ad hoc, trust-eroding scramble later.
This is also where drafting the new contract's shape earlier pays off directly: when you spec the new version's endpoints, request bodies, and error cases before finalizing the timeline, the migration diff and every "what breaks" bullet in the guide are already explicit rather than reconstructed after the fact under deadline pressure. Prodinja's API Designing tool is built for exactly this — sketching the new version's contract as endpoints and sample curl requests alongside the old one, so the surface area of the breaking change is visible before you commit to announcing a date.
Timeline Reference Table
| Milestone | Lead time before sunset | Primary channel |
|---|---|---|
| Public announcement | 6 months | Changelog, portal banner, email |
| Migration guide published | 3 months | Developer portal |
| First usage-based nudge | 60 days | Email, cohort-segmented |
| Escalation nudge | 14 days | Email + dashboard alert |
| Final cutover | 0 (sunset date) | 410 Gone response, changelog |
Anchor every deprecation in the customer's actual workflow, not just your API surface — the same discipline behind mapping a customer journey applies to a developer's integration lifecycle: know which step in their process breaks first when your endpoint changes.
Avoid the Failure Modes That Turn a Sunset Into a Trust Incident
Most deprecation failures trace back to one of three patterns: no dual-run period, no usage-based targeting, or a sunset date treated as fixed regardless of actual migration progress. Each is preventable with the mechanics above, but only if applied before the announcement goes out, not after complaints start.
- Skipping the dual-run window to save engineering effort turns every partner's migration into a fire drill instead of a scheduled task.
- Blanket-emailing every registered developer, active or not, trains partners to ignore your deprecation emails as noise — the opposite of what you want the one time it truly matters.
- Treating the sunset date as immovable even when your own usage data shows a large cohort still dependent on the old version converts a communication plan into a broken promise.
- Shipping the migration guide late, after the announcement rather than well before the nudges begin, gives partners a deadline with no path to hit it.
- Underestimating embedded and OEM integrations, where your partner's own customers need to re-certify, is the single most common cause of a sunset date slipping under pressure.
Getting this right consistently is also a signal to the rest of your ecosystem — partners evaluating whether to build deeper on your platform are watching how you handled the last deprecation, a dynamic worth weighing against the same trust calculus covered in building an integrations strategy across a stack of 50+ tools. Reliable sunsets are, in effect, a distribution advantage.
Key Takeaways
- Default to additive changes (new fields, new endpoints) and reserve version bumps for genuinely incompatible shifts in shape or meaning.
- Use
SunsetandDeprecationHTTP headers (per RFC 8594 and the IETF deprecation draft) so the signal is machine-readable, not just an email that gets missed. - Run a dual-run period scaled to integration complexity — 30-60 days for low-usage webhooks, 6-12 months for embedded/OEM integrations.
- Segment outreach by actual usage cohort, not a blanket announcement, so high-volume active accounts get white-glove attention and dormant accounts don't get spammed.
- Ship the migration guide before the nudges begin, structured as a request/response diff with real code samples, not prose.
- Build a reusable runbook with owners, dates, and a pre-agreed rollback threshold so each deprecation is execution, not a fresh design debate.
- Spec the new contract alongside the old one early so the migration diff is explicit before you commit to a public timeline.
Frequently Asked Questions
How much notice should you give before deprecating an API integration?
Give a minimum of 3-6 months for a standard REST API and up to 12 months for embedded or OEM integrations where a partner's own customers need to re-certify. Scale the window to actual usage depth and integration complexity, not a single fixed policy number.
What's the difference between the Deprecation and Sunset HTTP headers?
Deprecation signals that a resource is deprecated starting now, appearing on every call from the announcement date forward, while Sunset (RFC 8594) specifies the exact future date the resource stops being available. Together they let automated tooling detect both "this is going away" and "here's exactly when," without relying on a human reading an email.
How do you handle partners who miss the deprecation deadline?
Use usage-based cohort data to identify who's still calling the deprecated version as the sunset date approaches, and apply a pre-agreed rollback threshold (e.g., more than 15% of active accounts still unmigrated) to decide whether to extend the window. Deciding that threshold before the countdown starts, rather than improvising under pressure, is what keeps a slip from feeling arbitrary.
Is API versioning by URI or by header better for integration sunsets?
URI versioning (/v1/, /v2/) is more explicit and easier for partners to reason about at a glance, while header versioning (like Stripe's date-based scheme) keeps URLs stable and makes staleness obvious. Most platform teams do well combining a small number of major URI versions with header-based dating within each.
What should a deprecation runbook include at minimum?
At minimum, a runbook needs a dated timeline, a migration guide with a request/response diff, a usage-segmented cohort list, header implementation (Sunset/Deprecation/Link), a support team playbook, and a pre-agreed rollback criterion. Treating the first runbook as a reusable template — not a one-off document — is what makes every subsequent deprecation faster and less error-prone.