Keep installed clients compatible
Prompt:
Stop app versions older than 2.3.0 from calling the backend, and send those users to the store.
Also works: "Which versions of our app are people still using?" "Can I ship this backend change without breaking the old app?" "Force an update of the mobile app."
What your tool does
- Adds the version header to the one function the app uses for every backend request.
- Calls
read_realmon the environment's realm and reports the versions each declared client stated in the last day. - Calls
configure_realmwith the client'sminimum_versionandupdate_url, and reports anywarningsthe call returns. - Reads the
x-turnzero-cloud-versionheader on a backend response to confirm which deployed version handled it. - Reads the versions in use again before the backend changes in production, at a deploy on an application with one environment or a promote on one with two. It says which installed versions the new backend may break.
What you need
- A native app declared on the realm with its
client_id, as Sign in from a native app describes. - The app's store link, where a refused user is sent to update.
Before your AI starts
This section is for your AI tool: what it checks and gathers before it begins. You don't need to do these steps yourself.
- A connected, signed-in tool (Connect your tool).
- The realm's declared clients, read with
read_realmon each environment. - The app's release version, in the
major.minor.patchform the store build uses.
Steps
1. Send the version header from the app
The app states its identity and its version on every request to the backend. The value is the declared client_id, a slash, and the app's version. No test checks this sample.
x-turnzero-cloud-client: com.example.app/2.3.1
Set it in the one function the app uses for every backend request, beside the bearer. The version is major.minor.patch, with an optional pre-release such as 2.4.0-beta.1. A pre-release sorts below its release.
A request without the header is never refused. Neither is one that gives a client the realm does not declare, or a value of another form. The header reaches your backend as the app sent it.
2. Read the versions in use
Every serving router records each declared client's version it sees, at most once a minute. read_realm returns the last day of them beside each client, highest version first. No test checks this sample.
{
"client_id": "com.example.app",
"redirect_uris": ["com.example.app:/callback"],
"minimum_version": "2.0.0",
"update_url": "https://apps.apple.com/app/id123456789",
"versions_seen": [
{ "version": "2.3.1", "last_seen": "2026-09-27T09:41:00.000Z" },
{ "version": "2.2.0", "last_seen": "2026-09-27T08:15:00.000Z" }
]
}
A version drops out of the list a day after its last request. Each environment's realm keeps its own list, so read the realm of the environment you are changing. A client keeps at most fifty versions at a time.
3. Raise the minimum version
Call configure_realm with the client's minimum_version and its update_url. The change applies at once, with no deploy, and configure_realm lowers or removes it the same way. clients replaces the whole list, so send every client with its current members.
Also raise the minimum when a backend package contract your client's build depends on is retired at the end of its compatibility window. Set it to the first client version built against a contract still in service. Then the version check tells an older client to update, instead of a call failing. The platform enforces the declared value.
Where the new minimum would refuse versions seen in the last day, the response includes warnings. The change still takes effect. No test checks this sample.
{
"warnings": [
{ "code": "clients_in_use", "client_id": "com.example.app", "versions": ["2.2.0"] }
]
}
From then on, the router refuses a request from a lower version with 426 client_upgrade_required. The refusal reaches no backend code and counts toward no request limit.
{
"error": "client_upgrade_required",
"detail": "Version 2.2.0 of com.example.app is below 2.3.0, the oldest version this application admits; update the app at https://apps.apple.com/app/id123456789 and try again.",
"minimum_version": "2.3.0",
"update_url": "https://apps.apple.com/app/id123456789"
}
Show the user a screen that opens update_url, and stop retrying the request. update_url is null where the client declares none.
4. Read the version that responded
Every response your backend gives through the router includes x-turnzero-cloud-version, the deployed version that handled the request. It matches the version numbers list_versions returns. An environment with no deployed version responds without it.
5. Before a promote
A promote changes the backend every installed app calls, and so does each deploy on an application with one environment, which goes straight to production. Read the versions in use on the production realm first. Where the new backend drops something an installed version still calls, raise the minimum first, or keep the backend compatible until those versions leave the list.
A deploy, a promote, and a rollback never change a minimum, and none of them warns.
Expected result
A request from the app includes x-turnzero-cloud-client, and read_realm lists that version under the client's versions_seen. After the minimum is raised, a request from an older version is refused 426 with the store link. A request from a current version reaches the backend, and its response gives the serving version.
Refusals
| Refusal | Status | Cause | Remedy |
|---|---|---|---|
client_upgrade_required |
426 | The app stated a version below its client's minimum_version on this realm. |
Update the app from update_url. Lower the minimum with configure_realm if the refusal was not intended. |
invalid_request |
400 | A minimum_version is not major.minor.patch, or an update_url is not an https URL. |
Send the three numbers alone, and an https store link. |
Related
- Sign in from a native app declares the client and calls the backend with the bearer.
- Manage end users lists every realm setting.
- Manage versions and environments covers promotes, rollbacks, and the version history.