---
title: The turnzero command
description: The command your AI tool runs on your machine to deploy, store a secret, run locally, and start a service: its lines, a deploy, and how a line ends.
slug: /concepts/turnzero-command
order: 15
visibility: public
redirects_from: [/getting-started/the-provisioning-script, /concepts/the-turnzero-cloud-command, /concepts/turnzero-cloud-command, /concepts/the-turnzero-command, /guides/deploying-unattended]
---

# The turnzero command

The turnzero command is a small program that your AI tool runs on your machine, for work that needs your files or your processes. A deploy zips your folder with it, and a local run starts your application with it. Your tool gets almost every line it runs from a tool call's answer.

You install nothing yourself. `npx`, which comes with Node.js, fetches the command, the package `turnzero`, from the public npm registry and runs it. A line names the package by its platform's tag: `turnzero@latest` on `https://turnzero.ai`, and `turnzero@next` on Turn Zero's development platform. Each run looks the tag up again, unless your npm configuration prefers its cache, so a line runs the version the tag names then.

## The lines your tool runs

| Line | Where it comes from | What it does |
| --- | --- | --- |
| `deploy` | The `deploy` call's `command`, or `command_windows` on Windows | Zips the folder it runs in, uploads the zip, starts the deploy, and waits for the outcome ([A deploy, from call to outcome](#a-deploy-from-call-to-outcome)). |
| `check` | The `check_deploy` call's `command` | Runs a deploy's checks of the application and the zip, and uploads nothing ([Checking a deploy](#checking-a-deploy)). |
| `authorize` | You write the first; the `mint_token` call returns the second | Authorizes this computer for deploys, once for each platform address ([Connect Claude Code or Codex](/getting-started/connect-your-tool#authorize-this-computer-for-deploys)). |
| `secret store`, `secret rotate` | The `store_secret` or `rotate_secret` call that names no value | Reads the value from a file or a hidden prompt on your machine and stores it, so the value never passes through your tool ([Supply a secret value without exposing it](/guides/supply-a-secret-value-without-exposing-it)). |
| `provision`, `run` | The `submit_manifest` call that names `local_run: true` returns `provision`; you write `run` | `provision` writes the settings a local run needs into `.env`, and `run` starts your application with them ([Running on your machine](#running-on-your-machine)). |
| `scaffold` | You write it | Writes a new service from a template into your project and tests it ([Starting a new service](#starting-a-new-service)). |
| `library take` | The `read_library_entry` call's `download` | Takes one library entry into your project ([Use the library](/guides/use-the-library#3-add-an-entry-to-the-library-folder)). |

Your tool runs each line once, as given: `command` on macOS and Linux, `command_windows` on Windows. [Running and writing lines](#running-and-writing-lines) gives the rarer lines and how to write one yourself.

## A deploy, from call to outcome

Your tool calls `deploy` with the application and nothing else, as [The deploy in one pass](/getting-started/deploy-an-application#the-deploy-in-one-pass) shows. The answer's `command` is the line. For the application `3f6c2a1e-8d4b-4c7a-9e21-5b0f7d9c4a13`, on macOS and Linux, it is this. A test checks this line against the one the platform composes.

```text
npx -y turnzero@latest deploy --application 3f6c2a1e-8d4b-4c7a-9e21-5b0f7d9c4a13
```

That is `command`. `command_windows` is the same line with `npx.cmd` for `npx`. The line contains no credential, and the command reads nothing on its input. It also has `--path` where the call named `local_path`, `--origin` where the platform is at another address, and `--rotate-database-credential` where the call named `rotate_database_credential`.

Your tool runs the line once, from the application's folder. For the hello-world service of a new application, the command prints these lines and ends with status 0. A test runs a deploy over the platform and checks this sample against what the command prints.

```text
zip: 8 files from /home/you/hello-world/app, 2731 bytes, sha256: <64 hexadecimal characters>
files: .gitignore, AGENTS.md, manifest.json, package-lock.json, package.json, src/, test/. The hash subcommand with --list names every file the zip holds.
prepared: upload 9b1e4c2a-6f3d-4e8b-a7c5-2d0f8e6b4a19 to production, its grant expiring at 2026-10-10T12:05:00.000Z
uploaded: 2731 bytes as upload 9b1e4c2a-6f3d-4e8b-a7c5-2d0f8e6b4a19
started: {"contract_version":1,"summary":"Production is deploying version 1 (a deploy), in step pending_candidates, 0 seconds since it started; no version serves.","application":"3f6c2a1e-8d4b-4c7a-9e21-5b0f7d9c4a13","environment":"production","version":1,"state":"deploying","hostname":"hello-world-7k2m9q.ai.host","health_path":"/health",...}
step: pending_candidates at 0s
step: image_build at 1s, pending_candidates took 1s
step: slot_guard at 62s, image_build took 61s
step: platform_credential at 63s, slot_guard took 1s
step: declarations at 64s, platform_credential took 1s
step: realm_keys at 64s, declarations took 0s
step: pull_identity at 65s, realm_keys took 1s
step: compute_apply at 66s, pull_identity took 1s
step: shell_assets at 104s, compute_apply took 38s
step: health_gate at 105s, shell_assets took 1s
step: finish at 121s, health_gate took 16s
settled: deployed version 1
checked: the health check requested the health path alone; request the other routes you rely on and read read_logs for errors.
read_status with application 3f6c2a1e-8d4b-4c7a-9e21-5b0f7d9c4a13 and environment production reads the row's outcome, with the health gate's evidence or the build's last lines where the row failed at either; read_logs reads the console.
```

Read the lines this way:

- `zip:` and `files:` say what went up; [What the deploy zip holds](/concepts/what-the-deploy-zip-holds) says what is left out.
- `prepared:` names the environment the platform chose, before anything is sent.
- `started:`, shortened here, is the platform's whole answer to the start, with the hostname and the health path the check requests.
- `settled:` gives the outcome. `checked:` says the check requested the health path alone, so your tool requests its other routes and reads `read_logs` for errors.
- The last line gives the `read_status` call, which returns the whole record.

A failed deploy prints `settled: failed at <step>: <error>`, such as `settled: failed at health_gate: health_gate_failed`, then the platform's reading of the likely cause and the health check's facts. Your tool makes the `read_status` call the last line gives, and reads `read_logs` for the application's own lines ([Deploys](/troubleshooting/deploys)).

A deploy usually ends within four minutes. Allow the line fifteen minutes and the upload's time, or run it as a background job ([What it prints](/concepts/what-the-turnzero-command-reads-and-prints#what-it-prints)).

## How it ends

| Status | Means | Next, after `deploy` or `check` |
| --- | --- | --- |
| 0 | Done. | After `deploy`, the version serves; with `TURNZERO_DEPLOY_NO_WAIT` set, `read_status` shows the outcome. After `check`, deploy. |
| 1 | It ran and failed. | After `deploy`, make the `read_status` call the last line gives. After `check`, clear each `refused:` line and run the check again. |
| 2 | The outcome is unknown. | After `deploy`, the deploy may still be running: call `read_status` with its wait, as the last line says. |
| 3 | Nothing was started. | Make the call the printed refusal or sentence gives, usually the same line again. With no credential, the two routes it printed say how to get one. |

The [turnzero command reference](/reference/turnzero-command) gives each status under every subcommand.

## Running and writing lines

Five other lines are rarer. `put` uploads one file under the line `mint_upload_grant` returns ([Store files](/guides/store-files#an-upload-grant-from-your-tool)). `export download` downloads an export under the line `mint_download_grant` returns ([Download the export](/guides/export-or-delete-your-account#download-the-export)). `token request` and `token claim` mint a token whose value never passes through your tool ([Mint a token](/guides/mint-a-token#1-mint-it)). `logout` ends this computer's authorization, and `hash` prints the hash of the zip a deploy would upload, uploading nothing.

The two forms of a returned line differ in one word, `npx.cmd` for `npx`, and each runs the same in every shell of its operating system. These pages show the lines of `https://turnzero.ai`, which run `turnzero@latest`. A line from Turn Zero's development platform runs `turnzero@next` and adds `--origin https://dev.turnzero.ai`, so the command calls that platform. Run each line as the answer gives it.

A grant is a short-lived credential for one action. Where a subcommand reads one, the tool call that asks for the action returns it, and a line pipes it to the command on its input. No line contains a token: [How the turnzero command finds its credential](/concepts/how-the-turnzero-command-finds-its-credential) says where the command reads each credential and who may run a line.

Every line a tool call returns runs the command by its platform's tag, as `deploy`'s `command` does, so no line names a version. To run one version again, write `turnzero@<version>` in place of the tag. A line you write yourself from these pages runs `turnzero@latest`. Where your tool reaches the platform at any address other than `https://turnzero.ai`, such as `https://dev.turnzero.ai`, write `turnzero@next` instead.

Every line you write for that address, except `hash` and `run`, also carries `--origin` with it. The origin chooses the platform `scaffold`, `library take`, and `token request` reach, the platform `authorize` keeps this computer's pending request for, and the entry `logout` removes. Then the lines the run prints name the same address as the lines your tool's calls return.

No tool call returns the `hash` line, so you write it yourself, in this form:

```text
npx -y turnzero@latest hash
```

`hash` reads what a deploy from the folder would upload, and sends nothing. No deploy needs it first. [What it prints](/concepts/what-the-turnzero-command-reads-and-prints#what-it-prints) gives its lines.

On Windows, write `npx.cmd` for `npx`, because Windows PowerShell refuses `npx` where running scripts is disabled, as [Prerequisites](/getting-started/prerequisites#windows-powershell) describes. `npx.cmd` runs in every Windows shell, and a line a tool call returns already has it in its Windows form.

Where npm cannot reach the registry, a line runs the copy in npm's cache after npm's retries, and without one npm ends with an error naming the address it could not read.

The registry is the one npm's configuration names, and a project's `.npmrc` in the folder a line runs in can name another, such as a mirror. The command from that registry then runs with this computer's credential file and any minted token in the line's environment in reach. So run a line only in a folder whose npm configuration you trust. Running `npm config get registry` in that folder shows the registry npm uses there.

The older package name `turnzero-cloud` on the public npm registry holds no command: run `turnzero`. A line that names a platform address in place of the package, such as the bare `https://turnzero.ai`, runs nothing either. The `404 Not Found` line npm then prints names the command's line, so your tool can run that line instead.

The command needs Node.js 24 or later. Under an older one, it prints one sentence naming the version it found and ends with status 3. After a line's result, npm may print a notice of its own, which Windows PowerShell shows as an error. [Setup](/troubleshooting/setup) covers both.

Where your tool's shell cannot reach the platform, as in claude.ai's chat, `deploy_files` deploys the folder's files from the conversation, with no command ([Deploying from a chat whose shell cannot reach the platform](/getting-started/deploy-an-application#deploying-from-a-chat-whose-shell-cannot-reach-the-platform)).

Your tool calls `read_library_entry` with the entry's name, and the response's `download` has the `library take` line in its two forms, `command` and `command_windows`. Where an answer carries no `download`, as on the HTTP route, the line is `npx -y turnzero@latest library take --entry <name>`, run at your project's root.

The [turnzero command reference](/reference/turnzero-command) lists every option each subcommand takes.

## Checking a deploy

`check` says what a deploy would refuse, before you make it, and uploads nothing. [Checking a deploy before you make it](/getting-started/deploy-an-application#checking-a-deploy-before-you-make-it) gives the call, its answer, and the zip's checks.

The line is the deploy line with `check` in place of `deploy`: `npx -y turnzero@<tag> check --application <application id>`, with `--path` where the call named `local_path` and `--origin` off `https://turnzero.ai`. It names no environment, checking the one the platform would deploy to, and carries no credential. `check` reads its credential and builds its zip as `deploy` does. A tool runs only a check line its own `check_deploy` call returned, or one it wrote for its folder.

`check` prints its `zip:` line and makes one `check_deploy` call under the token, naming the application alone, so no byte of the zip and no hash leaves your machine. The call follows no redirect, ends after sixty seconds, and is never made twice. It prints one `refused:` line per refusal and a last `checked:` line, which [What it prints](/concepts/what-the-turnzero-command-reads-and-prints#what-it-prints) lists with the rest.

## Deploying unattended

An AI tool connected by a minted token rather than a sign-in, and a job with no AI tool, such as a CI job, run the same deploy line under a minted token. Each sets `TURNZERO_CLOUD_MINTED_TOKEN` from where the token is kept, never by writing the value in a line, and off `https://turnzero.ai` sets `TURNZERO_CLOUD_ORIGIN` to the platform's address. [A minted token in the environment](/concepts/how-the-turnzero-command-finds-its-credential#a-minted-token-in-the-environment) says how the command reads and sends it. [Mint it](/guides/mint-a-token#1-mint-it) shows the three moves, with the line piped into GitHub's secret store.

The unattended line is the deploy line itself: `npx -y turnzero@<tag> deploy --application <application id>`. Add `--env <environment>` to choose the environment, which the platform otherwise chooses. A job has no tool call to return the line, so on Windows it writes the line with `npx.cmd` for `npx`. The command reads nothing on its input, so the job need not close it.

### Setting the variable for one line

A tool sets `TURNZERO_CLOUD_MINTED_TOKEN` for the deploy or check line alone and unsets it once the line ends. So no later line in the tool's shell runs under the token. A job's variable is its step's own, so a job needs no such form.

The value comes from where the token is kept, such as a variable your tool names or a file read inside the line. The line never writes the value out. A variable that is set but empty, or holds only spaces, is refused: the line ends with status 3 and sends nothing. PowerShell removes a variable it is given an empty value, so its forms below check the read before the line runs. Off `https://turnzero.ai`, set `TURNZERO_CLOUD_ORIGIN` the same way, beside the token, for the line alone. Once the line ends, it holds what it held before.

In bash and zsh, the assignment stands before the command, on the same line, and lasts for that command alone. Here the token is read from a file:

```bash
TURNZERO_CLOUD_MINTED_TOKEN="$(cat <token file>)" npx -y turnzero@latest deploy --application <application id>
```

In PowerShell, the assignment, a check that the read found a token, and the line stand in a `try`, and the variable's removal in its `finally`. So an empty token file stops the line before it runs, and the variable is removed even where the line fails:

```powershell
try { $env:TURNZERO_CLOUD_MINTED_TOKEN = Get-Content -Raw -ErrorAction Stop <token file>; if (-not $env:TURNZERO_CLOUD_MINTED_TOKEN) { throw 'The token file is empty, so the line did not run.' }; npx.cmd -y turnzero@latest deploy --application <application id> } finally { Remove-Item Env:TURNZERO_CLOUD_MINTED_TOKEN -ErrorAction SilentlyContinue }
```

In cmd.exe, as a tool passes a line to `cmd.exe /c`, the assignment stands before the command with no quote around it, and `&&` follows the value with no space. The variable lasts for that `cmd.exe` alone, so run this form through `cmd.exe /c`, or run the line from bash or PowerShell. A quote there, passed as a tool's runtime passes it, sets a variable of another name and leaves `TURNZERO_CLOUD_MINTED_TOKEN` unset. Here the token is read from a variable your tool names:

```bat
set TURNZERO_CLOUD_MINTED_TOKEN=%<variable your tool names>%&& npx.cmd -y turnzero@latest deploy --application <application id>
```

Here are the bash and PowerShell forms off `https://turnzero.ai`, with the platform at `https://dev.turnzero.ai`. Each sets `TURNZERO_CLOUD_ORIGIN` beside the token for the line alone. The PowerShell form keeps the variable's earlier value and puts it back in its `finally`, which removes the variable where it was not set:

```bash
TURNZERO_CLOUD_MINTED_TOKEN="$(cat <token file>)" TURNZERO_CLOUD_ORIGIN=https://dev.turnzero.ai npx -y turnzero@next deploy --application <application id> --origin https://dev.turnzero.ai
```

```powershell
$heldOrigin = $env:TURNZERO_CLOUD_ORIGIN; try { $env:TURNZERO_CLOUD_MINTED_TOKEN = Get-Content -Raw -ErrorAction Stop <token file>; $env:TURNZERO_CLOUD_ORIGIN = 'https://dev.turnzero.ai'; if (-not $env:TURNZERO_CLOUD_MINTED_TOKEN) { throw 'The token file is empty, so the line did not run.' }; npx.cmd -y turnzero@next deploy --application <application id> --origin https://dev.turnzero.ai } finally { Remove-Item Env:TURNZERO_CLOUD_MINTED_TOKEN -ErrorAction SilentlyContinue; $env:TURNZERO_CLOUD_ORIGIN = $heldOrigin }
```

A shell with no form here runs the deploy line from bash, PowerShell, or cmd.exe instead.

## Running on your machine

[Run your application on your machine](/guides/run-your-application-on-your-machine) is the procedure for a local run, and [its step 2](/guides/run-your-application-on-your-machine#2-read-the-settings-the-file-holds) lists the seven settings the provision line writes. This section describes the command's part in it: `provision`, which writes the environment file, and `run`, which starts the application with it. [The environment file](/concepts/what-the-turnzero-command-reads-and-prints#the-environment-file) gives the forms `run` reads and how `provision` writes the file.

### The provision line

`provision` writes the settings a local run needs into `.env`, the environment file in the folder it runs in. It re-mints the application's development platform credential, and its development database credential where the application has a development database. An existing file keeps every line the command does not set and its permission mode, and `provision` writes no `PORT`.

[Write the environment file](/guides/run-your-application-on-your-machine#1-write-the-environment-file) gives the call that returns the line, the line's form, and its [secret grant](/concepts/glossary#secret-grant)'s fifteen minutes. The grant re-mints each of the two development credentials once. Where a re-mint landed, a second run of the same line is normally refused `secret_grant_spent` and changes nothing. For a new line, call `submit_manifest` again with the application, its manifest, and `local_run`. Each such call returns a new line.

With a development database, the command writes seven settings. Without one, the platform answers the database request `not_found`, which uses nothing of the grant, and the command writes the other five.

In an unattended run, set `TURNZERO_CLOUD_MINTED_TOKEN` to a token minted for the application, pipe no grant, and name `--application <application id>`. The platform refuses the application's own `TURNZERO_CLOUD_TOKEN` for this work, and the token goes only where [The address a credential goes to](/concepts/how-the-turnzero-command-finds-its-credential#the-address-a-credential-goes-to) allows.

`provision` writes the platform's settings alone, so a setting your manifest binds to a stored secret gets its local value from you, as [Read the settings the file holds](/guides/run-your-application-on-your-machine#2-read-the-settings-the-file-holds) says. Run under the line's grant, `provision` prints a line naming each one.

Each run revokes the development credentials the application had before it. A deployed development environment holds the revoked values until it restarts, so the line's last re-mint restarts it. Its redeploy takes both re-minted credentials from custody, the connection string and the platform credential, and spends no deploy of the day. Where a deploy of development is still in flight, the re-mint's answer names `restart_application` on development instead, and you call it once that deploy ends.

### The run line

`run` starts your application as the platform starts it, with `npm start` in the folder it runs in or the folder `--path` names. The application receives your shell's environment with every setting of the environment file laid over it, and the file wins where both set the same setting. `--port` sets `PORT`. The command leaves `TURNZERO_CLOUD_MINTED_TOKEN` and `TURNZERO_CLOUD_UPLOAD_GRANT` out of what the application receives. It reads no credential and sends no request.

The command also leaves out `npm_config_yes` where it holds `true`, which npm sets for the line's `-y`. So an `npx` your application runs asks before it installs, as in your shell. An `npm_config_yes` line in `.env` still reaches the application.

`run` runs until the application ends, so a tool starts it as a background process and reads its lines. Its help says so, and so does its first line.

`npm start` passes on your shell's environment alone, so an application that reads a setting from `.env`, and loads no file in its own code, starts through `run`. Without `--port`, the application receives `PORT` only where `.env` or your shell sets it, and otherwise listens where its own code chooses.

A local run reads and writes the development database, where the application has one. A [migration](/concepts/glossary#migration) your application applies at a local start is recorded there, so the next deploy to development finds none pending. Production's database is separate, and the first start there applies them.

`run`'s port line, what it hides in the application's output, and how it ends on an interrupt are in [What the turnzero command reads and prints](/concepts/what-the-turnzero-command-reads-and-prints#what-it-prints).

## Starting a new service

`scaffold` writes a new service from a template into your project and tests it, so your tool starts from a working service. The line, in its macOS and Linux form:

```text
npx -y turnzero@latest scaffold
```

The command has three templates:

- `hello-world`, the smallest service that deploys, with a health route and one API route that answers hello world.
- `database-service`, a notes service that keeps its data in the platform's database, the service [Build a database-backed service](/getting-started/build-a-database-backed-service) shows file by file.
- `scheduled-job`, the `hello-world` service with one handler that the platform runs each hour through the [Schedule](/backend-packages/schedule) package.

A line that names no `--template` writes `hello-world`, so the shortest line writes the smallest service. To write another, add `--template` and its name, such as `--template database-service`. The default stays `hello-world`, so a line you use today keeps writing what it writes.

The command needs no credential. A `database-service` or `scheduled-job` run takes a package from the library, whose reads are open, and a `hello-world` run sends no request.

Run the line at your project's root, or name the root with `--path`, and the command makes that folder where it does not exist. On Windows, a path written into the line contains none of the characters `&`, `|`, `<`, `>`, `^`, and `%`: where your folder's path contains one, run the line from that folder without `--path`.

The command starts a new application and writes over none. Where your project's `app/` folder contains any file or folder, the command refuses and writes nothing. The command looks for an application nowhere else, so where yours is in another folder, the line writes a new, separate service into `app/`. The command has no option that overwrites, and it asks no question. It reads no other file in the root but `system.json`, and changes no file that exists there, a `package.json` included.

Under `database-service` and `scheduled-job`, the refusal's last line gives the `library take` line, which adds the template's package to the application you already have. That line also names the page to follow: the guide [Add a database](/guides/add-a-database) for the Database package, and the [Schedule package's page](/backend-packages/schedule#what-an-application-must-do) for the Schedule package.

Where the template takes a package, the command takes it as `library take` does, checking each file before it writes any. Where the root contains neither `system/` nor `system.json`, it makes a `system/` folder there. It writes the template's files into `app.scaffold` beside `app/` and renames that folder to `app/`. So `app/` contains the whole template or none of it. Where something else is at `app.scaffold`, such as an earlier run's files under another template, the command refuses, never removes it, and names the folder to move or remove. It then runs `npm install` and `npm test` in `app/`.

Under every template, the command composes `manifest.json` at the run. It fills that file's `packages` list with the name and version of each entry in your library folder, and leaves the list empty where your project holds no entry.

`app/AGENTS.md` tells an AI coding tool that the service runs on tzCloud (Turn Zero Cloud) and where the platform serves its rules. A tool started at your project's root reads the root's `AGENTS.md` first. So the command writes one there, only where the root has none, with one sentence: "The service in `app/` runs on Turn Zero Cloud: read `app/AGENTS.md` before you work on it."

Where the root already has an `AGENTS.md`, the command changes nothing there and prints a `not changed:` line with the sentence to add. Where the write fails, it prints a `write failed:` line with the same sentence. Where the root has a `CLAUDE.md`, it prints a `not changed:` line for that file: Claude Code reads it and then no `AGENTS.md` on its own, so add the sentence to it. The command reads neither file, and writes no `CLAUDE.md`.

`npm install` and `npm test` receive neither `TURNZERO_CLOUD_MINTED_TOKEN` nor `TURNZERO_CLOUD_UPLOAD_GRANT`. An interrupt reaches npm, the command ends after npm does, and after an interrupted install the tests are not started. A signal that arrives after the command's first write and before npm starts is acted on once the writes are made. The command then prints the way to continue, starts no npm, and ends with status 128 plus the signal's number.

After the tests pass, the command prints the template's next steps in order, starting with `create_application`, which your tool skips where it already created the new service's application. Where it printed a `not changed:` or a `write failed:` line, the steps begin with one step for each such line, which repeats the sentence to add. Each line it prints for the command names the run's tag, `--origin` off `https://turnzero.ai`, and `npx.cmd` on Windows. The `run` step says that the line runs until the application ends, so your tool starts it as a background process and reads its lines.

A new application has one environment, production, so the `deploy` step goes straight to production. The `deploy` call's answer says so before you run its line. To try each version on development first, call `create_environment` before you deploy, and follow its answer.

Where the install fails or the run stops, the last printed line gives one way to continue, by what is at `app`:

- Where the run moved the template in, run `npm install` and then `npm test` in `app/` after a `hello-world` run. After the other two, run the `library take` line the command prints, at your project's root, then `npm test` in `app/`.
- Where it did not, and `app/` does not exist or is empty, run the same line again.
- Where something that is not a folder, or that the command cannot read, is there, move it or make it readable, then run the same line again.
- Where `app/` contains files that are not the run's, an application already exists there. Under `database-service` and `scheduled-job`, the line gives the `library take` line, as the refusal of such a folder does. After a `hello-world` run, the line says that `scaffold` starts a new application and writes over none, and gives no line to run.

Where the tests fail, they failed on the files as written, before any edit of yours. The printed line then asks you to report it, and gives no line to run again. It names the package and the version the library served, or, after a `hello-world` run, the template and the command's version.

### The hello-world template

`hello-world` writes seven files into `app/`: `package.json`, `manifest.json`, `src/server.mjs`, `src/main.mjs`, `test/hello.test.mjs`, `.gitignore`, and `AGENTS.md`. The server answers `GET /health` with status 200 and `{"ok":true}`, and `GET /api/hello` with status 200 and the plain text `hello world`. It answers any other request with status 404 and `{"error":"not_found"}`, and listens on the port in `PORT`, or on 8080 where `PORT` is not set.

The route sits under `/api/` so that it stays your application's own if you later add a web client, whose files the platform serves at `/`. The manifest declares no service, and the package file declares no dependency. A `hello-world` run ends with four next steps: `create_application`; `submit_manifest` with `app/manifest.json`, naming no `local_run`, because the service reads no setting; the `run` line; and `deploy`.

### The database-service template

`database-service` is the notes service that [Build a database-backed service](/getting-started/build-a-database-backed-service) shows file by file, written by the line with `--template database-service`.

The files in `app/` are `package.json`, `manifest.json`, `migrations/0001_notes.sql`, `src/db.mjs`, `src/server.mjs`, `src/main.mjs`, `test/notes.test.mjs`, `.gitignore`, and `AGENTS.md`.

To keep a resource other than notes, add `--resource` with its plural, the word of the table and the route, such as `--resource orders`. `--singular` names the singular, which is otherwise the plural without its closing `s`, so a plural that does not end in `s` needs it: `--resource people --singular person`. The command then writes the same files with the resource's names in place of notes, note, Notes, and Note. The [turnzero command reference](/reference/turnzero-command#scaffold) gives each name's form.

Where a name is outside its form, the plural is `s` alone, or `--singular` comes without `--resource`, the line writes nothing and ends with status 3.

To start from your own columns, add `--fields` with a list of fields separated by commas, each a name, a colon, and a kind: `--fields "name:text,message:text"`. The command then writes the migration, the data layer, the routes, and the tests under those columns, in place of the one `title` column. Write the list between double quotes, because PowerShell reads a bare comma as splitting an argument.

A name is a lower-case ASCII letter, then lower-case ASCII letters, digits, and underscores, at most 30 characters, and never `id`, the key the migration writes. The kinds are `text`, which refuses an empty string, `integer`, `boolean`, and `timestamp`. Every column is required, so `POST` answers status 400 to a body that lacks a field, or whose value the database refuses for its kind. A list holds from one to twenty fields, no two under one name.

A field may share a name with the resource, as `message` beside `--resource messages` does: the command writes the fields after the resource's names, so the field stays a column.

The command gives no column a default. A column the database fills itself, such as an insert time, goes into the migration by hand, outside `--fields`: for example `created_at timestamptz NOT NULL DEFAULT now()`. Add it before the service's first start, since a migration file never changes once a start has applied it, and read it in a query of your own.

A `database-service` run ends with five next steps: `create_application`; `submit_manifest` with `app/manifest.json`, naming `local_run`, and the `provision` line its answer gives; the `run` line; a step to shape the service; and `deploy`. The shaping step comes before the first deploy and makes the service your own: the table and its migration, the routes, and the tests.

### The scheduled-job template

`scheduled-job` is written by the line with `--template scheduled-job`. It writes eight files into `app/`: `package.json`, `manifest.json`, `src/server.mjs`, `src/main.mjs`, `src/jobs.mjs`, `test/job.test.mjs`, `.gitignore`, and `AGENTS.md`. The run copies the Schedule package's compiled code into `app/lib/schedule/`, which the package file declares as `file:lib/schedule`.

The server answers `GET /health` and `GET /api/hello` as `hello-world`'s does. Ahead of those routes, the Schedule package's router answers the schedule's path, `/jobs/heartbeat`, and passes each [scheduled run](/concepts/glossary#scheduled-run-and-due-instant) to the handler in `src/jobs.mjs`. A request to that path without the platform's headers gets status 404 and the error `scheduled_handler_only`. Where the manifest and the handlers do not match, the router stops the service as it starts.

The manifest declares one schedule, `heartbeat`, due once an hour, at the minute of the hour, in UTC, at which you ran the line. So services written from this template are not all due at the same moment. The cron expression is yours to change to any timetable your plan's shortest interval allows.

The handler prints one line naming the schedule and the run's key, such as `schedule heartbeat ran, key heartbeat@2026-01-01T09:00:00.000Z`, which is safe to repeat. A handler whose effect must not repeat records the key first, as [Schedule](/backend-packages/schedule) describes. The tests fire the handler through the package's [test double](/concepts/glossary#test-double), since no schedule fires on your machine.

A `scheduled-job` run ends with five next steps: the four of `hello-world`, whose `run` step also says that no schedule fires on your machine, and a fifth, `run_schedule`. That call fires the handler now and answers how the run ended. [Confirm it runs](/guides/add-a-scheduled-job#4-confirm-it-runs) says how to read that answer and its lines.

### Where you meant another template

A line that names no `--template` prints a `template:` line before the files, saying it wrote `hello-world`. Where you meant another template, remove the `app/` folder that run wrote, and the root's `AGENTS.md` where the run printed `written: AGENTS.md`. Then run the line again with `--template` and the name you meant, leaving `system/` as it is, since the next run uses it. Do not follow the refusal a second run prints while `app/` still holds the `hello-world` files. Its `library take` line would add the package to the `hello-world` service rather than write the template you meant.

## Related

- [Deploy an application](/getting-started/deploy-an-application) runs the deploy line from its call to the release check.
- [What the turnzero command reads and prints](/concepts/what-the-turnzero-command-reads-and-prints) gives what each line reads and prints, beyond the common case.
- [turnzero command reference](/reference/turnzero-command) gives each subcommand's usage line, its options, and the statuses it ends with.
- [How the turnzero command finds its credential](/concepts/how-the-turnzero-command-finds-its-credential) says where each line's credential comes from.
- [Run your application on your machine](/guides/run-your-application-on-your-machine) runs `provision` and `run`.
- [Connect Claude Code or Codex](/getting-started/connect-your-tool) authorizes this computer.
- [Supply a secret value without exposing it](/guides/supply-a-secret-value-without-exposing-it) runs the `secret` line.
- [Mint a token](/guides/mint-a-token) mints a CI job's token.
- [Store files](/guides/store-files) runs the `put` line, and [Export or delete your account](/guides/export-or-delete-your-account) the `export download` line.
- [Use the library](/guides/use-the-library) runs the `library take` line.
- [What your computer needs](/getting-started/prerequisites) checks Node.js and Windows PowerShell.
- [Deploys](/troubleshooting/deploys) starts from a line that was refused or ended early.
