Skip to the documentation
CLI

Hand-written commands

The commands written for people, with every argument, flag and example.

Commands

Every command here also takes the global flags, such as --json, --profile and --dry-run. See the global flags

nextmail login

Sign in with your browser, or save an API key

No sign-in needed

Usage

nextmail login
nextmail login --no-browser
nextmail login --scopes <list>
nextmail login --with-token < key.txt
nextmail login --token <key>
nextmail login --profile <name>

With no flags in an interactive terminal it asks how you want to sign in. The browser sign-in opens the Nextmail approval page, where you pick the workspace, the access and how long it lasts, then brings the approval back to the terminal on its own. Over SSH, or with --no-browser, it prints the link and you paste back the code the browser shows. A browser sign-in asks for a verification code before sensitive changes, exactly like the web app. An API key never asks for a code, which makes it the choice for scripts and servers. The sign-in is saved in ~/.nextmail/config.json as a profile, and becomes the active profile only when no other profile is active, so --profile <name> adds a second sign-in without changing what other commands use.

Flags

--token <key>

Save this API key (oe_live_ or oe_test_). It lands in your shell history, so prefer --with-token

--with-token

Read an API key from stdin and save it

--no-browser

Print the sign-in link and paste the code back instead of opening a browser. Chosen for you over SSH

--scopes <list>Repeatable

Permissions to preselect on the approval page, comma separated. You can still change them there

--force

Replace the sign-in already saved on this profile without asking

Examples

Asks how to sign in, then opens your browser
nextmail login
Over SSH: open the link anywhere and paste the code back
nextmail login --no-browser
Preselects these permissions on the approval page
nextmail login --scopes emails:send,threads:read
Saves an API key without it touching your shell history
nextmail login --with-token < ~/.config/nextmail/key
Signs a second profile in. The active profile stays as it is, so pass `--profile work` or run `nextmail profile use work`
nextmail login --profile work

nextmail whoami

Show who you are signed in as, and what you may do

Needs a sign-in

Usage

nextmail whoami
nextmail whoami --json
nextmail whoami --profile <name>

Reads the credential the next command would use, a saved profile, NEXTMAIL_API_KEY or --api-key, and asks the API what it may do: the workspace, the mode, the scopes, any address or domain restriction, and when a browser sign-in expires.

Examples

nextmail whoami
Every field, for scripts
nextmail whoami --json
Checks another saved profile
nextmail whoami --profile work
Checks a key without saving it
NEXTMAIL_API_KEY=oe_test_... nextmail whoami

nextmail status

Show your sign-in, sender addresses and domains

Needs a sign-in

Usage

nextmail status
nextmail status --json

Everything whoami shows, plus the addresses you can send from and the verification state of every domain, read in parallel. A section your credential may not read, for example domains without the domains:read scope, says so instead of failing the whole command.

Examples

nextmail status
The account, addresses and domains as one JSON object
nextmail status --json
nextmail status --profile work

nextmail send

Send, schedule or translate and send an email

Scopesemails:sendNeeds a sign-in

Usage

nextmail send --to <address> --subject <text> --text <body> [flags]
nextmail send --to <address> --subject <text> --body-file <path> [flags]
nextmail send --to <address> --template <id> [--props <json>] [flags]

Sends one email through emails.send. The body comes from --text, --html or both, then --body-file, then anything piped on stdin, and in an interactive terminal from your editor ($VISUAL or $EDITOR). Piped input that starts with an HTML tag is sent as HTML. Without --from you pick one of the addresses you can send from, or the only one is used. A piped body counts as unattended, so the picker is off and --from is needed when you can send from more than one address. --draft sends a saved draft's body, and its subject unless you pass --subject, to the recipients you name. In an interactive terminal you see a summary and confirm before anything goes, unless you pass --yes. Files attached with --attach travel inline while they come to 5 MB or less in total, and are uploaded to Files first and sent by reference when they come to more.

Flags

--to <address>Repeatable

Recipient, or several comma separated. Ada Lovelace <ada@example.com> works too

--cc <address>Repeatable

Copy recipient, or several comma separated

--bcc <address>Repeatable

Blind copy recipient, or several comma separated

--from <address>

Address to send from. Left out, the only address you can send from is used, or you pick one in a terminal. A piped body turns the picker off

--reply-to <address>

Address written into the Reply-To header

-s, --subject <text>

Subject line

--text <text>

Plain text body

--html <html>

HTML body

-f, --body-file <path>

Read the body from a file. A .html or .htm file is sent as HTML and anything else as text. - reads stdin

-a, --attach <path>Repeatable

Attach a file. Up to 5 MB in total travels inline, and a larger set is uploaded to Files first

--template <id-or-slug>

Send a stored template instead of a body

--props <json|@file>

Template props as a JSON object, @file or - for stdin

--at <when>

Schedule the send: an ISO date such as 2026-10-01T09:00:00Z, or a delay such as 10m, 2h, 1d or PT1H

--undo <seconds>

Hold an immediate send for 0 to 900 seconds so it can still be cancelled

