Designing APIs that survive multiple mobile app versions in the wild
Unlike a web app, you can't force every mobile user onto your latest API contract overnight. Here's how to design for that reality instead of discovering it during an incident.
- + 7 min read
- + May 21, 2026
- + api-design
- + mobile-development

Iliyas Shaik
Co-founder & CTO · May 21, 2026
A web app's API contract effectively has one live version most of the time, because deploying the frontend deploys the new contract expectations with it. Mobile breaks this assumption completely: app store review delays, users who don't update for months, and platforms that reject forced-update dark patterns all mean your API has to serve several app versions simultaneously, sometimes for a long time.
Design the contract assuming old clients never go away
- Never remove a field from a response that an old client depends on: add new fields, deprecate old ones slowly, and track actual usage before removing anything
- Never change the meaning of an existing field: if a status value used to mean one thing, add a new field for the new meaning rather than redefining the old one
- Make new request fields optional with sensible server-side defaults, so an old client that doesn't send them still works
Version at the right layer
Full URL versioning (/v1/, /v2/) works but tends to fossilize old endpoints indefinitely because nobody wants to be the one deciding it's safe to delete /v1. A lighter approach, an API version header the client sends, with the server able to adapt response shape per version, keeps the versioning decision explicit without duplicating entire endpoint trees.
Force-update as a last resort, not a first line of defense
A minimum-supported-version check that blocks genuinely incompatible old clients is a reasonable safety net; we build this into most mobile backends as a dedicated version-check endpoint the app calls on launch. But it should be the backstop for breaking changes you couldn't avoid, not the default plan for every API evolution. Most changes shouldn't need it if the contract was designed defensively.
- Ship a dedicated app-version endpoint that returns minimum supported version, so the app can prompt an update gracefully rather than crashing on a malformed response
- Log which app versions are actually hitting your API in production: you can't safely retire support for a version you don't know is still in use
- Treat force-update as a UX decision with real consequences, not just a technical toggle: a forced update at the wrong moment loses users

Test against old clients, not just the current one
The failure we've seen most often isn't a deliberate breaking change, it's an accidental one, where a backend refactor changes a response shape in a way that only breaks a client version the team stopped thinking about. Keeping a build of your oldest still-supported app version around for contract testing catches this before it ships, not after a support ticket does.
More on development.
Let's scope your build. Free, and with no pitch attached.
Tell us the workflow that's costing you time. We'll come back within 24 hours with an honest read on whether we're the right fit.


