# Getting started with the CLI

Source: https://cloud.synteq.com/docs/getting-started-with-the-cli
Updated: 2026-10-18T03:08:27.248094+00:00

---
# Getting started with the CLI

The Synteq CLI (`synteq`) manages your account, servers, apps, and functions from a terminal. It uses the same API as the portal, and every command can print JSON for scripts.

## Install

Requires Node.js 20 or newer.

```
npm install -g synteq
synteq --version

```

Upgrade:

```
npm install -g synteq@latest

```

If your version is below the portal's minimum supported version, every command except `login`, `logout`, and `settings` exits with code 4 and an upgrade hint.

For shell completion (bash, zsh, PowerShell), run `synteq autocomplete` and follow the printed instructions.

## Sign in

```
synteq login

```

The CLI opens the portal in your browser and prints the URL and a code. Confirm the code in the portal.

```
synteq whoami    # name, email, role, active team, auth mode
synteq logout    # revoke the session and clear stored credentials

```

Credentials are stored in the OS keychain, or in a file readable only by you when no keychain is available. Config lives in `~/.config/synteq` (`%APPDATA%\synteq` on Windows).

## Sign in with an API key

API keys run server, storage, order, and billing commands. They do not run Apps or Functions commands. Create a key in the portal first (see Creating an API key).

```
echo "$SYNTEQ_API_KEY" | synteq login --with-token

```

`--with-token` validates and stores the key. With nothing piped, it prompts with masked input. To use a key without storing it:

```
export SYNTEQ_API_TOKEN=sk_...
synteq vps list

```

A command outside the key's scopes fails and names the missing scope. Apps, Functions, `whoami`, `link`, `status`, and the TUI fail with "is a session-only command and cannot be run with an API key"; run `synteq login` without `--with-token` for a session.

## Choose a team and project

Commands act on the active team (your portal organization) and its default project.

```
synteq team            # show the active team
synteq team --list     # list your teams
synteq team acme       # switch by name substring or id prefix
synteq team --pick     # interactive picker
synteq projects        # list projects in the active team
synteq config          # active profile, team, project, and user

```

Connection profiles keep a separate login per API URL. `SYNTEQ_PROFILE` overrides the active profile for one shell.

```
synteq config profile add staging https://api.staging.cloud.synteq.com
synteq config profile use staging
synteq config profile use default

```

## Link a directory

Linking maps a directory and its subdirectories to one app, so app commands don't need `--app`.

```
synteq link

```

The walkthrough picks a team, project, and app, or creates an app (name, `<slug>.synteq.app` domain, plan, location). Environment variables and GitHub are optional steps; see Deploying and configuring an app.

Without prompts:

```
synteq link --app my-api
synteq link --app my-api --project 019e... --no-interactive

```

`synteq status` shows the linked app and its latest build. `synteq link --remove` removes the link.

## Deploy an app

```
synteq deploy

```

The CLI uploads the directory, streams the build, and prints the URL when the release is live. A Dockerfile is used if present; otherwise Railpack detects the language. In an unlinked directory, `deploy` runs the link walkthrough first and stops.

```
synteq deploy --image registry.example.com/acme/my-api:v3   # deploy a registry image
synteq deploy --no-wait                                      # return once queued
synteq logs                                                  # stream logs until Ctrl-C

```

## Deploy a function

```
mkdir hello-fn && cd hello-fn
synteq function init hello-fn

```

`init` creates or reuses the function, links the directory, and writes a starter handler if none exists. Default runtime: Node.js 22 (`index.mjs`).

```
export default async function handler(event, context) {
  return { hello: "world", path: event.path };
}

```

`--runtime python312` starts from `handler.py`:

```
def handler(event, context):
    return {"hello": "world", "path": event["path"]}

```

With an existing handler, `init` infers the runtime and overwrites nothing.

```
synteq function deploy
synteq function invoke --path /
synteq function logs --lines

```

Source uploads are limited to 32 files, about 900 KB total, 512 KiB per file; use a Dockerfile for larger projects. `invoke` calls `<slug>.fn.synteq.app` without Synteq credentials.

## Use in scripts

Output is a table on a terminal and JSON when piped or redirected. Force either with `-o json` or `-o table`.

```
synteq apps list -o json | jq '.[].slug'

```

Pass `--yes` to commands that confirm and `--no-interactive` to `link`. When stdout isn't a terminal, the CLI never opens the TUI or a browser. Exit codes and the JSON error format are in CLI reference.

## What next?

- Apps overview: plans, builds, domains, and billing.
- Functions overview: runtimes, triggers, credits, and budgets.
- CLI reference: every command, flag, and exit code.
