> For the index of every page in Orbital's docs, read https://docs.beta.runorbital.dev/llms.txt.

# The orbital command

> Every orbital subcommand with its options, an example and its exit codes, plus environment variables and data files

Use the `orbital` command to run Orbital's server, open it in a window, validate workflows, start runs, change settings and install the bundled skills. Run it with no arguments to print its help:

```sh
orbital
```

Every subcommand takes `--version`, which prints the version the command is running and exits with 0. `orbital --version` does the same.

A usage error, such as an unknown flag or a missing required flag, prints the problem and the help, and exits with 2.

## Install the command from the desktop app

The macOS app carries the `orbital` command. To use it in a terminal, do one of these:

- Open **Settings > Command line and skills** and choose **Install**.
- Choose **Orbital > Install Command Line Tool**.

Both link `/usr/local/bin/orbital` to the command inside the app. The app asks for an administrator password only when that folder needs one. After the app updates, the command runs the new release without being installed again.

## orbital serve

Runs the server and the browser app on one port.

```text
orbital serve [--bind <address>] [--port <port>] [--open | --no-open]
```

It prints its address and opens it in your browser. It reads nothing from the directory you start it in.

| Flag | What it does | Default |
| --- | --- | --- |
| `--bind <address>` | address to bind | `127.0.0.1` |
| `--port <port>` | port to bind (default 42121, or "port" in the config file; 0 takes a free one) | `42121`, or `port` in `~/.orbital/config.json` |
| `--open` | open the browser once the server is bound (default) | On |
| `--no-open` | leave the browser closed, as setting ORBITAL_NO_OPEN does | Off |
| `--version` | print the version this command is running and exit | |

A server whose output is redirected never opens a browser. The address it opens is always the loopback one, whatever `--bind` says.

The API of `orbital serve` has no secret. When you bind it to a network address, protecting that network is up to you. [HTTP API](/reference/http-api/) describes which requests the server refuses.

Example:

```sh
orbital serve --port 0 --no-open
```

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | The server stopped. |
| 1 | The server could not start. For example, the port is taken or `run-history.db` cannot be opened. The message says why. |
| 2 | Usage error. |

When the port is taken, the message suggests `--port <port>`, the `port` key in `~/.orbital/config.json`, or `--port 0`.

## orbital app

Opens Orbital in a window that runs its own server.

```text
orbital app [--bind <address>] [--port <port>]
```

Closing the window stops the server.

The window makes a new secret at each start. Its server refuses any request without that secret, so only the window, and scripts that read the secret from `~/.orbital/server.json`, can use it. The first start downloads the Electron runtime once, about 110 MB.

| Flag | What it does | Default |
| --- | --- | --- |
| `--bind <address>` | address the window's server binds | `127.0.0.1` |
| `--port <port>` | port the window's server binds (default: a free one) | A free port |
| `--version` | print the version this command is running and exit | |

Example:

```sh
orbital app
```

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | The window closed normally. |
| 1 | The window could not open. The message says why and nothing is left running. `orbital serve` still works in a browser. |
| 2 | Usage error. |

Otherwise the command exits with the code the window's process exited with.

## orbital validate

Checks a workflow without running it.

```text
orbital validate [workflow]
```

It starts neither the server nor an agent.

The argument is a workflow name or a path. A name is looked up the way the server looks it up, with the folder you run the command from as the project folder. With no argument, the command checks the default workflow set in **Settings > General**.

A valid workflow prints `Workflow <path> is valid.` Each warning is printed first, on its own line, starting with `warning:`.

| Flag | What it does | Default |
| --- | --- | --- |
| `[workflow]` | workflow name or path | The default workflow |
| `--version` | print the version this command is running and exit | |

Examples:

```sh
orbital validate implement-ticket
orbital validate /absolute/path/to/workflow.dot
```

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | The workflow is valid. Warnings do not change this. |
| 1 | The workflow was not found or is not valid. The message names the problem. |
| 2 | Usage error. |

## orbital run start

