Manage versions and environments
Prompt:
Checkout broke with the last release. Roll production back to the version before it.
Also works:
- "What did we deploy this week?"
- "Add a development environment, so I can test before production."
- "Stop the development environment for now."
- "Rename this application to parts-search."
- "Delete the test application."
What your tool does
- Reads the platform's
releaseskill for a rollback, and callslist_versionsto find the version production served before. - Calls
roll_backwith the application identifier, that version, andwait_seconds, so the response waits until the rollback ends. Where the response includesnext, it makes thatread_statuscall. - Calls
list_versionswhen you ask what was deployed, narrowed to one environment if you name one. - Calls
halt_environmentorresume_environmentwith the application identifier and the environment. Both finish before the call returns. - Calls
restart_applicationwith the application identifier, the environment, andwait_seconds. If the restart has not ended when the response returns, it makes the response'snextcall. - Calls
create_environmentwith the application identifier andenvironment: "development"when you ask for a development environment. It finishes before the call returns. - For a rename or a deletion, calls
rename_application,delete_environment, ordelete_applicationand prints the approval link in the response. After you approve in the browser, it reads the outcome withread_pending_action. - Asks you for a browser approval only for those three destructive-tier actions.
roll_back,halt_environment,resume_environment,restart_application, andcreate_environmentrun without one. - Reports the version production serves, the environment's
haltedmember, or the pending action's outcome, and writes nothing into your project.
What you need
- For renaming or deleting an application, sign in to a browser with the same account, because you approve that action there yourself.
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.
- Your tool connected and signed in (Connect your tool).
- An application deployed as Deploy an application describes. A rollback needs an earlier deployed version that production does not serve.
- For a production halt, your signed-in session or a token minted for the whole account.
Steps
Each section below is one task. They do not depend on each other.
Roll back
roll_back requires the application identifier and version. The version is the number of a deployed row in the version history, and it must not be the version production is serving. A rollback promotes that version:
- It reuses that version's image.
- It mints a new production platform credential, as every promote does, and leaves the database credential unchanged.
- It takes
wait_seconds, 1 to 45, as a promote does (Promote to production). The response then waits until the rollback ends, and returns status 200 withstatedeployedorfailedand the record'soutcome. - Without
wait_seconds, or where the wait runs out, it returns status 202 withstate: "deploying". After a wait that ran out, the response also includesnext: the exactread_statuscall that follows the rollback until it ends. That call namesenvironment: "production", so its top-level members describe production.
When a rollback shows deployed, every router already sends production's hostname to the version you named. The switch waits until the rollback is 30 seconds old, and the record turns deployed 3 seconds after it. So a rollback takes at least 33 seconds.
Each response starts with summary, one sentence about production. Its detail says how the rollback ended or how to follow it. Each also includes health_path, the current manifest's health path, which the health check probes on the version you named.
A response that is not the platform's own, such as a gateway's error page or a closed connection, says nothing about whether the rollback was made. Read read_status first: a rollback that started shows as a promote row begun after your call. Roll back again only where none did.
roll_back works on every application, including one with a single environment, where promote itself is refused. There every deploy goes straight to production, so the version you name is one of production's own earlier deploys.
A rollback to production's serving version is refused 409 version_already_serving. A number that no deployed row has is refused 404 no_such_version. A version whose image the platform has deleted is refused 409 version_image_pruned; deploy its artifact again as a new version instead.
A rollback moves code only. The platform takes no snapshot at a promote, so across a data-model change you decide yourself how the data is migrated or restored. Add a database explains what the migration walk does when the application starts.
The version history
list_versions returns the application's history newest first, one row per deploy, promote, or platform redeploy. An optional environment limits the response to one environment, and limit and cursor split it into pages. To learn only which version each environment serves, call read_status, which names it without the history. The list_versions reference lists each row's members.
Two members say what a row can be used for:
servingis true on the row of the version each environment runs.promotableis true on a deployed row whose image the platform still keeps, sopromoteandroll_backcan name its version. It says the image still exists, not that promoting it is advised.
The platform keeps the images of each environment's twenty most recent deployed versions, the serving version among them, and deletes older ones. A row whose image was deleted shows promotable: false, and a promote or rollback of its version is refused 409 version_image_pruned. The history leaves out the rows of a deleted environment.
Two more members describe the runtime harness, the platform's code built into every image beside your application. harness_hash is the SHA-256 of the harness in the row's image, or null where the platform did not record it. harness_current is true where that harness is the one the platform builds into new images today. Only a new deploy gives a version the current harness, because a promote reuses the image as it is.
The list_versions response's page is the address of this page, and its detail names this section.
A rollback and a promote both write a promote row with the number of the version they promote. On an application with one environment, each deploy writes a production row of kind deploy. So the history shows which version production served, and when. The version history explains how the serving version is determined.
Each ended row's outcome starts with result: succeeded, failed, interrupted, or superseded. Each row's timings lists the steps it went through, with when each began and ended.
succeeded means the declared health path answered 200 within the check's time limit. Where the row replaced a serving version, the routers' short wait after the switch has also passed. No other path is checked, so a failing route shows in read_status's server_errors once a request reaches it. A single request ended with upstream_ended (the router's answer when the application's own process ends before it responds) just after a switch may be retried where repeating it is safe.
After a failed first promote, or a failed first deploy of an application with one environment, production has no serving version. list_applications and export_account then return the application's own state as failed, the same value production's environment shows. The application page on the signed-in site shows it as Failed to reach production. Once a promote or a production deploy succeeds, the state is deployed. A failed one over a serving version leaves the state deployed.
Halt and resume
halt_environment stops an environment, and resume_environment starts it again. Each takes the application identifier and the environment, and finishes before the call returns. Each returns the environment's halted member and an outcome of halted, resumed, or unchanged.
A halted environment keeps its version, data, and credentials. Its hostname returns 503 environment_halted on every path.
Which credential can halt or resume:
- A production halt needs your signed-in session or a token minted for the whole account. A token limited to one application is refused 403
account_credential_required. halt_environmenton development, andresume_environmenton either environment, accept your signed-in session, a token minted for the whole account, or a token limited to one application.
halt_environment refuses an environment with no deployed version, 409 environment_never_deployed. It also refuses one with a deploy, promote, or platform redeploy in progress, 409 deploy_in_flight. One case differs: on an application with one environment, halting production while a deploy is still building is accepted. It ends that deploy, which read_status then shows as failed, and nothing reaches production. Once the build is done, the halt is refused deploy_in_flight until the deploy ends, so call it again then.
What ends a halt:
- A development halt ends at the next
deployto it or atresume_environment. - A production halt ends only at
resume_environment. Until then a promote to production is refused 409target_environment_halted, and so is a deploy on an application with one environment.
The platform also halts an unused development environment itself. The halted state states what each halt stops and when the platform halts an environment.
Restart an environment
restart_application takes the application identifier and the environment. It re-creates the environment's running copy from the version the environment serves, under the platform's current settings. It builds nothing and writes a restart row for the same version. With wait_seconds, 1 to 45, it returns once the restart ends, as a promote does; otherwise it returns status 202 at once. Where the wait runs out, its next is the read_status call for the restarted environment. A restart does not count against your plan's deploys per day. It is refused while a deploy, promote, or restart of the environment is in progress.
Each response includes health_path, the current manifest's health path, which the restarted copy's health check probes. Like a rollback, a restart switches no sooner than 30 seconds after it starts and shows deployed 3 seconds after its switch.
A response that is not the platform's own, such as a gateway's error page or a closed connection, says nothing about whether the restart was made. Read read_status first: a restart that started shows as a restart row begun after your call. Restart again only where none did.
A restart re-applies the settings the manifest bound when the running copy was made, never those of the current manifest. Each setting takes the value stored now. A rollback re-applies the bindings its version last had in production, or, where production never ran it, those its deploy recorded. A bound setting is left out, with a warning in the application's log, where its stored name no longer exists or a later rule rejects it. The restart or rollback is never refused for it.
Where the stored name exists but the secret store does not return its value, the restart or rollback ends as failed with bound_setting_unreadable before anything is applied, and the serving copy is unchanged. Try it again. A restart brings a rotated bound value into a running copy that already has the binding. A binding added since the copy was made waits for the next deploy or promote (Store a secret).
read_status reports both cases for each environment. rotated_since_read lists each setting whose secret was stored or rotated after the running copy started, which a restart brings up to date. bound_not_applied lists each setting the manifest binds that the running copy lacks, which only the next deploy or promote applies. The response's summary counts the settings in each list and names the list. It does not repeat the settings. Where either list has an entry, the environment's settings_apply says which action applies each list.
Both lists are computed at every read. So an empty rotated_since_read means the running copy has the stored value of every setting it applied, never that the platform has not looked yet.
A restart sets each declared upstream's settings from the current declarations, with a new egress key for each key setting that a provider's software development kit (SDK) reads (An unchanged SDK).
Rename the application
rename_application requires the application identifier and a new valid name that differs from the current one. Create the application gives the rules for a name. The call asks for a browser approval.
The approval description is short. It names the application's hostname label, the current and new names, and the two hostnames that stop working. It counts the passkeys of each environment and the unredeemed invitation links of both that stop working, says which running copies restart, and links to this section.
When the approved rename runs, it retires both previous hostnames, and the serving router starts serving both new ones within its refresh interval. Each new hostname joins the new name to a fresh key that the platform chooses when the rename runs. Read the outcome with read_pending_action for the exact new hostnames.
The rename has these effects:
- Both previous hostnames, production's and development's, stop working for good. A request to either is refused
unknown_applicationand is never redirected to the new hostname. The platform never gives a retired hostname to any application again. Renaming the application back to its old name gives it new hostnames, not the old ones. - The previous name is freed, so another application in the account can take it.
- Each passkey that an end user registered on a previous hostname becomes a stranded passkey and stops working. The person registers a new passkey on the new hostname.
- An end user who is signed in signs in again on the new hostname, because the browser keeps the sign-in cookie for the previous hostname only.
- A sign-in code requested on a previous hostname cannot be confirmed after the rename. The person requests a new code on the new hostname.
- An invitation link that holds a previous hostname stops working, though the invitation itself can still be redeemed. Send the link again with the new hostname in place of the previous one. Or revoke the invitation with
revoke_invitationand issue a new one. - Each deployed environment restarts, so its running copy's
APP_PUBLIC_HOSTsetting names the new hostname without a deploy. - Where a restart is refused, the outcome's
containermember names the refusal. That running copy keeps the previous hostname inAPP_PUBLIC_HOSTuntilrestart_application, or the next deploy or promote of its environment, writes the new one. - The application keeps its identifier, plan, manifest, deployed code, secrets, tokens, and usage.
Renaming an application explains the name rules and what happens when another change reaches the application before the rename runs.
Turn the development environment on
A new application has one environment, production. Its deploys go straight to production, and roll_back puts an earlier version back. A second environment, development, gives you a hosted copy where you test a version before your users see it.
create_environment turns development on at any time. It takes the application identifier and environment: "development", and finishes before the call returns, with no browser approval. A call that names production is refused 400 invalid_request, because production always exists.
You can call it before or after submit_manifest: either order ends in the same state. submit_manifest creates development's credentials on every application, and its database where the manifest declares one, whichever call comes first. create_environment adds the hosted development copy and creates no database.
From then on:
- a deploy goes to development, at
<label>-dev.ai.host, andpromotemoves a version to production; - where the manifest declares the accounts service, development has its own realm and its own list of end users, and local runs sign testers in there;
- the manifest's
realmmember andpushproviders apply to development as well as production; - development's schedules run from its first deploy.
Local data that names production's users matches no one on the development realm, because that realm has its own users.
The call returns created: true and the development hostname. Where the application already has development, it returns created: false and changes nothing, except to finish a step an earlier call left undone. It creates nothing hosted: development's compute starts at its first deploy. The response's page is the address of this page.
Delete the development environment
delete_environment turns development off again, after a person approves the deletion in the browser. It removes the development environment, and the application has one environment again, so the next deploy goes to production. A call that names production is refused 400 invalid_request, because production is deleted only with its application, through delete_application.
On an application with one environment, the call removes the development database and the other records your local runs keep. It does so where a database setup exists, finished or stopped partway, where an earlier deletion of them stopped, or where a record an earlier version of the platform left is still there. Production is untouched. Otherwise it is refused 409 environment_not_created.
The next submit_manifest provisions development's records for local runs again, including its database and storage parts, and mints its credentials once more. It creates no development realm. It also ends development's schedules, and a later create_environment declares them again from the manifest. The Hypertext Transfer Protocol (HTTP) application programming interface (API) returns the credentials, and the Model Context Protocol (MCP) tool withholds them, as Declare the manifest describes. Deleting the development environment lists what the deletion removes and what stays.
If you turn development on again with create_environment, call submit_manifest before the first deploy to development, so that development has its records again, its database among them.
Delete the application
delete_application removes the application with every environment it has, after a person approves it in the browser:
- Your tool calls it with the application identifier and prints the approval link in the response.
- You open the link and approve on the browser page, which shows the platform's description of what the deletion removes. It lists each kind and counts the storage areas, secrets, upstreams, and outstanding transfer grants. The page also links to this section for what the deletion keeps.
- Your tool reads the outcome with
read_pending_action.
The deletion removes, one kind at a time:
- each environment's compute, the image repository, and the published assets;
- every end-user realm with every user, identity, session, passkey, and invitation in them;
- both databases with their roles and credentials;
- its issue-tracking space, or both spaces of an application with one for each environment, each deleted at the issue service with every report, comment, rating, and ask in it;
- its binding to an issue space of your account's own, which keeps its records;
- the secrets stored at the application's scopes, both platform credentials, the tokens minted for the application, and the transfer grants;
- the schedule rows, the upstream declarations bound to the application, and the storage areas bound to it with their files;
- the log entries and counter totals;
- last, the application row with its version history, its label retired and never reused.
Secrets stored for the whole account stay. So does any storage area or upstream that was declared before an application binding was required and is not yet bound to one. The usage meters keep their rows. The secret store keeps deleted secret values for ninety days before it purges them, and no action of yours can read or restore them (Secrets). The deletion does not revoke a key at the service that issued it, so replace the key there if it should stop working.
The application's console output also stays in the hosting provider's log store for up to thirty days, and no deletion, erasure, or purge_logs reaches it. An approved deletion cannot be undone.
A deletion that stops because one kind fails to be removed ends execution_failed, and the Refusals table below gives its remedy. Management action tiers and approvals explains the pending action and its outcomes.
Expected result
- After a rollback,
read_statusshows production'sdeploy.stateasdeployedand itsversionas the number you named.list_versionsshows a newpromoterow for production withserving: true. - After a halt, the environment's
haltedmember containsatandby, and its hostname returns 503environment_halted. After a resume,haltedis null. - After an approved rename,
read_pending_actionshows the recordcompleted, and its outcome gives the new hostname. - After
create_environment,read_statuslists development beside production, development asnever_deployeduntil its first deploy. - After an approved deletion,
read_pending_actionshows the recordcompleted, and its outcome lists what was removed. After the development environment's deletion,read_statuslists production alone.
Refusals
A refusal changes nothing on the platform. The status is the one the HTTP route returns, and the MCP tool returns the same refusal name. Three rows, description_changed, execution_failed, and interrupted, are outcomes a pending action records, and read_pending_action shows them. They are not responses to the call. Two more, cell_not_configured and cell_unavailable, refuse a deletion after its approval, so read_pending_action shows them too, on a record that ended failed. Refusals lists every refusal the platform returns.
After development is turned on, create_environment can also be refused name_bound_to_setting, custody_entry_missing, custody_entry_unmovable, or realm_not_declared while it records the manifest's sign-in or push settings there. Development stays on, and the detail says what became of the setting and whether to call it again or submit the manifest. Author the manifest explains each.
| Refusal | Status | Cause | Remedy |
|---|---|---|---|
version_already_serving |
409 | roll_back named production's serving version. |
Name an earlier version. To mint a new production platform credential, call promote instead, or deploy again on an application with one environment. |
no_such_version |
404 | roll_back: the version is not a deployed row of the application, or its environment was deleted. |
Name a row list_versions returns with state: "deployed". |
version_image_pruned |
409 | roll_back: the platform has deleted the named version's image. |
Deploy that version's artifact again as a new version, and promote it where the application has two environments. |
target_environment_halted |
409 | roll_back while production is halted, or restart_application on a halted environment. |
Call resume_environment, then call again. |
deploy_in_flight |
409 | roll_back while a production promote is in progress, or halt_environment or restart_application while a deploy, promote, or redeploy of the environment is. |
Wait with read_status and wait_seconds, up to 45, until deploy.state is no longer deploying, then call again. |
environment_never_deployed |
409 | halt_environment or restart_application: the environment has no deployed version, so there is nothing to halt or restart. |
Deploy first. |
plan_quantity_unset |
409 | roll_back or restart_application of an application with a database while its plan's database-connection-limit is not set. plan and measure name it, and no version is added. |
Wait until platform staff set the quantity, then call again. |
account_credential_required |
403 | halt_environment on production under a token limited to one application. |
Call it under your signed-in session or a token minted for the whole account. |
environment_halted |
503 | A request reached a halted environment's hostname. | Call resume_environment, or, for the development environment, deploy. |
name_taken |
409 | rename_application: the account already has a live application with that name. |
Choose another name. |
invalid_request |
400 | Missing or malformed input, such as create_environment or delete_environment naming production, or rename_application naming the current name. The detail names the member. |
Correct the named member. Delete production with delete_application. |
environment_not_created |
409 | The call named development on an application with one environment: halt_environment, resume_environment, restart_application, or delete_environment where no development database setup, stopped deletion, or record left by an earlier version exists. |
Name production, or turn development on with create_environment first. |
no_such_application |
404 | The account has no application with that identifier. | Use an identifier list_applications returns. |
cell_not_configured |
503 | delete_environment, after the approval: the platform has no record of where the development environment is hosted, and no hosting cell is registered or open to record one. Nothing was deleted. |
Nothing on your side corrects this. Report the refusal with its detail, and request the deletion again once the platform's operator has opened a hosting cell. |
cell_unavailable |
503 | delete_environment, after the approval: the platform has no record of where the development environment is hosted, and every open hosting cell is full. Nothing was deleted. |
Nothing on your side corrects this. Report the refusal with its detail, and request the deletion again once the platform's operator has added room for it. |
deletion_in_progress |
409 | A deletion of the application or one of its environments is running. Reads, read_pending_action, and a repeat of the same deletion are accepted. |
Wait for the deletion to finish; read_pending_action shows whether it completed. If it failed, request the same deletion again to complete it. |
destructive_class_required |
403 | delete_application, delete_environment, or rename_application ran under a credential without the destructive grant. No pending action is created. |
Call it from the connected session, or under a token minted with the destructive grant. |
approval_wrong_account |
403 | The browser that opened the approval link is signed in to another account. | Sign in to the requesting account in the browser, then open the approval link again. |
approval_expired |
409 | The pending action expired before a person approved or declined it. | Request the action again and approve the new pending action. |
description_changed |
none | At approval, the platform's description of the subject differed from the one the person approved. The record ends declined, and nothing runs. |
Request the action again and approve its current description. |
execution_failed |
none | The pending action failed without a named refusal. A deletion's outcome includes receipts for what it removed before the failure. |
Read the receipts and the current state, then request the deletion again. A kind already removed reports zero removals. |
interrupted |
none | A pending action stayed in progress for more than thirty minutes, for example across a platform restart, and was marked failed. |
Read the current state before you request and approve another attempt, because some changes may have happened. |
Related
- Deploy an application creates the application and deploys it to production, and covers the promote of an application with two environments.
- Applications and environments explains the version history, the halted state, renaming, and the two deletions.
- Management action tiers and approvals explains the browser approval and the pending action.
- Add a database explains what the migration walk does at start, which a rollback does not undo.
- roll_back, list_versions, halt_environment, resume_environment, restart_application, rename_application, create_environment, delete_environment, and delete_application are the actions' generated reference entries.