Skip to the documentation
CLI

Mail

Send with any body and attachments, read and search the mailbox, reply, file threads, and use disposable inboxes.

Send

Terminal
nextmail send --to [email protected] --subject "Lunch?" --text "Thursday at noon works for me."

The body comes from the first of these that is there:

  1. --text and --html, both together if you want both parts.
  2. --body-file <path>. A .html or .htm file is sent as HTML and anything else as text, and - reads stdin.
  3. Whatever is piped on stdin. Input that starts with an HTML tag is sent as HTML.
  4. Your editor ($VISUAL, then $EDITOR), when you run it in a terminal.

Without --from, the CLI sends from the only address you can send from, or lets you pick one in a terminal. Unattended with more than one, it stops and asks for --from. Piping the body in counts as unattended, so a piped send needs --from too. In a terminal you see a summary and confirm before anything goes, which --yes skips.

FlagWhat it does
--to, --cc, --bccRecipients, comma separated or repeated. Ada Lovelace <[email protected]> works too
--from, --reply-toThe sending address, and the Reply-To header
-s, --subjectThe subject line
-a, --attach <path>Attach a file. Repeat it for more
--at <when>Send later: an ISO time such as 2026-10-01T09:00:00Z, or a delay such as 10m, 2h, 1d or PT1H
--undo <seconds>Hold an immediate send for up to 900 seconds, so it can still be cancelled
--translate <language>Translate the email into this language before it goes
--template <id>, --props <json>Send a stored template with its props instead of a body
--draft <id>Send the body of a saved draft, with its subject unless you pass --subject. --to and --from still apply
--thread <id>File the sent email into this thread
--tag <key=value>Tag the email. Repeat it for more
--idempotency-key <key>Running the command again with the same key never sends twice
More sends
cat report.md | nextmail send --from [email protected] --to [email protected] --subject "Weekly report" --attach chart.pngnextmail send --to [email protected] --subject "Invoice" --body-file invoice.html --translate de --at 2hnextmail send --to [email protected] --template welcome --props '{"name":"Ada"}' --tag campaign=onboarding

It prints the email id and its status. sent, partial and failed mean the send was tried within the request, and queued and scheduled mean it is held. A failed send exits with code 1, and --json prints the whole email.

Every send carries an idempotency key, yours or one the CLI makes up, so a retry after a dropped connection never sends the message twice. Pass your own when a pipeline may run the same step again.

Attachments

--attach takes up to 20 files. While they come to 5 MB or less in total, they travel inside the message. When they come to more, each one is uploaded to Files first and the message refers to it, so a large file needs no extra step. The content type comes from the file extension.

Inbox

Terminal
nextmail inboxnextmail inbox --unread --limit 50nextmail inbox archive --sort oldestnextmail inbox --all --json | jq -r ".items[].id"

Lists one page of threads, newest first, with when each last moved, who wrote last, the subject, the labels and the thread id. A dot marks unread mail. The folder is the inbox unless you name another: sent, archive, starred, snoozed, spam, trash, draft, or a label id such as USER_RECEIPTS.

  • -u, --unread keeps threads with unread mail, -l, --label keeps threads that carry a label, and -q, --query narrows the list with a search.
  • -n, --limit sets the page size, from 1 to 100 (25 unless you say). When more remain, the next cursor is printed on stderr for --cursor, and --all reads every page.
  • --from-contacts keeps threads whose newest message came from a saved contact, and --sort orders them by newest, oldest, sender or subject. --semantic matches the words of --query by meaning, best match first.
  • --json prints { items, hasMore, nextCursor }, with every thread whole.

Read a thread

Terminal
nextmail read CAHk7pQ2x9LmZ4nextmail read CAHk7pQ2x9LmZ4 --message -1nextmail read CAHk7pQ2x9LmZ4 --html --message 1 > first.html

Prints every message on the thread, oldest first: who sent it and to whom, 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 that keeps its lists, quotes, headings and links. Reading marks the thread read, unless you pass --no-mark-read.

  • -m, --message <n> shows one message, counting from 1, or from the newest with a negative number.
  • --html prints only the raw HTML of one message on stdout, with the headers on stderr, so it can go straight into a file. On a thread with more than one message it needs --message.
  • An encrypted message is not decrypted here, so open it in the web app.

Reply

Terminal
nextmail reply CAHk7pQ2x9LmZ4 --text "Thanks, that works for me."nextmail reply CAHk7pQ2x9LmZ4 --all --attach notes.pdfecho "Confirmed." | nextmail reply CAHk7pQ2x9LmZ4 --yes

Replies in the same thread to whoever sent the last message, or to its Reply-To address. When the last message is yours, 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 has it already, and the reply goes from the address the thread was delivered to when you can send from it.

It takes the body, attachment, scheduling, translation, tag and idempotency flags of send, with --from and --subject, and --to, --cc and --bcc override the recipients.

File threads

CommandWhat it does
archive <thread-id...>Out of the inbox, still searchable
unarchive <thread-id...>Back into the inbox
trash <thread-id...>To the Bin. It asks you to confirm, because no call takes a thread back out
star, unstarAdd or remove the star
mark read, mark unreadMark threads read or unread
snooze <thread-id...> --until <when>Hide threads until a time, or for a delay such as 3h or 1w. They come back within about an hour of it
unsnoozeBring snoozed threads back now
label add, remove --label <id>Put labels on threads or take them off. nextmail labels list shows the ids

Each takes several thread ids and reports on each one. The first failure sets the exit code, and --json prints { results, succeeded, failed }. Ids from a search chain straight in:

Terminal
nextmail inbox --query "newer_than:30d from:alerts" --json | jq -r ".items[].id" | xargs nextmail archive

Disposable inboxes

nextmail temp makes short-lived addresses that need no account and no sign-in, which suits sign-up tests and one-time codes. Each inbox token is kept in ~/.nextmail/temp-mail.json, so later commands find an inbox by its id or address, or on their own when you have only one.

Terminal
ADDRESS=$(nextmail temp new --ttl 15)nextmail temp watch --first --json | jq -r .snippetnextmail temp listnextmail temp readnextmail temp read tinb_k7m2q9xw4bdp thr_91c3e07a5d2b8f4c61a9e0d7nextmail temp delete --yes
  • temp new prints only the address on stdout. It lives for 60 minutes unless --ttl says otherwise, for up to 24 hours, and --name and --domain choose the address.
  • temp watch prints what has arrived, then checks every 3 seconds until you stop it or the inbox expires. --first stops at the first message, and --json prints one JSON line per message.
  • temp read lists the messages with a short preview, or prints one whole message, and --html prints only its raw HTML on stdout.
  • temp delete moves the mail the inbox shows to the bin at once and forgets its token here. The lease itself runs on until its expiry, and nothing holds the address back.
  • --inbox-token reaches an inbox this CLI did not create, in temp read, watch and delete.
  • The sender of mail in a disposable inbox is never verified.
  • A saved inbox token goes only to the API that issued it, so temp read, watch and delete stop with exit code 2 when --base-url or NEXTMAIL_BASE_URL names another one.