API-driven development, and where it quietly falls apart
API-driven development - designing your API contract before you write the implementation behind it - is one of those ideas that's correct often enough to become dogma. And dogma is where good ideas go to cause damage.
The Case For It Is Real
It's worth being clear about this up front: API-first isn't a trend that got oversold from nothing. The reasoning behind it holds up.
When you design the contract first, frontend and backend teams can work in parallel against a shared, agreed interface instead of blocking on each other's progress. Nobody's waiting for someone else to finish before they can start. Mobile clients, web clients, and third-party integrators get a stable target to build against instead of a moving one that shifts under them mid-project. And the discipline of writing the contract before the implementation has a habit of surfacing bad assumptions early - while they're still a conversation, not after they've been baked into a database schema and require a migration to fix.
For the right kind of API, this process doesn't just feel rigorous. It saves real time and prevents real breakage.
Where It Falls Apart
The trouble starts when teams treat "API-first" as a mandate rather than a tool to be applied with judgment.
We've seen internal services - with exactly one consumer, changing weekly, owned by the same two engineers who own the caller - put through a full API design review process, simply because "that's how we do things here." The review board, the sign-offs, the versioning discussion: all of it, for a service whose only consumer sits in the same repository and gets deployed in the same pull request.
That ceremony exists to protect you from breaking a public integration you don't control and can't coordinate with directly. It's pure overhead when the consumer is a teammate three desks away who'll see the change in code review anyway. Applying public-API rigor to a private, single-consumer service doesn't make the service more reliable — it just makes it slower to change, with no corresponding benefit.
The Quieter Failure: Contracts That Outlive Their Purpose
The first failure mode is easy to spot because it's visible in the process — extra meetings, extra sign-offs, extra delay. The second failure mode is quieter, and more expensive.
A contract designed to protect external consumers from breaking changes will, if left unquestioned, end up protecting your own team from ever refactoring the internals behind it. "Don't break the API" is a reasonable rule. Left unexamined for long enough, it quietly mutates into "don't touch anything the API touches" - which is a much bigger, much less reasonable rule, and one nobody actually agreed to.
At that point the contract isn't providing stability anymore. It's ossification wearing stability's clothes. The code underneath can't evolve, not because evolving it would actually hurt anyone, but because the team has lost the habit of asking whether the original reason for the rigidity still applies.
The Question That Should Come Before the Ceremony
The pragmatic version of API-first development doesn't discard the process — it asks a question before applying it: who actually consumes this, how many of them are there, and how expensive is a breaking change to each of them?
Public APIs earn the full process. So do cross-team contracts, where the consumer is a different team you can't just walk over and talk to. In both cases, the cost of a breaking change is real and distributed across people who have no visibility into your roadmap - the ceremony is buying you something.
An internal service with a single caller, owned by the same people who own the service itself, usually doesn't earn that same process. The blast radius of a breaking change there is one conversation, not an outage for strangers.
Apply the rigor where the blast radius justifies it. Skip it everywhere else. The goal was never the contract itself - it was protecting the people who'd be hurt by breaking it. Where there's no one to protect, the protection is just weight.