> ## Documentation Index
> Fetch the complete documentation index at: https://developer.zeeg.me/llms.txt
> Use this file to discover all available pages before exploring further.

# Zeeg CLI

> Install the zeeg command-line tool, sign in, and script the Zeeg API from your terminal or CI pipelines.

`zeeg` works with your Zeeg account from the terminal: event types, available times, bookings, notes, CRM records, routing forms and AI phone calls. It calls the public [Zeeg API v2](/authentication), so it can do exactly what an API token can do, with your own dashboard permissions.

<Note>
  **Coming soon.** `@zeeg/cli` isn't published to npm yet. This page describes the shape it ships with.
</Note>

<Info>
  The CLI needs a plan that includes API access. A free plan cannot sign in. Finding available times (`zeeg availability`) and booking meetings (`zeeg bookings create`) need a **paid** plan; a **trial** can use everything else. If your API access comes from AI minutes alone, the CLI can only run `zeeg agents` and `zeeg calls start`.
</Info>

## Install

Node.js 20 or later:

```bash theme={null}
npm install -g @zeeg/cli
zeeg --help
```

## Log in

```bash theme={null}
zeeg login
```

The CLI prints a one-time code and opens `https://api.zeeg.me/oauth/device` in your browser. Sign in to Zeeg if you're not signed in already, check that the code on the page matches the one in your terminal, and allow access. On a machine without a browser, run `zeeg login --no-browser` and open the printed link anywhere.

<Warning>
  Only approve a code you started yourself. Anyone holding a code you approve gets access to your account.
</Warning>

* `zeeg whoami` shows the account, the API origin, and the scopes the login carries.
* `zeeg logout` revokes the login on Zeeg's side and removes it from this machine.

The access token lasts an hour and renews itself; a login you don't use for 30 days ends, and `zeeg login` starts a new one.

### Where the login is stored

In the system keychain: Keychain on macOS, Credential Manager on Windows, and the Secret Service (GNOME Keyring, KWallet) on Linux. A machine without one, such as a server you reach over SSH, keeps it in `~/.config/zeeg/credentials.json` (or under `$XDG_CONFIG_HOME`), readable only by you; the CLI says so the first time. Set `ZEEG_TOKEN_STORE=file` to use the file everywhere.

### Other environments

`--base-url` or `ZEEG_API_URL` points the CLI at another API origin, for example a local backend:

```bash theme={null}
ZEEG_API_URL=http://localhost:8000 zeeg login
```

Plain `http` is accepted for `localhost`, `127.0.0.1` and `[::1]` only — every other origin needs `https`. Each origin keeps its own login.

## Commands

| Command                                                                                         | What it does                                                            |
| ----------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------- |
| `zeeg event-types list` / `get <uuid>`                                                          | Your event types (scheduling pages)                                     |
| `zeeg availability <eventTypeUuid> [--from --to --tz --duration]`                               | Open start times, by day                                                |
| `zeeg schedules list [--email]`                                                                 | Availability schedules                                                  |
| `zeeg time-off add --start --end --title [--type --note --email]`                               | Block days as time off                                                  |
| `zeeg bookings list [--status --from --to --invitee-email --host-email --keyword --all --desc]` | Bookings you can see                                                    |
| `zeeg bookings get <uuid>`                                                                      | One booking                                                             |
| `zeeg bookings create <eventTypeUuid> --date --time --name --email`                             | Book a meeting for an invitee                                           |
| `zeeg bookings cancel <uuid> [--reason]`                                                        | Cancel a booking                                                        |
| `zeeg bookings reschedule <uuid> --date --time`                                                 | Move a booking                                                          |
| `zeeg bookings hand-over <uuid> [--to]`                                                         | Hand a round-robin booking to another host                              |
| `zeeg notes list <bookingUuid>` / `add <bookingUuid> <text>`                                    | Notes on a booking                                                      |
| `zeeg crm list <people\|companies\|slug>`                                                       | CRM records, paginated (`--search <text>` filters by name/email/domain) |
| `zeeg crm get <object> <id>`                                                                    | One CRM record                                                          |
| `zeeg crm upsert <object> --match <attribute> --data <json>`                                    | Create a record, or update the one that matches                         |
| `zeeg forms list` / `submissions [--form]`                                                      | Routing forms and their submissions                                     |
| `zeeg agents list`                                                                              | Your AI phone agents                                                    |
| `zeeg agents calls <agentUuid> [--from --to --direction]`                                       | One agent's calls, newest first                                         |
| `zeeg agents call <callId>`                                                                     | One call, with its transcript and collected data                        |
| `zeeg calls start <agentUuid> --phone [--name --email --data --at]`                             | Have an AI phone agent call someone                                     |

`zeeg <command> --help` lists every option. Times are in your machine's time zone unless you pass `--tz`.

Commands that reach other people or spend AI minutes (`bookings create`, `cancel`, `reschedule`, `hand-over`, `calls start`) ask before they act. Pass `-y` / `--yes` to skip the question, which scripts must do: without a terminal to ask in, they stop instead.

```bash theme={null}
zeeg availability 5c7e… --from 2026-10-05 --to 2026-10-09 --tz Europe/Berlin
zeeg bookings create 5c7e… --date 2026-10-06 --time 14:30 --tz Europe/Berlin \
  --name "Sophie Laurent" --email sophie@northwind.io
zeeg crm upsert people --match emails --data '{"firstName":"Sophie","emails":["sophie@northwind.io"]}'
```

## JSON output

In a terminal the CLI prints tables. When its output goes to a pipe or a file, or with `--json`, it prints the API's JSON unchanged, so you can hand it to `jq` or an agent:

```bash theme={null}
zeeg bookings list --status confirmed | jq -r '.collection[].uuid'
```

Messages meant for you (the login code, questions, notices) go to stderr and never mix with the JSON.

## Exit codes

| Code | Meaning                                                                   |
| ---- | ------------------------------------------------------------------------- |
| 0    | Done                                                                      |
| 1    | Wrong usage, or you answered no                                           |
| 2    | Not logged in, or the login ended: run `zeeg login`                       |
| 3    | The API refused the request or could not be reached; the message says why |
