Export or delete your account

Prompt:

Export everything about my account, then delete it.

Also works:

  • "Save a copy of my account's declarations."
  • "Export my app's production database."
  • "What does deleting my account remove?"

What your tool does

  • For an export, calls export_account and writes the response's export document to a file in your project.
  • For each application's data, calls request_export, and calls read_export until the export completes. It then calls mint_download_grant and runs the line the response has, which downloads the files the manifest lists.
  • For a deletion, follows the platform's delete-account skill. It exports the declarations and each application's data first, then calls delete_account and prints the approval_url for you to open in a browser. It reads the outcome with read_pending_action and the id of the pending action.
  • Deletes nothing until you approve the deletion in your browser.

What you need

  • For a deletion, save the export somewhere you choose first, and sign in to a browser with the same account. Only that account's browser session can approve the deletion.

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.

Steps

1. Export

export_account returns the account's declarations as one JSON document under export, with a read_at time. It contains:

  • the account record and product profiles;
  • applications with their manifests, plans, environments, versions, and deployment state;
  • end-user realm settings, without users, with the count of registered devices by platform;
  • each environment's push configuration, with the provider identifiers and secret names, without values;
  • storage area declarations, upstream declarations, and secret names, without values;
  • token records, without values;
  • your feedback, where the platform runs its issue service: your own reports with their histories and comments, your ratings, and the rating asks put to you. spaces contains your own filings, as the same four lists, from each issue space you have. That means each space of your account's own, each application's own space, and each space of an application that kept one for each environment. Without the service, the export leaves this member out.

The export reads these records one after another, so a change made during the export can appear in some parts and not others. read_at is when the export was stamped, just after the account record was read. It is not a single point-in-time snapshot.

The export_account response's page is the address of this page, and its detail names this step.

2. Export each application's data

export_account contains no application code, database contents, or stored files. Application code stays with you: the platform never keeps your source. It keeps the image built from your artifact, which you cannot download.

A zip you deploy with artifact stays a stored file in your own storage area. A zip uploaded through deploy's upload form stays in the application's deploy area until the deploy that read it ends. A zip that no deploy reads stays until a later deploy's upload replaces it. Otherwise the platform's daily cleanup deletes it once it is more than a day old.

Each application's database and stored files leave through request_export, one application and one environment per call, production where you give none. It returns 202 at once with the export's export id and the state running. Call read_export with the application and the export id until the state is completed. A call made while an export of the same application and environment is still running returns that export with repeated: true and starts no second one. The request_export response's page is the address of this page, and its detail names this step.

The export writes into the application's export area, export-<application id>, under a folder named by the export id:

  • each table of the database as one CSV file with a header line, <export id>/database/<table>.csv;
  • a manifest, <export id>/manifest.json, which read_export also returns.

The manifest lists each table's file, columns, and row count, and each file of the application's other storage areas with its size and version. It leaves out the deploy area, deploy-<application id>, whose pending zip the platform deletes itself.

A new export of the same application and environment first deletes the earlier exports' folders, so read_export returns an earlier export with manifest null.

Each part of the export is consistent on its own:

  • The database is read under one repeatable-read transaction, so every table is as it was at the manifest's database.read_at.
  • The stored files are listed, not copied. Where a download returns a different version, its ETag, from the one the manifest lists, the file changed after the listing. The download keeps the file as it arrived and reports it as moved.

Download the export

Once the export is completed, your tool calls mint_download_grant with:

  • application and export, the export's id;
  • local_path, optional: the folder on your machine to write into, as an absolute path or one relative to the folder the line runs in.

The response has one line in two forms:

  • command, for macOS and Linux;
  • command_windows, the same line for every Windows shell, with npx.cmd in place of npx.

Your tool runs the form for its operating system, once, as given, before the response's expires_at. For a call that names local_path as notes-export, command is:

echo <grant> | npx -y https://turnzero.ai/packages/turnzero-cloud-0.8.0.tgz export download --export <application id>/<export id> --path "notes-export"

The line pipes a download grant, a kind of transfer grant, to the turnzero-cloud command. The grant is in the line and in no other member of the response. Until the response's expires_at, five minutes after minting by default, it reads, by name, this export's own files and the application's stored files in the exported environment. It lists nothing and writes nothing, a read does not use it up, and every other route refuses it. So no long-lived token reaches the shell.

Of the application's stored files, the grant reads those created by the time the export listed them. The line asks for each file the manifest lists and for no other. A file that was rewritten after the export is downloaded with its newer bytes and reported as moved.