--translate <language>

Translate the email before it goes, to a code or name such as de or German

--tag <key=value>Repeatable

Tag the email. Tags are echoed back on every read

--draft <id>

Send the body of a saved draft, and its subject unless you pass --subject. --to and --from still apply

--thread <id>

File the sent email into this thread

--idempotency-key <key>

Your own idempotency key, so running the command again never sends twice

Examples

nextmail send --to ada@example.com --subject "Lunch?" --text "Thursday at noon works for me."
The body is read from stdin, so nothing can ask which address to send from
cat report.md | nextmail send --from you@acme.com --to team@acme.com --subject "Weekly report" --attach chart.png
Translated to German and sent in two hours
nextmail send --to ada@example.de --subject "Invoice" --body-file invoice.html --translate de --at 2h
nextmail send --to ada@example.com --template welcome --props '{"name":"Ada"}' --tag campaign=onboarding
Running it again with the same key never sends twice
nextmail send --from billing@acme.com --to ada@example.com --subject "Receipt" --text "Thanks" --idempotency-key order-4192 --json

nextmail inbox

List the threads in your inbox or another folder

Scopesthreads:readNeeds a sign-inAliasesls

Usage

nextmail inbox [folder] [flags]

Lists one page of threads, newest first, and reads each one (six at a time) to show when it last moved, who wrote last, the subject, its labels and its id. The folder defaults to the inbox, and sent, archive, starred, snoozed, spam, trash, draft or a label id such as USER_RECEIPTS work too. A dot marks a thread with unread mail. Pass the id to nextmail read to open it.

Arguments

<folder>

Folder or label id to list (default inbox)

Flags

-u, --unread

Only threads with unread mail

-q, --query <search>

Mailbox search such as from:ada has:pdf newer_than:7d

-l, --label <label-id>Repeatable

Only threads carrying this label id, or every one of several comma separated

-n, --limit <n>

Threads per page, 1 to 100 (default 25)

--cursor <cursor>

Carry on from the cursor an earlier page printed

--all

Read every page instead of the first one

--from-contacts

Only threads whose newest message came from a saved contact

--semantic

Match the words of the query by meaning instead of spelling, best match first

--sort <order>

Order of the threads, newest first unless you pick another

One of"newest""oldest""sender""subject"

Examples

nextmail inbox
nextmail inbox --unread --limit 50
Threads you sent to Ada
nextmail ls sent --query "to:ada"
nextmail inbox archive --from-contacts --sort oldest
Every thread id in the inbox
nextmail inbox --all --json | jq -r ".items[].id"

nextmail read

Read a thread, message by message

Scopesthreads:readNeeds a sign-inAliasesshow

Usage

nextmail read <thread-id> [flags]

Prints every message on the thread, oldest first, with who sent it, who it went to, when, the subject, the attachments with their sizes and ids, and the body. A plain text part is shown as it is, and an HTML-only message is turned into readable text: paragraphs, lists, quotes, headings and links as text (url). With --html stdout gets only the raw HTML of one message, so it can be saved to a file, and the headers go to stderr. Reading marks the thread read unless you pass --no-mark-read.

Arguments

<thread-id>Required

Thread id from nextmail inbox

Flags

-m, --message <n>

Show only this message, counting from 1. A negative number counts from the newest

--html

Print only the raw HTML of one message on stdout, with the headers on stderr

--mark-read

Mark the thread read once it is shown, which is the default. Pass --no-mark-read to leave it unread

Examples

nextmail read CAHk7pQ2x9LmZ4
Only the newest message
nextmail read CAHk7pQ2x9LmZ4 --message -1
nextmail show CAHk7pQ2x9LmZ4 --html --message 1 > first.html
nextmail read CAHk7pQ2x9LmZ4 --no-mark-read --json

nextmail reply

Reply to the last message on a thread

Scopesthreads:reademails:sendNeeds a sign-in

Usage

nextmail reply <thread-id> --text <body> [flags]
nextmail reply <thread-id> --all --body-file <path> [flags]

Replies to whoever sent the last message on the thread, or to its Reply-To address, and files the reply into the same thread. When the last message is one you sent, the reply goes to the people it went to. --all copies everyone else on that message, leaving out your own addresses. The subject gets Re: unless it already has it, and the reply is sent from the address the thread was delivered to when you can send from it. The body flags work as they do for nextmail send, including stdin and your editor.

Arguments

<thread-id>Required

Thread id from nextmail inbox

Flags

--text <text>

Plain text body

--html <html>

HTML body

-f, --body-file <path>

Read the body from a file. A .html or .htm file is sent as HTML and anything else as text. - reads stdin

--all

Reply to everyone on the last message, leaving out your own addresses

-a, --attach <path>Repeatable

Attach a file. Up to 5 MB in total travels inline, and a larger set is uploaded to Files first

--from <address>

Address to send from. Left out, the only address you can send from is used, or you pick one in a terminal. A piped body turns the picker off

--to <address>Repeatable