Queues a run on the server running on this machine, the desktop app's or `orbital serve`'s.

```text
orbital run start --project <id> [--workflow <name>] [--input <name=value>]... [--goal <text>] [--title <text>] [--harness <name>] [--server <url>]
```

It prints the run's id and then the address of its page.

The command reads the server's address and secret from `~/.orbital/server.json`, so it works with the desktop app with no extra flags. The run queues like any other run. It starts when a slot is free, under the cap in **Settings > General**.

| Flag | What it does | Default |
| --- | --- | --- |
| `--project <id>` | project the run works in (GET /api/projects lists them) | Required |
| `--workflow <name>` | workflow to run (default: the project's default workflow) | The project's default workflow |
| `--input <name=value>` | value for one of the workflow's inputs; repeat for more | None |
| `--goal <text>` | goal for the run (default: the title, else the first input) | The title, else the first input |
| `--title <text>` | title the run is listed under, instead of a generated one | A generated title |
| `--harness <name>` | harness to run with: claude, codex, opencode | The workflow's choice |
| `--server <url>` | server to start the run on, instead of the one ~/.orbital/server.json names; ORBITAL_URL does the same | The server `~/.orbital/server.json` names |
| `--version` | print the version this command is running and exit | |

A run needs a goal. Without `--goal`, `--title` or an `--input`, the command refuses.

For a server on another host, give its address with `--server` or `ORBITAL_URL`, and its secret with `ORBITAL_TOKEN`. The secret in `~/.orbital/server.json` is never sent to a server that the file does not name.

Example:

```sh
orbital run start --workflow implement-ticket --project proj_r3tQMqBPBB5p \
  --input ticket_url=https://linear.app/acme/issue/IE-3770 --title "Pay invoices from the portal"
```

It prints:

```text
2026-09-24-npn6fk
http://127.0.0.1:52011/runs/2026-09-24-npn6fk/workflow
```

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | The run was queued. |
| 1 | No run was started. The message says why: no server is running, `~/.orbital/server.json` was left by a server that stopped, the server wants a secret (set `ORBITAL_TOKEN`), or the server refused the run. |
| 2 | Usage error, such as a missing `--project` or an `--input` without `=`. |

## orbital settings set

Changes one setting on the server running on this machine, the desktop app's or `orbital serve`'s.

```text
orbital settings set <setting> <value> [--server <url>]
```

It finds the server the way [`orbital run start`](#orbital-run-start) does. **Settings > [Recent changes](/reference/settings/#recent-changes)** lists the change with the command's words as its source.

| Setting | Value |
| --- | --- |
| `runs-at-once` | How many runs run at once: a whole number of 1 or more, or `default`. |
| `supervisor-feature` | `on` or `off`. |
| `triggers-feature` | `on` or `off`. |
| `accounts-feature` | `on` or `off`. Only a development build offers it. |

| Flag | What it does | Default |
| --- | --- | --- |
| `--server <url>` | server to change, instead of the one ~/.orbital/server.json names; ORBITAL_URL does the same | The server `~/.orbital/server.json` names |
| `--version` | print the version this command is running and exit | |

Example:

```sh
orbital settings set runs-at-once 4
```

It prints:

```text
Set runs-at-once to 4 on http://127.0.0.1:52011/.
```

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | The setting was changed. |
| 1 | Nothing was changed. The message says why: the setting or value is not one the command knows, no server is running, the server wants a secret (set `ORBITAL_TOKEN`), or the server refused the value. |
| 2 | Usage error, such as a missing value. |

## orbital skill install

Installs every skill that ships with Orbital, for agents and for Claude.

```text
orbital skill install [--replace <name>]...
```

It installs these skills:

- `orbital-create-workflow` designs Orbital workflows.
- `orbital-delivery-lead` delivers tickets through Orbital runs.

Each skill is copied to `~/.agents/skills/<name>` and linked from `~/.claude/skills/<name>`.

The command prints one line for each skill:

| Line | Meaning |
| --- | --- |
| `Installed <name>.` | The skill was not installed before, and now is. |
| `Updated <name> to the version this release ships.` | An earlier release installed the skill and nobody changed it since. The command replaced it. |
| `<name> is already up to date.` | Nothing changed. |
| `Kept <name>: <path> differs from the bundled skill and was not changed.` | Someone changed the installed copy or link. The command left it as it is. The line suggests `--replace`. |
| `Replaced <name> with the bundled skill; the old one is now <backup>.` | `--replace` moved the old copy aside and installed the bundled one. |
| `Could not install <name>: <reason>` | The skill failed. The other skills still install. |

`--replace <name>` moves the installed copy or link aside as a dated backup and installs the bundled skill. Backups go to `~/.agents/skill-backups` for a copy and `~/.claude/skill-backups` for a link.

When an earlier release installed a skill under a name Orbital no longer uses, the command removes that old copy once the new skill is in place, unless someone changed it; a changed copy is kept and reported.

| Flag | What it does | Default |
| --- | --- | --- |
| `--replace <name>` | move the installed copy of this skill aside as a dated backup and install the bundled one; repeat for more | None |

**Settings > Command line and skills** in the app shows each skill's state and installs, updates or replaces it the same way.

Example:

```sh
orbital skill install --replace orbital-delivery-lead
```

Exit codes:

| Code | Meaning |
| --- | --- |
| 0 | Every skill is installed, updated, up to date, replaced or kept. |
| 1 | At least one skill could not be installed, or `--replace` named a skill Orbital does not ship. In the second case nothing is installed. |
| 2 | Usage error. |

## Environment variables

| Variable | What it does |
| --- | --- |
| `ORBITAL_HOME` | Takes the place of your home directory for Orbital's data. The data directory becomes `$ORBITAL_HOME/.orbital`. Skills still install under your own home directory. |
| `ORBITAL_NO_OPEN` | When set, `orbital serve` leaves the browser closed, as `--no-open` does. |
| `ORBITAL_URL` | The server `orbital run start` uses, as `--server` does. `--server` wins when both are given. |
| `ORBITAL_TOKEN` | The secret `orbital run start` sends. It replaces the secret in `~/.orbital/server.json`, and it is the only secret sent to a server that file does not name. |
| `OPENROUTER_API_KEY` | Lets OpenCode use OpenRouter models. Export it in the shell that starts the server. A server that was already running does not see a later export, so restart it. |

The server sets `ORBITAL_HOME` to `~/.orbital/turn-home` for every agent it starts. An `orbital` command an agent runs then uses its own data, not yours.

## Where Orbital keeps its data

Orbital keeps its data in `~/.orbital`, or in `$ORBITAL_HOME/.orbital` when `ORBITAL_HOME` is set.

| Path | Holds |
| --- | --- |
| `run-history.db` | Every run's progress and transcript, the settings change record, and the GitHub token and Linear key. |
| `config.json` | Settings. |
| `server.json` | Where the running server listens, and a window's secret. Only you can read it. The server removes it when it stops. |
| `mcp-token` | The MCP endpoint's bearer token. Only you can read it. |
| `workflows/` | Your workflow library. |
| `exports/` | Run exports written by the MCP tool `export_run`. |
| `attachments/` | Files attached in chats. |
| `supervisor/` | The folder the Supervisor's chats work in. |
| `worktrees/` | The worktrees runs work in. |
| `turn-home/` | The data directory of the agents Orbital starts. |
| `logs/server/orbital.log` | The server's log. The desktop app's **Help > Show Logs** opens its folder. |

The first start after an upgrade updates `run-history.db`. An older release refuses to open the file once a newer one has updated it. To go back to an older release, move `run-history.db` aside rather than deleting it.

## Related

- [Command line](/command-line/): when to use each subcommand, with worked examples
- [Settings](/reference/settings/): every setting, and the settings file the command changes
- [HTTP API](/reference/http-api/): call the running server from a script
- [Use the shipped skills](/mcp/skills/): what the skills `orbital skill install` installs do
