You’ve been there. You’re three hours into integrating a third-party API, you’ve read the documentation twice, and you still can’t figure out why your POST request keeps returning a 422 Unprocessable Entity error. You start to wonder if the developers who built this thing actually hate you personally. Here’s the thing: sometimes the friction isn’t a bug. Sometimes it’s the product. The deliberate complexity baked into many APIs isn’t engineering negligence, it’s a carefully considered business strategy that filters users, creates dependency, and builds moats that competitors can’t easily cross.
This connects to a broader pattern worth understanding. As we’ve explored before in our look at how tech companies hide their real business logic in product decisions, the most revealing thing about a software product is often not what it does but what it makes unnecessarily hard.
The Qualification Filter You Never Signed Up For
Let’s start with the most counterintuitive idea: a painful API is a self-selecting talent filter. If you can’t get through the OAuth 2.0 handshake, generate a valid JWT (JSON Web Token, a compact way of securely transmitting information between parties), and correctly paginate your requests, the company has quietly decided you’re not their target developer. This sounds elitist, and honestly, it is. But from a support cost perspective, it makes cold business sense.
Stripe, which is widely praised for its developer experience, still requires you to understand webhook verification, idempotency keys, and event-driven architecture before you can build anything production-ready. That complexity isn’t accidental. It means the developers who successfully integrate Stripe are capable enough to troubleshoot their own problems, reducing the burden on Stripe’s support team dramatically. The friction cost is real, but it’s paid by the developer once, not by Stripe’s support staff indefinitely.
Compare that to the alternative: a completely frictionless API that any junior developer can wire up in twenty minutes. You’d get a flood of integrations, most of them fragile, poorly maintained, and generating support tickets at scale. The math on that is ugly.
Complexity as a Lock-In Mechanism
Once you’ve spent forty hours learning the quirks of a particular API, its custom query language, its non-standard rate limiting behavior, its proprietary data formats, you have skin in the game. Switching to a competitor means abandoning that investment and starting over. This is sometimes called a “switching cost,” and API complexity is one of the most effective ways to manufacture it.
Salesforce is the canonical example. Their API ecosystem is famously sprawling and inconsistent. There’s the REST API, the SOAP API, the Bulk API, the Streaming API, and the Metadata API, each with its own conventions, each solving slightly overlapping problems in slightly different ways. Learning to navigate all of them takes months. But once your engineering team has built that expertise and your business logic is woven through it, the idea of migrating to a competitor feels genuinely terrifying. That terror is valuable to Salesforce. It’s basically an invisible retention contract.
This is the same logic that explains why SaaS companies deliberately lose money on cheap tiers: they’re buying future lock-in with present-day discounts. API complexity buys lock-in with your time and cognitive investment instead of their money.
Documentation That’s Just Incomplete Enough
Here’s a pattern you’ll recognize if you’ve done enough API integration work. The documentation is good, almost suspiciously good, for the basic use cases. Getting your first successful API call feels great. But the moment you try to do something even slightly advanced, like filtering by multiple nested fields, handling partial failures in batch operations, or working around rate limits during traffic spikes, the docs go quiet. You’re left reading Stack Overflow threads from five years ago and reverse-engineering behavior from error messages.
This isn’t always malicious. Sometimes it’s just under-resourced technical writing. But the business consequence is real regardless of intent: developers who need advanced functionality have to reach out, engage with the company, talk to sales or developer relations staff, and often end up on higher-tier plans that include support. Incomplete documentation quietly monetizes your confusion.
This is a cousin of the strategy behind software companies releasing products with deliberate gaps. The gap isn’t a failure of quality control. It’s a feature of the business model.
The Moat Nobody Talks About
API complexity also serves a competitive function that has nothing to do with end users. When your API is deeply integrated into a customer’s infrastructure, the customer’s own switching cost becomes your competitive moat. But there’s a second-order effect: competitors trying to build compatible or interoperable tools also face that complexity.
Imagine you’re a startup trying to build a tool that syncs with a major platform’s data. You have to reverse-engineer rate limits that aren’t fully documented, handle authentication edge cases that behave differently across account types, and manage schema changes that get announced in a changelog buried three links deep in a developer portal. Every hour your engineering team spends on that is an hour they’re not building your core product. The incumbent’s complexity is your startup’s tax.
This connects to a broader pattern of strategic friction that elite software teams have learned to recognize and route around. The teams that ship fastest aren’t the ones fighting the complexity, they’re the ones who’ve learned to identify which battles are worth having.
What Developers Should Actually Do With This Knowledge
Understanding that API friction is frequently intentional changes how you should approach integration decisions. Before you commit to a platform, map the complexity honestly. How much institutional knowledge will your team need to build? What does the migration path look like if you need to leave? Are there open standards (like REST, OpenID Connect, or GraphQL) being used, or is everything proprietary?
The presence of proprietary abstractions isn’t automatically a red flag, but it should prompt a calculation. You’re not just buying access to functionality. You’re accepting a long-term dependency that the provider has engineered to be hard to exit.
And if you’re on the other side of this, building an API rather than consuming one, it’s worth being honest about the tradeoffs. Complexity that creates switching costs also creates resentment. Developers talk. The communities around APIs that treat developers as partners rather than captives tend to grow faster and generate more genuine advocacy. Sometimes the smartest long-term play is the one that makes integration embarrassingly easy and trusts your product to do the retention work instead.
The friction in your developer experience is always telling you something. The question is whether you’re listening to what it’s actually saying.