Recipient, or several comma separated. Ada Lovelace <ada@example.com> works too

--cc <address>Repeatable

Copy recipient, or several comma separated

--bcc <address>Repeatable

Blind copy recipient, or several comma separated

-s, --subject <text>

Subject line

--at <when>

Schedule the send: an ISO date such as 2026-10-01T09:00:00Z, or a delay such as 10m, 2h, 1d or PT1H

--undo <seconds>

Hold an immediate send for 0 to 900 seconds so it can still be cancelled

--translate <language>

Translate the email before it goes, to a code or name such as de or German

--tag <key=value>Repeatable

Tag the email. Tags are echoed back on every read

--idempotency-key <key>

Your own idempotency key, so running the command again never sends twice

Examples

nextmail reply CAHk7pQ2x9LmZ4 --text "Thanks, that works for me."
Opens your editor for the body
nextmail reply CAHk7pQ2x9LmZ4 --all --attach notes.pdf
echo "Confirmed." | nextmail reply CAHk7pQ2x9LmZ4 --yes
nextmail reply CAHk7pQ2x9LmZ4 --body-file reply.html --undo 30

nextmail archive

Archive threads out of the inbox

Scopesthreads:writeNeeds a sign-in

Usage

nextmail archive <thread-id...>

Adds ARCHIVE and removes INBOX, the same pair the app uses, so the threads leave the inbox and stay searchable. Several ids are handled in one run, and each one is reported.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail archive CAHk7pQ2x9LmZ4
nextmail archive CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn --json
Archive every recent alert
nextmail inbox --query "newer_than:30d from:alerts" --json | jq -r ".items[].id" | xargs nextmail archive

nextmail unarchive

Move archived threads back to the inbox

Scopesthreads:writeNeeds a sign-in

Usage

nextmail unarchive <thread-id...>

Adds INBOX and removes ARCHIVE, so the threads show in the inbox again.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail unarchive CAHk7pQ2x9LmZ4
nextmail unarchive CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn

nextmail trash

Move threads to the Bin

Scopesthreads:writeNeeds a sign-in
Asks you to confirm

Usage

nextmail trash <thread-id...>

Adds TRASH and takes the threads out of the inbox, spam, snoozed and archive in one step, like delete in the app. Nothing is deleted, and a snoozed thread loses its wake time. No API call takes a thread back out of the Bin, so you are asked to confirm unless you pass --yes.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail trash CAHk7pQ2x9LmZ4
nextmail trash CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn --yes

nextmail star

Star threads

Scopesthreads:writeNeeds a sign-in

Usage

nextmail star <thread-id...>

Adds the STARRED label, so the threads show under Starred.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail star CAHk7pQ2x9LmZ4
List what you starred
nextmail inbox starred

nextmail unstar

Take the star off threads

Scopesthreads:writeNeeds a sign-in

Usage

nextmail unstar <thread-id...>

Removes the STARRED label.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail unstar CAHk7pQ2x9LmZ4
nextmail unstar CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn

nextmail mark read

Mark threads read

Scopesthreads:writeNeeds a sign-in

Usage

nextmail mark read <thread-id...>

Removes the UNREAD label from each thread.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail mark read CAHk7pQ2x9LmZ4
Mark the whole first page read
nextmail inbox --unread --json | jq -r ".items[].id" | xargs nextmail mark read

nextmail mark unread

Mark threads unread

Scopesthreads:writeNeeds a sign-in

Usage

nextmail mark unread <thread-id...>

Adds the UNREAD label to each thread, so it shows as new again.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail mark unread CAHk7pQ2x9LmZ4
nextmail mark unread CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn --json

nextmail snooze

Hide threads until a later time

Scopesthreads:writeNeeds a sign-in

Usage

nextmail snooze <thread-id...> --until <when>

Adds SNOOZED, takes the threads out of the inbox and stores when they come back. Threads are woken by an hourly sweep, so one returns up to about an hour after the time you set, always into the inbox. Snoozing a snoozed thread replaces its wake time.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Flags

--until <when>

When the thread returns: an ISO date such as 2026-10-01T09:00:00Z, or a delay such as 3h, 2d or 1w

Examples

nextmail snooze CAHk7pQ2x9LmZ4 --until 3h
nextmail snooze CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn --until 1w
nextmail snooze CAHk7pQ2x9LmZ4 --until 2026-10-01T09:00:00+02:00

nextmail unsnooze

Bring snoozed threads back now

Scopesthreads:writeNeeds a sign-in

Usage

nextmail unsnooze <thread-id...>

Adds INBOX, removes SNOOZED and clears the wake time, so the threads return straight away. A thread that is not snoozed stays where it is.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Examples

nextmail unsnooze CAHk7pQ2x9LmZ4
List what is snoozed
nextmail inbox snoozed

nextmail label add

Put labels on threads

Scopesthreads:writeNeeds a sign-in

Usage

nextmail label add <thread-id...> --label <label-id>

