Skip to the documentation
CLI

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 [email protected],[email protected], 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

FlagWhat it does
-h, --helpHelp for the command or group
-v, --versionPrint the CLI version
--jsonOnly JSON on stdout, errors as JSON on stderr, and never a prompt
-y, --yesConfirm 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-inputNever prompt. A missing value stops with exit code 2
--no-colorNo colour, like NO_COLOR and FORCE_COLOR=0
--debugPrint 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.

CommandWhat it does
loginSign in with your browser, or save an API key
whoamiWho you are signed in as, with the workspace, scopes and expiry
statusWhat whoami shows, plus your sender addresses and the state of each domain
verifyEnter a verification code now, so sensitive commands run for 60 minutes
logoutSign out and forget a profile
profile list, use, current, removeList, switch and remove saved sign-ins
sendSend, 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, unstarFile one or more threads
mark read, mark unreadMark threads read or unread
snooze, unsnoozeHide threads until later, or bring them back now
label add, label removePut labels on threads, or take them off
temp new, list, read, watch, deleteDisposable inboxes, with no sign-in
ai translate, languages, compose, summarizeTranslate, write and summarise mail with AI
mcp config, tools, call, serveConnect AI clients, or call MCP tools yourself
docs ask, open, readAsk, 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
updateCheck npm for a newer release
completion <shell>Print a completion script for bash, zsh or fish
versionPrint 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 listopenemail domains create --domain acme.comopenemail rules create --data @rule.jsonopenemail keys list-requests 9f2c1a4b7e05d3862c1f0a44 --failed-only --allopenemail 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.

NamespaceAlsoVerbs
meget, ping, rotate
keyskeylist, get, create, update, delete, rotate, revoke, list-requests, list-activity, list-workspace-requests, list-workspace-activity
addressesaddresslist
languageslanguagelist
emailsemailsend, send-batch, translate, list, get, list-events, get-tracking, cancel, reschedule
templatestemplatelist, 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
trackinglist, get-stats, get, list-opens, list-clicks
threadsthreadlist, get, update, trash, snooze, unsnooze, list-attachments
draftsdraftlist, get, create, update, delete
labelslist, list-colors, get, create, update, delete
contactscontactlist, get, create, update, delete, set-audiences, list-people, save, delete-many, set-photo, remove-photo, block, unblock, list-threads, activity
audiencesaudiencelist, growth, get, create, update, delete, empty, list-contacts, add-contact, remove-contact, add-contacts, remove-contacts, import-contacts
broadcastsbroadcastpreview, send, list, get, stats, list-recipients, get-recipient, cancel
domainsdomainlist, get, create, verify, update, delete, list-addresses, create-address, get-address, update-address, delete-address
rulesrulelist, get, create, update, delete, reorder, test, list-runs
webhookswebhooklist, get, create, update, delete, rotate-secret, test, list-deliveries, get-delivery, replay-delivery, list-workspace-deliveries, list-activity, list-workspace-activity
importsimportlist, get, create, upload-state, upload-chunk, start, cancel, list-failures, delete-upload, import-files
provider-importsprovider-import, providerImportsinspect, create, list, get, cancel
calendarlist-events, get-event, get-event-ics
settingssettingget, update
rolesrolelist, get, create, update, delete, list-permissions
membersmemberlist, get, add, update, remove, grant-address, revoke-address, list-invitations, revoke-invitation, resend-invitation
suppressionssuppressionlist, get, add, remove
filesfilelist, get, stats, download, list-links, create-link, revoke-link, upload, delete, delete-many
temp-mailtempMaillist-domains, create, get, extend, delete, list-messages, get-message, delete-message, list-attachments

Aliases

AliasFor
lslist
show, viewget
new, addcreate
editupdate
rm, del, removedelete
openemail lsopenemail inbox
openemail showopenemail 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/selfopenemail api GET /threads --query folder=inbox --query limit=5openemail api POST /labels --data '{"name":"Receipts"}'openemail api PATCH /threads/CAHk7pQ2x9LmZ4 --data @patch.jsonopenemail 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 --helpopenemail help sendopenemail domains --helpopenemail 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.

Your inbox,
on your own terms.

Email infrastructure for businesses, AI, agents and personal email. Built for scale, privacy and control. Everything email should have had from day one.

OpenEmail

Email infrastructure for businesses, AI, agents and personal email. Built for scale, privacy and control. Everything email should have had from day one.

© 2026 OpenEmail. All rights reserved.