A file first stored after the export is in no manifest, so the line does not read it and counts nothing for it. A file deleted and stored again after the export is in the manifest but is not downloaded. Its read returns 404 no_such_file, as a name with no file does, and the line counts it as a failed file. A new export has the application's files as they now stand.

An export made before the release that introduced this rule recorded no time for its stored files, so its line downloads the manifest and the tables alone. Each stored file its manifest lists fails, and the response's detail says so. Request a new export to download the stored files. What changed dates the release.

The command reads the manifest, then each file the manifest lists, four at a time, and writes into the folder:

  • manifest.json;
  • each table as database/<table>.csv;
  • each stored file as files/<area>/<name>;
  • .turnzero-cloud-export.json, an index of the files it has finished.

A file name that your machine's file system would refuse or change is written under an escaped name, which the command prints.

Give local_path a folder outside your application's folder, so that no deploy zips the export. Where the call has no local_path, the line writes a new folder, export-<export id>, in the folder it runs in, and it refuses to run in a folder that has a package.json. The command also refuses a folder that already has files and no index of this export, so it writes over no file of yours.

A local_path with a character that deploy refuses in its own local_path is refused 400 invalid_request, and nothing is minted. The deploy reference lists those characters. The line does not expand ~: name your home folder in full.

The line ends with one of four statuses:

  • 0: every file the manifest lists is on disk;
  • 1: a file failed. Run the same line again before the grant expires, and it reads only the files that failed. Where the platform returned HTTP 404 no_such_file for a file, the file was not read, and the closing lines say so. The same line fails that file again, as it does a file deleted and stored again after the export. Call request_export again: a new export has your application's files as they are now;
  • 2: the run stopped before the end, as when the grant expired. Call mint_download_grant again with the same local_path and run the new line, which skips the files already on disk;
  • 3: nothing was written, as when the grant in the line is not valid or the folder is refused.

A script of your own can read the same files without the command: GET /storage/v0/areas/<area>/files/<name> under a minted token, with the x-turnzero-cloud-environment header set to the exported environment. The database files are in the export area, and each other file is in its own area.

The export's files count in the application's stored data from the next daily usage check, so delete them once you have them. If they take the application over its plan's stored data, file uploads stop until you delete them and the next daily check finds the application within its plan (Plan and usage). A table whose CSV file would pass 16 GiB ends the export failed with table_bound_exceeded, and the manifest identifies the table. The export reads no secret value and no end-user list.

Every database server keeps automated backups for 35 days. Only platform staff can restore one. No build serves the restore action, restore_snapshot: a call to it returns 501 not_yet_provisioned. A promote takes no snapshot of the production database.

3. Delete

The delete-account skill exports the account's declarations and each application's data first, then calls delete_account. The deletion request on the site's account page also calls delete_account, without the export, and opens the approval page.

Before you approve, the browser page shows the platform's description of what the deletion removes, the same text as the description in delete_account's response. It names each application by label and counts each other kind: sign-in identities, product profiles, secrets, upstreams, storage areas, databases, end-user realms, issue spaces where there are any, and minted tokens. The issue spaces counted are your applications' spaces and your account's own. It also says that every session ends and that you should export first. The rest of this step says what each of those takes with it and what stays.

The approval page links to this step for what the deletion keeps: the paragraphs after the list below say what stays.

Each kind goes with what belongs to it:

  • each application with its hosted resources, as the list at the end of this step gives them;
  • each storage area with its files, and each database with its roles;
  • each end-user realm with its users;
  • each issue-tracking space, your applications' and your account's own, with every record in it, deleted at the issue service. Its daily copies go with it, and a copy being written at that moment goes at the next daily run.

Some things stay. 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). To stop a key from working, replace it at the service that issued it.

An 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. The action record, the metering history, and the builder realm's event log keep their rows: the deletion removes what you run, never the history of it.

Deleting your account erases your identity from every report and rating you filed in the platform's own feedback. It deletes no report, and each report keeps its text as written.

Each deleted application leaves one record containing its identifier, its retired label, and the deletion time; its name, its manifest, and your account's identifier are cleared from it.

Each application is deleted exactly as delete_application deletes it. That removes:

  • each environment's compute;
  • 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;
  • the daily copies of its own space, a copy being written at that moment deleted at the next daily run;
  • its binding to a space of your account's own, a space the account's deletion deletes too;
  • every end-user realm, with its passkeys and its users' device registrations;
  • the push configurations, the queued deliveries, and the month's counts;
  • the storage areas bound to it, with every file;
  • both environments' application secrets and both platform credentials;
  • the schedule declarations and their run records, and the upstream declarations bound to it;
  • the version histories, the published assets, and the stored images;
  • the log entries and counter totals.