Adds every label in --label to each thread. A label id that names no label is refused and nothing on that thread changes, so create it first with nextmail labels create. TRASH, SNOOZED and DRAFT cannot be set here: use nextmail trash or nextmail snooze.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Flags

-l, --label <label-id>Repeatable

Label id such as USER_RECEIPTS or STARRED, or several comma separated

Examples

nextmail label add CAHk7pQ2x9LmZ4 --label USER_RECEIPTS
nextmail label add CAHk7pQ2x9LmZ4 CAJx0dW1bQe7Tn --label USER_TAXES,USER_2026

nextmail label remove

Take labels off threads

Scopesthreads:writeNeeds a sign-in

Usage

nextmail label remove <thread-id...> --label <label-id>

Removes every label in --label from each thread. A label the thread does not carry is not an error.

Arguments

<thread-id...>RequiredOne or more

One or more thread ids from nextmail inbox

Flags

-l, --label <label-id>Repeatable

Label id such as USER_RECEIPTS or STARRED, or several comma separated

Examples

nextmail label remove CAHk7pQ2x9LmZ4 --label USER_RECEIPTS
nextmail label rm CAHk7pQ2x9LmZ4 --label IMPORTANT --json

nextmail temp new

Create a disposable inbox

No sign-in neededAliasescreate

Usage

nextmail temp new [--name <local-part>] [--domain <domain>] [--ttl <minutes>]

Creates a disposable address that needs no account and no API key, and keeps its token in ~/.nextmail/temp-mail.json so the other temp commands can reach it. The address is printed on stdout on its own, so ADDRESS=$(nextmail temp new) works in a script. It lives for 60 minutes unless you pass --ttl, up to 24 hours, and nextmail temp-mail extend adds up to an hour at a time within 24 hours of its creation, saving the new token it returns. A name you choose with --name is issued to anyone who asks for it too, so leave it out when the mail should reach you alone.

Flags

--name <local-part>

The part before the @, up to 64 letters, digits, dots, dashes or underscores, starting and ending with a letter or digit. Left out, one is generated. Anyone who asks for the same name reads its mail too

--domain <domain>

Domain from nextmail temp-mail list-domains. Left out, the first one in that list is used

--ttl <minutes>

How long the inbox lives, 1 to 1440 minutes (default 60)

Examples

nextmail temp new
nextmail temp new --name signup-test --ttl 120
Keep the address in a shell variable
ADDRESS=$(nextmail temp new --ttl 15)
Prints the inbox with its id, expiry and token
nextmail temp new --json

nextmail temp list

List the disposable inboxes this CLI created

No sign-in needed

Usage

nextmail temp list

Lists the inboxes kept in ~/.nextmail/temp-mail.json, soonest to expire last. Expired inboxes are forgotten as they are found, because their tokens no longer open anything. An inbox extended with nextmail temp-mail extend shows its later expiry. Nothing is read from the network.

Examples

nextmail temp list
Ids, addresses and expiry times, never the tokens
nextmail temp ls --json

nextmail temp read

List the mail in a disposable inbox, or read one message

No sign-in neededAliasesshowopen

Usage

nextmail temp read [inbox] [message-id] [flags]

Without a message id it lists what has arrived, newest first, with a short preview that is often enough to read a one time code. With one it prints the whole message, turning HTML into readable text, and lists its attachments by name and size, without their bytes. The inbox is its id or address, and can be left out when you have only one, so a lone thr_ id reads that message. Reading a message does not mark it seen, and its body is never cut. The sender of mail in a temporary inbox is never verified.

Arguments

<inbox>

Inbox id or address from nextmail temp list

<message-id>

A thr_ id from the list

Flags

--html

Print only the raw HTML on stdout, with the headers on stderr

--inbox-token <token>

The oe_inbox_ token of an inbox this CLI did not create

Examples

nextmail temp read
nextmail temp read quiet-otter-12@example-temp.com
Reads one message from your only inbox
nextmail temp read thr_9e3b7c1a5f2d8e40b6a9c3f1
nextmail temp read tinb_k7m2q9xw4bdp thr_9e3b7c1a5f2d8e40b6a9c3f1
nextmail temp read tinb_k7m2q9xw4bdp thr_9e3b7c1a5f2d8e40b6a9c3f1 --html > message.html

nextmail temp watch

Wait for mail to arrive in a disposable inbox

No sign-in needed

Usage

nextmail temp watch [inbox] [--first]

Prints what is already in the inbox, then checks every 3 seconds and prints each new message as it lands, until you press Ctrl+C or the inbox expires. When nextmail temp-mail extend saves a new token for the inbox meanwhile, the watch carries on with it until the later expiry. With --first it stops as soon as there is a message, which suits a script waiting for a sign-up code. With --json each message is one JSON line on stdout.

Arguments

<inbox>

Inbox id or address from nextmail temp list, optional when you have only one

Flags

--first

Stop as soon as the inbox holds a message, which suits a script waiting for a code

--inbox-token <token>

The oe_inbox_ token of an inbox this CLI did not create

Examples

