---
title: "Commands"
description: "How a command reads, the global flags, every hand-written command and every resource namespace."
url: "https://openemail.uk/docs/cli/commands"
area: "CLI"
category: "Using it"
---

# Commands

How a command reads, the global flags, every hand-written command and every resource namespace.

## How a command reads

**Grammar**

```
openemail <command> [subcommand] [arguments] [flags]
```

- Flags go anywhere after the command, before or after the arguments. Global flags such as `--profile` and `--json` may also come before it, and any other flag placed there stops with a hint to move it after the command name.
- A value follows its flag after a space or an equals sign, so `--limit 50` and `--limit=50` are the same. Short flags take values too, as in `-n 50`.
- A value that starts with a dash needs the equals sign, as in `--subject=-draft-`, because after a space it reads as the next flag and the first one is reported as missing its value. Negative numbers work either way. An empty value is a usage error rather than a quiet default.
- A switch is on with `--flag` and off with `--no-flag`, and `--flag=true` and `--flag=false` work too.
- A list is comma separated or repeated: `--to ada@example.com,bob@example.com`, or `--to` twice.
- Everything after `--` is an argument and never a flag, which is how a search for `-from:ada` gets through.
- An unknown command or flag stops with exit code `2` and suggests the closest match.

## Global flags

| Flag | What it does |
| --- | --- |
| -h, --help | Help for the command or group |
| -v, --version | Print the CLI version |
| --json | Only JSON on stdout, errors as JSON on stderr, and never a prompt |
| -y, --yes | Confirm destructive actions without asking. Never skips a verification code |
| --profile <name> | Use this saved profile, like `OPENEMAIL_PROFILE` |
| --api-key <key> | Use this API key for this command only, ignoring profiles |
| --base-url <url> | The API origin for an API key or a command that sends no credential, like `OPENEMAIL_BASE_URL`. A saved sign-in always uses its own |
| --no-input | Never prompt. A missing value stops with exit code `2` |
| --no-color | No colour, like `NO_COLOR` and `FORCE_COLOR=0` |
| --debug | Print request ids, the failed request and stack traces |

## Hand-written commands

These are written for people: they ask for what is missing, format what they print, and combine several API calls where that helps.

| Command | What it does |
| --- | --- |
| login | Sign in with your browser, or save an API key |
| whoami | Who you are signed in as, with the workspace, scopes and expiry |
| status | What `whoami` shows, plus your sender addresses and the state of each domain |
| verify | Enter a verification code now, so sensitive commands run for 60 minutes |
| logout | Sign out and forget a profile |
| profile list, use, current, remove | List, switch and remove saved sign-ins |
| send | Send, schedule, or translate and send an email |
| inbox [folder] | List the threads in a folder |
| search <query> | Search mail with the syntax the app uses |
| read <thread-id> | Read a thread, message by message |
| reply <thread-id> | Reply to the last message on a thread |
| archive, unarchive, trash, star, unstar | File one or more threads |
| mark read, mark unread | Mark threads read or unread |
| snooze, unsnooze | Hide threads until later, or bring them back now |
| label add, label remove | Put labels on threads, or take them off |
| temp new, list, read, watch, delete | Disposable inboxes, with no sign-in |
| ai translate, languages, compose, summarize | Translate, write and summarise mail with AI |
| mcp config, tools, call, serve | Connect AI clients, or call MCP tools yourself |
| docs ask, open, read | Ask, open and read this documentation |
| open [page] | Open a page of the web app |
| api <method> <path> | Call any REST endpoint with your sign-in |
| update | Check npm for a newer release |
| completion <shell> | Print a completion script for bash, zsh or fish |
| version | Print the CLI, SDK and runtime versions |
| help [command] | Show the help of any command |

## Resource commands

Every method of the SDK is also a command, `openemail <namespace> <verb>`. The namespace is the SDK namespace in kebab case, and the verb is the method name in kebab case, so `keys.listRequests` is `openemail keys list-requests`. Together they cover the whole REST API.

**Terminal**

```
openemail domains list
openemail domains create --domain acme.com
openemail rules create --data @rule.json
openemail keys list-requests 9f2c1a4b7e05d3862c1f0a44 --failed-only --all
openemail files download file_6bb640f5b99e47deb758f1f5 --out report.pdf
```

- An id the method takes is an argument, as in `openemail domains get <id>`. Each field of the request body is a flag named after it in kebab case: `replyTo` is `--reply-to`, and `color.backgroundColor` is `--color-background-color`.
- Three fields whose flag would clash with a global flag are renamed: `--template-version`, `--label-color` and `--resend-key`.
- `--data` takes the whole body as JSON, inline, from a file with `@path`, or from stdin with `-`, and any flag you pass as well overrides its key. A flag that takes an object reads JSON the same way.
- Numbers and switches are read as such, and lists are comma separated or repeated.
- A missing required value is asked for in a terminal, and is a usage error (exit code `2`) anywhere else.
- A list verb reads one page. `--limit` sets its size and `--cursor` carries on from the cursor it printed. `--all` reads every page and streams the items, `--max <n>` stops after that many, and `--ndjson` prints one JSON object per line.
- Anything destructive, such as deleting, revoking, rotating, cancelling or emptying, asks you to confirm, unless you pass `--yes`.
- A download is written to the file in `--out`, and to stdout only when stdout is not a terminal.