Deletion ends the account's services. It does not change who owns your own work, such as your source code.

Expected result

export_account returns export with read_at and the members account, applications, realms, push, areas, custody, upstreams, and tokens, and feedback where the platform runs its issue service.

request_export returns 202 with export, state: "running", area, and folder. read_export returns state completed with the manifest: its database member with read_at and one entry per table, and its files member with one entry per area. A second request_export while one runs for the same application and environment returns that export with repeated: true.

mint_download_grant returns export, application, environment, expires_at, command, and command_windows. The line prints one line that opens with downloaded: and counts the files on disk, and ends with status 0.

delete_account returns a pending_action in state requested, with its description and expires_at, and the approval_url. After you approve, read_pending_action shows the record in state completed. Its outcome contains deleted: true, estate, one entry for each kind of account resource removed, and applications, one entry for each application removed. The account's sessions end with its services.

Refusals

A refusal changes nothing on the platform. The status is the one the HTTP route returns, and the Model Context Protocol (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. Refusals lists every refusal the platform returns.

Refusal Status Cause Remedy
invalid_request 400 A member is missing or malformed, such as no id for read_pending_action. The detail names it. Correct the named member and call again.
app_credential_not_admitted 403 The call ran under an application's platform credential, which only read_account accepts. Use your signed-in session or a minted token.
authentication_required 401 No credential matched an account; export_account returns it for a session with no account. Sign in again through your tool.
issue_service_unreachable 503 export_account could not read your feedback from the platform's issue service, so it refused the whole export rather than returning one without it. Repeat the export after a short wait.
account_suspended 403 The account is suspended, so actions that need your identity, and sign-ins, are refused. Wait for platform staff to reinstate the account, then sign in again.
fresh_authentication_required 403 A change from the dashboard, such as the deletion request, came more than 8 hours after your browser sign-in. Follow the page's Sign in again link, then repeat the change.
not_found 404 read_pending_action named a pending action that is not yours, or read_export or mint_download_grant an export the application does not have. mint_download_grant also returns it where the export's files are gone: a later export replaced them, or they were deleted. Use the id the destructive call returned, or the export id request_export returned. Where the files are gone, call request_export again and download the new export.
no_such_application 404 request_export, read_export, or mint_download_grant named an application that is not your account's. Use an application id list_applications returns.
export_not_completed 409 mint_download_grant named an export that is still running, or one that failed. For a running export, call read_export until its state is completed, then call mint_download_grant again. For a failed one, call request_export again and use the new export's id.
transfer_grant_expired 403 The download grant expired, five minutes after minting by default, before the line read every file. The line ends with status 2 where it had read a file. It ends with status 3, with nothing written, where the grant had expired before its first read. Call mint_download_grant again with the same local_path and run the new line. It skips the files already on disk.
transfer_grant_not_admitted 403 The download grant was used for something other than reading a named file of its export or its application, such as a listing. A line run as the call returned it can also be refused by this name on a stored file. Run the line as the call returned it. Where that line was refused on a stored file, call mint_download_grant again and run the new line. For any other request, use your signed-in session or a minted token.
no_such_file 404 Under the download grant, a stored file was read that was created after the export listed its files: one deleted and stored again after the export. The line counts it as a failed file. Under the grant of an export made before the release that introduced this rule, every stored file the manifest lists returns it. A name with no file returns the same refusal. Call request_export again and download the new export, which has the application's files as they now stand.
destructive_class_required 403 delete_account was called under a minted token with no destructive grant. No pending action was created. Ask from your signed-in session, or from a token minted with the destructive grant. A person still approves in a browser.
approval_expired 409 The pending action expired before the browser approved or declined it; expires_at gives the time. Request the action again and approve the new record before it expires.
approval_wrong_account 403 The approving browser is signed in to a different account from the one that asked. Sign in to the account that asked, then open the approval link again.
description_changed none At approval, the platform's new description of what would be deleted differed from the one you approved. The record ends declined, and nothing ran. Request the action again and approve its current description.
execution_failed none The deletion failed partway with an error that has no refusal name. The outcome identifies the part that failed, a reference to the platform's record of the error, and what was removed before it. Read the outcome and the current state, then request the action again. Any request_id, or none, starts a new pending action.
interrupted none The deletion ran for more than thirty minutes without finishing and was marked failed. Check the current state before you request and approve another attempt, because some parts may already be removed.