nextmail temp watch
nextmail temp watch quiet-otter-12@example-temp.com
Wait for one message and print its preview
nextmail temp watch --first --json | jq -r .snippet

nextmail temp delete

Move the mail in a disposable inbox to the bin and forget its token

No sign-in needed
Asks you to confirm
Aliasesrm

Usage

nextmail temp delete [inbox] [--yes]

Moves every message the inbox shows to the bin at once, then removes the inbox and its token from ~/.nextmail/temp-mail.json. Nothing about the lease is stored on the server, so there is nothing to revoke: it runs on until its expiry, and mail that arrives in the meantime still reaches whoever holds the token. Nothing holds the address back either, so it can be issued again at once, to anybody. You are asked to confirm unless you pass --yes.

Arguments

<inbox>

Inbox id or address from nextmail temp list, optional when you have only one

Flags

--inbox-token <token>

The oe_inbox_ token of an inbox this CLI did not create

Examples

nextmail temp delete
nextmail temp rm quiet-otter-12@example-temp.com --yes
nextmail temp delete tinb_k7m2q9xw4bdp --yes --json

nextmail ai translate

Translate a subject and body without sending anything

Scopesemails:sendNeeds a sign-in

Usage

nextmail ai translate --to <language> [--text <text>|--html <html>|--body-file <path>] [--subject <subject>]
nextmail ai translate --to <language> < message.txt

Runs the same translation a translated send performs and prints the result, so you can read it before anything leaves. Nothing is stored and nothing is sent. The body comes from --text, --html, --body-file (a .html file is sent as HTML, anything else as text) or stdin when it is piped. --text and --html also read a file with @path or stdin with -. Each call spends one AI action, and the credential needs the emails:send scope.

Flags

--to <language>Required

Target language as a code (de), an English name (German) or its own name (Deutsch)

--from <language>

The language you wrote in. Stating it skips detection

--subject <subject>

A subject line to translate

--text <text|@file|->

A plain text body to translate

--html <html|@file|->

An HTML body to translate

--body-file <path>

Read the body from a file. A .html or .htm file is HTML, anything else is text

--original

Keep your original text below the translation (the default). Pass --no-original to leave it out

Examples

nextmail ai translate --to de --subject "Your invoice" --text "The invoice is attached."
Translates an HTML body and leaves your original out
nextmail ai translate --to Japanese --body-file reply.html --no-original
Reads the body from stdin
cat notes.txt | nextmail ai translate --to fr
Prints the full translation object, including the detected source language
nextmail ai translate --to es --text "See you soon" --json

nextmail ai languages

List every language translation accepts

Works signed in or notAliaseslangs

Usage

nextmail ai languages [--search <text>]

Prints the language table the server translates into, in the order a picker should show it. Any row's code, English name or own name works as --to on nextmail ai translate and nextmail send --translate. Signed out, it prints the table bundled with this version of the CLI.

Flags

--search <text>

Keep only languages whose code, English name or own name contains this text

Examples

nextmail ai languages
Finds Portuguese and Brazilian Portuguese
nextmail ai languages --search port
Lists the right-to-left codes
nextmail ai languages --json | jq -r '.[] | select(.rtl) | .code'

nextmail ai compose

Write an email body with AI from a short prompt

Scopesdrafts:writeNeeds a browser sign-inAliaseswrite

Usage

nextmail ai compose "<prompt>" [--to <address>] [--subject <subject>] [--thread <thread-id>] [--tone <tone>]

Asks the Nextmail assistant to write an email body in your own writing style and prints it. Nothing is sent or saved, so pipe it into nextmail send --from <address> when you are happy with it. With --thread the assistant reads the thread first and writes a reply to it. The prompt can also come from stdin. This uses the MCP tool composeEmail, so it needs a browser sign-in (nextmail login) and spends one AI action, plus one for each web search it runs.

Arguments

<prompt...>One or more

What the email should say

Flags

--to <address>Repeatable

Who it is for. Repeat the flag or separate addresses with commas

--cc <address>Repeatable

Who is copied in

--subject <subject>

The subject the email will have, which helps the assistant stay on topic

--thread <thread-id>

Write a reply to this thread. The assistant reads its latest messages first

--tone <tone>

The tone to write in

One of"formal""friendly""casual""concise""direct""warm"

Examples

nextmail ai compose "thank Ada for the invoice and ask for a PDF copy" --to ada@example.com
Writes a reply after reading the thread
nextmail ai compose "say yes to Tuesday at 3pm" --thread thr_123 --tone friendly
Pipes the text into a send, which reads its body from stdin and needs `--from` to know the sender
nextmail ai compose "decline politely" --thread thr_123 | nextmail send --from you@acme.com --to ada@example.com --subject "Re: Proposal"
Prints the body with the inputs as JSON
nextmail ai compose "remind the team about Friday" --json

nextmail ai summarize

Print the AI summary of a thread

Scopesthreads:readNeeds a browser sign-inAliasessummarisesummary

Usage

nextmail ai summarize <thread-id>