`openemail <namespace> <verb> --help` shows each argument and flag with its type, the scopes the call needs, its method and path, what it returns, and the notes from the API reference.

## Every namespace

Also lists the other names a namespace answers to.

| Namespace | Also | Verbs |
| --- | --- | --- |
| me |  | `get`, `ping`, `rotate` |
| keys | `key` | `list`, `get`, `create`, `update`, `delete`, `rotate`, `revoke`, `list-requests`, `list-activity`, `list-workspace-requests`, `list-workspace-activity` |
| addresses | `address` | `list` |
| languages | `language` | `list` |
| emails | `email` | `send`, `send-batch`, `translate`, `list`, `get`, `list-events`, `get-tracking`, `cancel`, `reschedule` |
| templates | `template` | `list`, `get`, `create`, `update`, `duplicate`, `replace-content`, `delete`, `list-versions`, `get-version`, `publish`, `restore-version`, `delete-version`, `list-starters`, `get-starter`, `list-fonts`, `render`, `preview`, `get-analytics`, `list-sends`, `send` |
| tracking |  | `list`, `get-stats`, `get`, `list-opens`, `list-clicks` |
| threads | `thread` | `list`, `get`, `update`, `trash`, `snooze`, `unsnooze`, `list-attachments` |
| drafts | `draft` | `list`, `get`, `create`, `update`, `delete` |
| labels |  | `list`, `list-colors`, `get`, `create`, `update`, `delete` |
| contacts | `contact` | `list`, `get`, `create`, `update`, `delete`, `set-audiences`, `list-people`, `save`, `delete-many`, `set-photo`, `remove-photo`, `block`, `unblock`, `list-threads`, `activity` |
| audiences | `audience` | `list`, `growth`, `get`, `create`, `update`, `delete`, `empty`, `list-contacts`, `add-contact`, `remove-contact`, `add-contacts`, `remove-contacts`, `import-contacts` |
| broadcasts | `broadcast` | `preview`, `send`, `list`, `get`, `stats`, `list-recipients`, `get-recipient`, `cancel` |
| domains | `domain` | `list`, `get`, `create`, `verify`, `update`, `delete`, `list-addresses`, `create-address`, `get-address`, `update-address`, `delete-address` |
| rules | `rule` | `list`, `get`, `create`, `update`, `delete`, `reorder`, `test`, `list-runs` |
| webhooks | `webhook` | `list`, `get`, `create`, `update`, `delete`, `rotate-secret`, `test`, `list-deliveries`, `get-delivery`, `replay-delivery`, `list-workspace-deliveries`, `list-activity`, `list-workspace-activity` |
| imports | `import` | `list`, `get`, `create`, `upload-state`, `upload-chunk`, `start`, `cancel`, `list-failures`, `delete-upload`, `import-files` |
| provider-imports | `provider-import`, `providerImports` | `inspect`, `create`, `list`, `get`, `cancel` |
| calendar |  | `list-events`, `get-event`, `get-event-ics` |
| settings | `setting` | `get`, `update` |
| roles | `role` | `list`, `get`, `create`, `update`, `delete`, `list-permissions` |
| members | `member` | `list`, `get`, `add`, `update`, `remove`, `grant-address`, `revoke-address`, `list-invitations`, `revoke-invitation`, `resend-invitation` |
| suppressions | `suppression` | `list`, `get`, `add`, `remove` |
| files | `file` | `list`, `get`, `stats`, `download`, `list-links`, `create-link`, `revoke-link`, `upload`, `delete`, `delete-many` |
| temp-mail | `tempMail` | `list-domains`, `create`, `get`, `extend`, `delete`, `list-messages`, `get-message`, `delete-message`, `list-attachments` |

## Aliases

| Alias | For |
| --- | --- |
| ls | `list` |
| show, view | `get` |
| new, add | `create` |
| edit | `update` |
| rm, del, remove | `delete` |
| openemail ls | `openemail inbox` |
| openemail show | `openemail read` |

In `members` and `suppressions`, whose verbs are `add` and `remove`, `new` and `create` lead to `add`, and `rm`, `del` and `delete` lead to `remove`. A few hand-written subcommands have aliases of their own, which their help lists.

## Any REST call

`openemail api <method> <path>` sends one request to the REST API through the same transport as every other command, so your profile or key, token renewal and verification codes all apply. A path on its own is a `GET`. A JSON answer prints formatted, and a failed request prints the API error and exits with the matching code.

**Terminal**

```
openemail api /keys/self
openemail api GET /threads --query folder=inbox --query limit=5
openemail api POST /labels --data '{"name":"Receipts"}'
openemail api PATCH /threads/CAHk7pQ2x9LmZ4 --data @patch.json
openemail api GET /files/file_6bb640f5b99e47deb758f1f5/content --out report.pdf
```

- `-d`, `--data` takes the body as inline JSON, from a file with `@path`, or from stdin with `-`. `-q`, `--query` and `-H`, `--header` take `key=value` and can be repeated, and `-o`, `--out` saves the answer to a file as it came.
- The path is relative to the API origin. A full URL, a path that would leave the origin and an `Authorization` header are refused with exit code `2` before anything is sent, because the CLI sets the credential itself.

## Help

**Terminal**

```
openemail --help
openemail help send
openemail domains --help
openemail domains create --help
```

`openemail --help` lists every command by what it is for. A group lists its subcommands with examples, and a command shows everything it takes. `openemail docs open cli` opens these pages.
