Kueri.me All articles
Opinion & Retrospectives

Dead Integrations Walking: How to Audit the API Debt Nobody Wants to Talk About

Kueri.me
Dead Integrations Walking: How to Audit the API Debt Nobody Wants to Talk About

Photo: Federal Bureau of Investigation, Public domain, via Wikimedia Commons

Somewhere in your codebase — probably in a services folder with an optimistic name like integrations/ or lib/third-party/ — there are connections to the outside world that nobody has thought about in a long time. Maybe it's a payment processor you switched away from eighteen months ago but never fully removed. Maybe it's a social login flow for a platform that quietly changed its API terms and started returning 403s. Maybe it's an analytics SDK from a company that got acqui-hired and deprecated their product last spring.

This is API graveyard territory, and it's one of the most underestimated forms of technical debt in modern software teams.

Why Integration Debt Is Different (And Sneakier)

Most technical debt is internal. Messy code, outdated patterns, missing tests — these are problems that live entirely within your control. You can fix them on your own schedule, and while they accumulate interest over time, they don't usually introduce new failure modes out of nowhere.

Third-party integration debt is different because it has an external dependency you can't control. An API provider can change their authentication scheme, deprecate an endpoint, raise their rate limits, or simply go dark — and suddenly your integration breaks in production, often without any warning that's visible inside your own system.

The sneaky part is that most dead or dying integrations don't fail loudly. They fail silently. A webhook stops firing. An enrichment call returns empty objects instead of data. An SDK makes network requests that time out without throwing exceptions your error tracking actually catches. The integration looks alive in your code. It just isn't doing anything useful anymore.

The Real Cost Nobody Budgets For

Let's talk about what dead integrations actually cost, because the business case for cleanup is stronger than most teams realize.

Security surface area. Every third-party dependency is a potential attack vector. An unmaintained SDK might have known CVEs. An API key that's been sitting in your environment variables for three years, scoped too broadly because nobody remembers why, is a liability. The fewer active integrations you have, the smaller your exposure.

Developer cognitive load. When a new engineer joins your team and reads through the codebase, every integration they encounter is something they need to understand — or at least account for when making changes. Dead integrations add noise to that mental model. They make it harder to reason about what the system actually does.

Operational overhead. Monitoring, alerting, and incident response all scale with complexity. If your dashboards are tracking the health of integrations that don't meaningfully impact your product anymore, you're burning attention on signals that don't matter.

Surprise migration costs. The longer you wait to remove a dead integration, the more entangled it becomes. A third-party SDK you installed three years ago might have quietly woven itself into a dozen different components by the time you get around to removing it — especially if subsequent developers assumed it was intentional infrastructure.

Running an Integration Audit Without Losing Your Mind

The good news is that auditing your integration layer is more tractable than it sounds. Here's a framework that works well for teams of most sizes.

Step one: Inventory everything. Pull together every external API call, SDK, webhook endpoint, and OAuth connection in your codebase. This isn't just a grep exercise — check your environment variables, your secrets manager, your CI/CD config, and your infrastructure-as-code. You'll find things you forgot existed.

Step two: Classify by status. For each integration, answer three questions. Is the provider still active? Is the integration still actively used by real users or real workflows? Is there a current owner on your team who understands it? An integration that fails all three of these checks is a strong cleanup candidate.

Step three: Check actual traffic. Don't rely on code inspection alone. Pull your API call logs, your network monitoring data, or your APM traces and look at actual request volumes over the last 90 days. You'll often find integrations that exist in code but have zero real-world traffic — which tells you they can probably be removed without user impact.

Step four: Triage into buckets. Not everything you find needs immediate action. Sort your findings into three groups: remove now (clearly dead, zero traffic, provider gone), schedule for cleanup (low traffic, provider still active but integration is redundant or outdated), and watch list (integration is active but the provider has announced deprecation or shown instability).

Making the Case to Actually Do Something About It

Here's where a lot of cleanup efforts stall: the audit goes great, the findings are clear, and then nobody can get prioritization for the actual work. Integration cleanup doesn't have a user-facing feature to demo. It doesn't move a product metric. It's hard to put in a sprint.

The framing that tends to work is connecting the cleanup to something the business already cares about. Security audits, compliance reviews, and incident postmortems are all natural forcing functions. If your team is preparing for a SOC 2 audit, a dependency cleanup initiative fits naturally into that narrative. If you recently had an incident that involved a third-party failure, that's a window to make the case for reducing your integration footprint.

Another angle that resonates with engineering leadership: frame it as reducing your blast radius. Every external dependency your system relies on is a dependency that can fail, get compromised, or change its behavior without your consent. Cutting dead integrations isn't just housekeeping — it's risk reduction.

What to Do When the Provider Is Still Alive But the Integration Is Dying

Sometimes the messiest situation isn't a dead provider — it's a live one whose product has drifted away from your use case, or whose API is technically still running but clearly in maintenance mode. These are the judgment calls that require the most nuance.

A few signals that a still-active integration is worth sunsetting: the provider hasn't shipped a meaningful update in over a year, their developer documentation is visibly stale, their status page has a pattern of recurring incidents, or the problem they solve is now handled natively by another tool in your stack.

For these cases, treat the migration like any other migration: define a clear cutover date, identify what replaces the integration (even if the answer is "nothing," that's still a valid replacement), and give the removal a proper project scope rather than just deleting files and hoping for the best.

The Unglamorous Work That Keeps Systems Healthy

There's a reason integration audits don't make it onto engineering blogs very often. The work isn't exciting. There's no clever algorithm involved, no architectural insight to brag about. It's mostly reading logs, following import chains, and having honest conversations about what your system actually needs versus what it was built to accommodate years ago.

But the teams with the cleanest, most maintainable codebases aren't the ones who wrote the most brilliant code. They're the ones who consistently did the unglamorous work — including taking out the trash when integrations stopped earning their place.

Your API graveyard isn't going to clean itself. But the good news is, it's not as scary as it looks once you start.

All Articles

Related Articles

I Built the Same App Three Times in Three Frameworks. Here's What a Year Taught Me.

I Built the Same App Three Times in Three Frameworks. Here's What a Year Taught Me.

Stuck in the Bug Loop: What Debugging Marathons Reveal About How We Actually Think

The Repo Graveyard: What Your Abandoned Projects Are Actually Trying to Tell You

The Repo Graveyard: What Your Abandoned Projects Are Actually Trying to Tell You