Prints the short summary Nextmail keeps for a thread, with its subject, sender and date, and writes it first when there is none yet or new mail has arrived since. A thread holding an encrypted message gets no new summary, and summaries spend no AI actions. This uses the MCP tool getThreadSummary, so it needs a browser sign-in (nextmail login).

Arguments

<thread-id>Required

The thread to summarise, as nextmail inbox lists it

Examples

nextmail ai summarize thr_123
Prints the summary, subject, sender and date as JSON
nextmail ai summarize thr_123 --json
Reads the summary through the workspace your work profile signed in to
nextmail ai summarize thr_123 --profile work

nextmail mcp config

Print the snippet that connects an AI client to Nextmail

No sign-in needed

Usage

nextmail mcp config [--client <client>]

Prints what to add to an MCP client so it can read and act on your mail, and which file it goes in. There are two ways to connect. The remote server URL is the simplest: the client opens your browser, you approve it on the Nextmail consent page, and it appears in Account, Connected apps. Each client runs its own browser sign-in for the remote URL. The local bridge (nextmail mcp serve, started through npx) is for clients that only start local servers, and it reuses this CLI's sign-in, so run nextmail login first. With no --client, every client is printed in short form.

Flags

--client <client>

The client to print the full snippet for

One of"claude-code""claude-desktop""cursor""vscode""windsurf""codex"

Examples

Every client in short form
nextmail mcp config
nextmail mcp config --client claude-code
The local bridge serves the workspace your work profile signed in to
nextmail mcp config --client cursor --profile work
The snippets as JSON, for a setup script
nextmail mcp config --client vscode --json

nextmail mcp tools

List the MCP tools this sign-in can use

Needs a browser sign-inAliaseslist

Usage

nextmail mcp tools [tool]

Lists every tool the Nextmail MCP server offers to this sign-in, with the first sentence of its description. The list already leaves out tools your role or the app grant cannot use. Name one tool to see its full description and arguments. It needs a browser sign-in (nextmail login).

Arguments

<tool>

Show the description and arguments of this tool

Examples

nextmail mcp tools
Shows what composeEmail takes
nextmail mcp tools composeEmail
Prints only the tool names
nextmail mcp tools --json | jq -r '.[].name'

nextmail mcp call

Call one MCP tool and print its result

Needs a browser sign-in

Usage

nextmail mcp call <tool> [--args <json|@file|->] [--arg key=value ...]

Calls a tool on the Nextmail MCP server with your browser sign-in and prints the text it returns. --args gives every argument as one JSON object, and each --arg key=value sets or overrides one of them. A value is read as JSON when it parses (--arg maxResults=5 is a number, --arg labelIds='["Label_1"]' a list) and as text otherwise, so quote a number you mean as text (--arg 'id="123"'). A result that starts with Refused ( exits with code 4, and usually means your role or the app grant does not allow the tool. A tool that makes a sensitive change, such as creating a rule or removing a domain, first needs a verification code, as the same change does through the REST API. In an interactive terminal the command asks for the code and then calls the tool again. Unattended it exits with code 4, so run nextmail verify beforehand. The MCP server never asks for confirmation, so a tool that sends or deletes acts at once. Run nextmail mcp tools <tool> to see what a tool takes.

Arguments

<tool>Required

The tool to call, as nextmail mcp tools lists it

Flags

--args <json|@file|->

Every argument as one JSON object, from inline JSON, a file (@args.json) or stdin (-)

--arg <key=value>Repeatable

Set one argument. The value is JSON when it parses, text otherwise

Examples

nextmail mcp call whoAmI
nextmail mcp call listThreads --arg folder=inbox --arg maxResults=5
nextmail mcp call getThread --args '{"threadId":"thr_123"}'
Prints the full MCP result, including every content part
nextmail mcp call listTemplates --json | jq .content

nextmail mcp serve

Run a local stdio MCP server that forwards to Nextmail

Needs a browser sign-in

Usage

nextmail mcp serve

Reads newline-delimited JSON-RPC from stdin, sends each message to the Nextmail MCP server with your saved browser sign-in, and writes each answer to stdout as one line. Notifications produce no output, a batch is split into single requests and answered as one array, and an expired access token is refreshed without the client noticing. Nothing but protocol reaches stdout, and nothing reaches stderr unless you pass --debug, except one hint the first time a tool is refused because it needs a verification code. That refusal reaches the client unchanged, because the bridge cannot ask for a code over stdio. Run nextmail verify in a terminal with the same profile, and tools that make a sensitive change run without a code for the next 60 minutes. It stops when stdin closes. Use it for MCP clients that only start local servers; nextmail mcp config prints the snippet. It needs a browser sign-in (nextmail login), because API keys cannot reach the MCP server.

Examples

MCP clients start it as `npx -y @nextmail/cli mcp serve`. Sign in once with `nextmail login` first
nextmail mcp serve
Serves the workspace your work profile signed in to
nextmail mcp serve --profile work
Lists the tools by hand, one JSON line in and one out
echo '{"jsonrpc":"2.0","id":1,"method":"tools/list"}' | nextmail mcp serve
Logs each forwarded method and its status to a file
nextmail mcp serve --debug 2> mcp.log

nextmail docs ask

Ask the docs assistant a question

No sign-in needed

Usage

nextmail docs ask "<question>"

Sends your question to the Nextmail docs assistant and prints the answer as it is written, followed by the numbered pages it came from. The assistant answers only from the documentation, so it cannot see or change your mailbox. It needs no sign-in and never sends your credentials. Questions are limited to 600 characters and to a daily number per network, so for longer research open the docs with nextmail docs open.

Arguments

<question...>RequiredOne or more

What you want to know, in plain words

Examples

nextmail docs ask "how do I verify a domain?"
Quotes are optional
nextmail docs ask what does step-up mean for the CLI
Collects the answer and its sources into one JSON object
nextmail docs ask "which scopes does sending need?" --json | jq -r .answer

nextmail docs open

Open a docs page in your browser

No sign-in needed

Usage

nextmail docs open [slug] [--print]

Opens the Nextmail documentation, or the page you name. A slug is the part of the address after /docs/, such as cli/ai-and-mcp, and a full docs link works too. Over SSH, or with --print, it prints the link instead.

Arguments

<slug>

The page to open, such as get-started/welcome or cli/authentication

Flags

--print

Print the link instead of opening a browser

Examples

Opens the docs home
nextmail docs open
nextmail docs open cli/authentication
nextmail docs open cli/commands --print

nextmail docs read

Print a docs page as Markdown

No sign-in needed

Usage

nextmail docs read [slug]

Prints the Markdown version of a docs page, the same text the website serves at the page address with .md on the end. It is handy for reading in the terminal or handing a page to another tool. With no slug it prints llms.txt, the index of every page. It needs no sign-in.

Arguments

<slug>

The page to print, such as cli/commands. Leave it out for the index of every page

Examples

nextmail docs read cli/commands
Prints the index of every docs page
nextmail docs read
nextmail docs read get-started/welcome | less
nextmail docs read cli/scripting --json | jq -r .markdown

nextmail agents

A guide for AI agents and scripts that drive this CLI

No sign-in neededAliasesagent

Usage

nextmail agents
nextmail agents --json

Prints a short guide, in Markdown, for an AI agent such as Claude Code or Codex, or a script in CI: how to sign in without a person, why to pass --json and how to read errors and exit codes, how to find commands with --help --json, how to preview a change with --dry-run and when to pass --yes, how lists and streams page, what happens when a verification code or a scope is missing, and a few recipes to copy. With --json it prints the same guide as one JSON document. It needs no sign-in and sends nothing.

Examples

The guide as Markdown, ready to hand to an agent
nextmail agents
Save it next to your agent instructions
nextmail agents > NEXTMAIL.md
Only the recipes
nextmail agents --json | jq -r '.recipes[].commands[]'

nextmail verify

Enter a verification code now, so sensitive commands run for 60 minutes

Needs a browser sign-in

Usage

nextmail verify
nextmail verify --status
nextmail verify --force

With a browser sign-in, a sensitive change such as adding a webhook, creating or turning on a rule, or removing a domain asks for a verification code first, the way the web app does. Commands ask for it when they need it. nextmail verify asks for it now instead: it emails you a code, or asks for one from your authenticator app or a backup code when two-factor sign-in is on, and once the code is right, sensitive commands, nextmail mcp call and nextmail mcp serve run without a code for the next 60 minutes. Run it before a script or an AI client does something sensitive, because neither can type a code. It covers this profile only. An AI client connected through the remote server URL is a connected app of its own, so this does not cover it: allow that app with Allow changes for 60 minutes in its menu under Connected apps on the website (nextmail open apps). --status shows whether this sign-in is verified and until when. A code allows 5 tries. After 10 wrong codes for this sign-in within 24 hours, or 20 across all your connected apps, verification is paused, so the command says when it resumes and exits 4. API keys never need a code.

Flags

--status

Show whether this sign-in is verified and until when, without asking for a code

--force

Ask for a new code even when this sign-in is already verified, which starts a fresh 60 minutes

Examples

Asks for a code, then sensitive commands run without one for 60 minutes
nextmail verify
nextmail verify --status
Prints elevated, elevatedUntil, method and minutes for scripts
nextmail verify --status --json
Verifies the sign-in of another saved profile
nextmail verify --profile work

nextmail logout

Sign out and forget a saved profile

No sign-in needed

Usage

nextmail logout
nextmail logout --profile <name>
nextmail logout --all

A browser sign-in is revoked on the server first, which removes it from Account settings, Command line, and then forgotten on this device. The profile is forgotten even when the server cannot be reached, and the command says so. An API key is only forgotten: the key itself keeps working until you revoke it.

Flags

--all

Sign out of every saved profile

Examples

Signs out of the active profile
nextmail logout
nextmail logout --profile work
Signs out of every profile on this device
nextmail logout --all
Prints what was removed and whether the server confirmed it
nextmail logout --json

nextmail profile list

List the saved profiles

No sign-in needed

Usage

nextmail profile list
nextmail profile list --json

Shows every saved sign-in with its kind, workspace and user or key. The active profile is marked with a dot.

Examples

nextmail profile list
Never prints tokens or keys
nextmail profile ls --json

nextmail profile use

Make a saved profile the active one

No sign-in neededAliasesswitch

Usage

nextmail profile use <name>

Every command without --profile then uses this sign-in. With no name in an interactive terminal it lets you pick one.

Arguments

<name>Required

The profile to activate

Examples

nextmail profile use work
Pick from a list
nextmail profile use
nextmail profile use default --json

nextmail profile remove

Sign out of a profile and forget it

No sign-in needed

Usage

nextmail profile remove <name>

The same as nextmail logout --profile <name>: a browser sign-in is revoked on the server, then the profile is forgotten on this device either way.

Arguments

<name>Required

The profile to remove

Examples

nextmail profile remove work
nextmail profile rm staging --json

nextmail profile current

Print the profile the next command would use

No sign-in needed

Usage

nextmail profile current
nextmail profile current --json

Prints the profile name on stdout, so $(nextmail profile current) works in scripts. When NEXTMAIL_API_KEY or --api-key is in effect no profile is used, and it says so on stderr.

Examples

nextmail profile current
NEXTMAIL_PROFILE=work nextmail profile current
nextmail profile current --json

nextmail open

Open a page of the Nextmail web app in your browser

No sign-in needed

Usage

nextmail open [page] [--print]
nextmail open forwarding <address> [--print]

Opens the web app at the page you name, signed in as whoever is signed in to that browser. Use it for what the CLI does not do, such as account security, deleting your account, linking a DNS provider and talking with the assistant. With no page it opens the mailbox. forwarding takes the address whose forwarding you want to change. A path that starts with / is opened as it is. Over SSH, or with --print, it prints the link instead.

Arguments

<page>

One of the pages below, or a path such as /mail/workspace/domains

<address>

The address a forwarding page belongs to

Flags

--print

Print the link instead of opening a browser

Examples

Opens the mailbox
nextmail open
nextmail open billing
Command line, where each terminal sign-in is listed and can be signed out
nextmail open cli
Forwarding for one address
nextmail open forwarding you@acme.com
Link a DNS provider, so the records of a new domain are written for you
nextmail open providers
Prints the link instead of opening it
nextmail open domains --print

nextmail update

Check npm for a newer version of the CLI

No sign-in needed

Usage

nextmail update

Checks the npm registry now, ignoring the daily cache, and prints the command that installs the latest release with the package manager you used. The CLI never updates itself. When npm has no release of the CLI yet it says so and exits 0, and only a registry it could not reach exits 9.

Examples

nextmail update
Prints current, latest, published, updateAvailable and the install command
nextmail update --json

nextmail completion

Print a shell completion script for bash, zsh or fish

No sign-in needed

Usage

nextmail completion <bash|zsh|fish>

Prints a completion script built from every command, subcommand and flag this version of the CLI knows. Load it in your shell profile, and run the command again after an update.

Arguments

<shell>Required

bash, zsh or fish

Examples

Add this line to ~/.bashrc
eval "$(nextmail completion bash)"
Then start a new shell, or run compinit
nextmail completion zsh > "${fpath[1]}/_nextmail"
nextmail completion fish > ~/.config/fish/completions/nextmail.fish

nextmail api

Call any REST endpoint with your sign-in

Needs a sign-in

Usage

nextmail api <method> <path> [--data <json|@file|->] [--query <key=value>] [--header <key=value>]
nextmail api <path>

Sends one request to the Nextmail REST API through the same transport the other commands use, so your profile or API key, token refresh and verification codes all apply. The path is relative to the API origin, for example /threads or /keys/self, and a path on its own is a GET. A JSON response is printed as formatted JSON, and a file is saved with --out. A failed request prints the API error and exits with the matching code.

Arguments

<method>

GET, POST, PUT, PATCH, DELETE or HEAD (default GET)

<path>Required

Path on the API, such as /threads or /emails/msg_123

Flags

-d, --data <json|@file|->

Request body: inline JSON, @file to read a file, or - for stdin

-q, --query <key=value>Repeatable

Query parameter. Parameters written into the path are kept too

-H, --header <key=value>Repeatable

Extra request header. Key: value works too. The CLI sets Authorization itself

-o, --out <path>

Save the response body to this file as it came, which suits a download. - writes it to stdout

Examples

nextmail api /keys/self
nextmail api GET /threads --query folder=inbox --query limit=5
nextmail api POST /labels --data '{"name":"Receipts"}'
nextmail api PATCH /threads/CAHk7pQ2x9LmZ4 --data @patch.json
Saves the download as it came
nextmail api GET /files/file_123/content --out report.pdf
A DELETE asks to confirm first unless you pass --yes
nextmail api DELETE /webhooks/wh_123 --yes