nextmail emails
Every command in this namespace, with its arguments, flags and examples.
Commands
Send mail now or later, in batches or translated, and follow what happened to it.
Every command here also takes the global flags, such as --json, --profile and --dry-run. See the global flags
openemail emails send
Send, schedule or translate and send one email
Usage
nextmail emails send --from <value> --to <a,b> [flags] nextmail emails send --data <json|@file|-> [flags]
Sends one message now, or holds it for later with --scheduled-at or an undo window with --cancellable-for-seconds. The body comes from exactly one source: html and or text, a stored template, or an existing --draft-id. Naming none is a 422, and template alongside html, text or --draft-id is refused. An immediate send is dispatched inside the request, so the promise usually settles on a sent, partial or failed message. A held send settles as queued or scheduled, so read status rather than treating a resolved promise as delivered mail.
Every call carries an Idempotency-Key. The SDK generates one per call and reuses it on that call's retries, and the API claims it against the key's own unique index before anything is dispatched, so a retried network failure replays the original message instead of sending a second one. Pass --idempotency-key to extend that across processes and restarts, deriving it from what made the send necessary rather than from a clock. A replay resolves with replayed: true and the stored message in its current state. The same key with a different body is a 422 idempotency_key_reuse.
Add translate to deliver the message in the recipient's language. The translation runs when the request is accepted, before any record exists, so a scheduled send carries the approved wording and a translation that cannot be produced refuses the whole send: nothing is ever delivered untranslated as a fallback. By default the subject is translated too and your original text is placed below the translation, captioned in the target language. It works with template, translating what the template rendered, and is refused alongside --draft-id because a draft goes as it was written.
Flags
--from <value>Sender as
[email protected],Acme Billing <[email protected]>or{ email, name }. It must be an address the key may send as, otherwise 403from_address_forbidden. Required, here or in--data.--to <a,b>RepeatableOne recipient or a list.
to,ccandbcctogether hold at most 50 addresses, and more is a 422too_many_recipients. Required, here or in--data.--cc <a,b>RepeatableCopy recipients, counted toward the 50 recipient ceiling.
Default[]--bcc <a,b>RepeatableBlind copy recipients, counted toward the 50 recipient ceiling.
Default[]--reply-to <value>Written into the
Reply-Toheader.--subject <value>At most 998 characters. Falls back to the template or draft subject when empty.
Default""--html <value>HTML body, at most 1,000,000 characters.
--text <value>Plain text body, at most 1,000,000 characters.
--template <json|@file|->A stored template by id or slug. Omitting
versionresolves whatever is published at that moment, so pin it when somebody else owns the copy. JSON shaped as{ id: string, version?: number, props?: Record<string, unknown>, slots?: Record<string, unknown> }, inline or from a file with @path.--draft-id <value>Sends an existing draft as written. Cannot be combined with
templateortranslate.--thread-id <value>Files the sent message into an existing thread.
--headers <json|@file|->RepeatableCustom headers limited to
X-*,List-*,Reply-To,Precedence,Auto-Submitted,Importance,PriorityandFeedback-ID. Anything the server sets itself is a 422reserved_header.Default{}--attachments <json|@file|->At most 20 files. Each entry is an inline file, with
filenameandcontentas bytes or a base64 string (bytes are encoded for you, and inline files are capped at 10 MB in total once decoded), a file at an https address as{ url, filename?, contentType? }, fetched once when the message is accepted, or a stored file as{ fileId }naming a file already uploaded to the workspace, up to 100 MB. Inline andurlfiles come to at most 25 MB together; an address that cannot be fetched is a 422attachment_unreachable. JSON shaped asArray<AttachmentInput>, inline or from a file with @path.Default[]--attachment-delivery <value>How the files in
attachmentstravel.mimecarries them inside the message, so files that come to more than 25 MB together are refused.linkuploads each file and puts a download link in the body in its place, so the message itself stays small.autolinks when the files together come to more than 25 MB, or to more than 2 MB when thefromdomain has an active files domain, and attaches them otherwise. Left out, the sender's mailbox setting applies, and that defaults toauto.--scheduled-at <when>A
Date, an ISO 8601 instant or a duration such asPT1HorP2D. At least one second and at most 365 days out.--follow-up-at <when>Asks to be reminded if nobody replies: a
Date, an ISO 8601 instant or a duration from now such asP3D, later than the time the message goes out and at most 365 days out. If no real reply has arrived by then, the thread returns to the top of the inbox, unread, with a push.followUps.listlists the reminders andfollowUps.cancelcancels one.--cancellable-for-seconds <n>An undo window from 0 to 900 seconds on an immediate send. Refused alongside
--scheduled-at, which is already cancellable until it goes.Default0--tracking <json|@file|->Overrides the tracking setting for this send. A field left out takes the setting of the address it is sent from: its own, else its domain catch-all's when the catch-all caught that address, else off. JSON shaped as
{ opens?: boolean, clicks?: boolean }, inline or from a file with @path.--signatureAn
htmlbody goes out exactly as written, so it carries a signature only when this istrue, while atext-only body carries one unless this isfalse. When it is added it is the default signature of the address it is sent from: the one it keeps for replies when the message answers a thread (--thread-idor anIn-Reply-Toheader), and the one for new mail otherwise. An address with no signature of its own takes its domain catch-all's when the catch-all caught that address, else the Nextmail footer unless that address turned the footer off.--signature-idpicks another signature of the address. Template sends and encrypted sends never carry one.--signature-id <value>Adds one particular signature of the
fromaddress in place of its default, by the idsignatures.listreturns. It signs anhtmlbody too, sosignature: trueis not needed with it, and it cannot be combined withsignature: false. An id that is not a signature of thefromaddress is a 422invalid_parameter. When the signature is deleted before a scheduled message goes out, the message carries the default of the address instead.--tags <json|@file|->RepeatableUp to 10 tags, keys of 1 to 64 letters, digits,
_or-, values up to 256 characters. Echoed back on every read.Default{}--stream <value>The lane the message travels in:
transactional, the default, for mail one person is waiting for, orbroadcastfor newsletters and other mail to many people. Each lane has its own queue and its own reputation.--translate <json|@file|->{ to, from?, includeOriginal?, subject? }.totakes a code, an English name or an endonym.includeOriginalandsubjectboth default to true. JSON shaped asSendTranslateOptions, inline or from a file with @path.--idempotency-key <value>Your own key, 1 to 255 characters of letters, digits,
_,.,:or-. Anything else is a 400invalid_idempotency_key.--data <json|@file|->The whole
bodyas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails send --from 'Acme Billing <[email protected]>' --to [email protected]nextmail emails send --from 'Acme Billing <[email protected]>' --to [email protected] --subject 'Your September invoice' --html '<p>The invoice is attached. Tell me if anything on it looks wrong.</p>' --idempotency-key invoice:inv_2026_09_4192nextmail emails send --data @email.jsonAlso available in
- API
POST /emails- TypeScript
nextmail.emails.send()- Python
emails.send()- Ruby
emails.send- PHP
emails->send- Go
Emails.Send- Java
emails().send- C#
Emails.SendAsync
openemail emails send-batch
Send up to 100 independent emails in one request
Usage
nextmail emails send-batch <emails> [flags]
Sends each message in order, as if emails.send had been called for it, and reports per item. It is never all or nothing: a bad address on item 7 fails item 7 and the rest still go, because a batch that rolled back would turn your retry into a guess about which messages had already been delivered. The promise resolves whenever the batch was processed, so check failed and each item's status rather than relying on a throw.
The batch shares one Idempotency-Key, generated once per call or supplied as --idempotency-key, and the server derives a separate key per item from it and the item's position. Retrying the same array replays the items that already went and sends only the ones that did not. Reordering the array between attempts changes which body each position's key is bound to, so an item that moved comes back as an idempotency_key_reuse error.
Apart from a key or scope failure or a server fault, only problems with the batch as a whole reject the promise with a 422: an empty array, more than 100 messages, or more than 10 messages carrying translate. Translation costs several model calls per message and they run one after another, so a larger translated batch would time out partway. Split it, or schedule the messages instead.
Arguments
<emails>RequiredBetween 1 and 100 messages, each shaped exactly like the body of
emails.send,followUpAtincluded, and validated on its own.
Flags
--idempotency-key <value>Your own batch key, 1 to 255 characters of letters, digits,
_,.,:or-.
Examples
nextmail emails send-batch ./emails.jsonnextmail emails send-batch ./emails.json --idempotency-key shipments:2026-09-15Also available in
openemail emails translate
Preview a translation without sending anything
Usage
nextmail emails translate --to <value> [flags] nextmail emails translate --data <json|@file|-> [flags]
Runs the same translation translate performs on a send and stops one step early. The same function produces both, so what comes back is what would go out. Nothing is stored and nothing is sent. Use it when somebody should read the translated wording before it reaches a recipient.
Send the approved result as an ordinary subject and html on emails.send with no translate option. Passing translate again translates a second time, moving the wording off the version that was signed off and discarding any edits. When --include-original is on, html already contains your original text below the translation, so do not append your own copy.
At least one of html, text or subject is required. to accepts a BCP-47 code, an English name or the language's own name, and the response reports the code it settled on in language.code, which is the form worth storing. State from to skip language detection. Otherwise it is detected from the body, and a detector that cannot tell returns null in detectedSourceLanguage rather than guessing.
Flags
--to <value>Target language as a code (
de), English name (German) or endonym (Deutsch). An unrecognised value is a 422invalid_parameteronto. Required, here or in--data.--from <value>The language you wrote in. Stating it skips the detection call.
--include-originalDefaults to true, placing your original text below the translation under a caption in the target language.
Defaulttrue--subject <value>Subject line to translate, at most 998 characters.
--html <value>HTML body to translate. Only the content inside
<body>is sent to the model when the markup is a full document.--text <value>Plain text body to translate. Translated separately when given alongside
html.--data <json|@file|->The whole
bodyas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails translate --to janextmail emails translate --to ja --from 'Acme Billing <[email protected]>' --subject 'Your September invoice' --html '<p>The invoice is attached.</p>'nextmail emails translate --data @email.jsonAlso available in
openemail emails check
Check how a message would be rated, without sending it
Usage
nextmail emails check [flags]
Scores a message the way a receiving mailbox would, before it goes out: a spam score, a phishing score and an AI-writing score, each 0 to 100, with the signals behind each one. Nothing is stored and nothing is sent.
The same checks score every message that arrives in a mailbox on Nextmail, so what comes back is what a recipient on Nextmail sees in Details. It cannot know a recipient's own filter, sender history or reputation, so a low score is a good sign and not a delivery guarantee.
Run it before an automated send, or as someone writes, and fix what signals names. Sender authentication is taken as passing, since the message will be signed for your domain.
Flags
--subject <value>Subject line, at most 998 characters.
Default""--html <value>HTML body. Links and images are read from it.
--text <value>Plain text body. Taken from
htmlwhen left out.--from <value>The address it will be sent from.
--from-name <value>The display name it will carry. A name that claims another address or a known brand raises the phishing score.
--reply-to <value>A Reply-To on a different domain raises the phishing score.
--replyingTrue when it answers an existing thread. A
Re:subject on a message that answers nothing raises the spam score.--attachment-names <a,b>RepeatableFile names, so an attachment that can run code is caught.
--data <json|@file|->The whole
bodyas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails checknextmail emails check --subject 'Your September invoice' --html '<p>The invoice is attached.</p>' --from [email protected]Also available in
- API
POST /emails/check- TypeScript
nextmail.emails.check()- Python
emails.check()- Ruby
emails.check- PHP
emails->check- Go
Emails.Check- Java
emails().check- C#
Emails.CheckAsync
openemail emails list
List one page of sent emails, newest first
lsUsage
nextmail emails list [flags]
Returns one page of the workspace's send records, ordered newest first. Paging is keyset rather than offset: nextCursor is the id of the last message on the page, and passing it back as cursor continues strictly after it, so messages sent while you page never shift or repeat rows. hasMore is false on the last page and nextCursor is then null.
Filter with status, one value or an array that the SDK joins with commas, with from, which matches the sending address exactly and ignores case, with --broadcast-id, which keeps the copies of one broadcast, and with --scheduled-from and --scheduled-to, which keep the messages scheduled inside a window. An unrecognised status is a 422 invalid_parameter naming the offending values, and a cursor that names no message in the workspace is a 400 invalid_cursor.
Rows are the summary form. They never carry recipients or translation, whose absence on a row says nothing either way, and a tracked message carries only the counts half of tracking: opens, clicks, opened, clicked, openCount, clickCount and firstOpenAt. Call get for per-recipient delivery state and getTracking for the full engagement report.
Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.
Flags
--status <a,b>RepeatableOne or more of
queued,scheduled,sending,sent,partial,bounced,cancelledandfailed.--from <value>A bare sending address such as
[email protected], matched exactly and case insensitively. A display name form does not match.--broadcast-id <value>Only the copies of one broadcast, a
brd_id frombroadcasts.send. Each person a broadcast reaches gets a message of their own, so this lists who it went to and what happened to each copy. An id that names no broadcast answers an empty page.--scheduled-from <when>Only messages scheduled for this instant or later. With
--scheduled-toandstatus: ['scheduled', 'queued']it lists what is waiting to go out in a window, as the calendar of the app does. A message with noscheduledAtis left out.--scheduled-to <when>Only messages scheduled for this instant or earlier.
--scheduled-fromafter--scheduled-tois a 422invalid_parameter.--since <when>Only messages made at this instant or later.
--until <when>Only messages made before this instant.
sinceafteruntilis a 422invalid_parameter.--recipient <value>Only messages that went to this address as a to, cc or bcc recipient, matched exactly.
--tag <value>Only messages sent with this tag:
namefor any value, orname:valuefor one value. Tags are stored encrypted, so the match is exact and case-sensitive.--limit <n>Rows per page, a whole number from 1 to 100, defaulting to 25. Outside that range is a 422.
Default25--cursor <value>The
nextCursorfrom the previous page, which is a message id.--allFetch every page and stream the items as they arrive.
--max <n>Stop after this many items. Implies
--all.--ndjsonPrint every item as one JSON object per line. Implies
--all
Examples
nextmail emails listnextmail emails list --status failed,partial --from [email protected] --limit 50nextmail emails list --all --max 100nextmail emails list --all > emails.ndjsonAlso available in
- API
GET /emails- TypeScript
nextmail.emails.list()- Python
emails.list()- Ruby
emails.list- PHP
emails->list- Go
Emails.List- Java
emails().list- C#
Emails.ListAsync
openemail emails get
Read one sent email with per-recipient state
showviewUsage
nextmail emails get <id> [flags]
Returns the full send record for one message: its lifecycle status, delivery attempts and lastError, the schedule fields, and the two parts a list row leaves out. recipients has one entry per address with its own status, error and deliveredAt, and translation records what was done to a translated send.
A message that went out as a single call can still land differently per recipient. status on the message says how the send went as a whole, while each recipient moves on as delivery reports, bounces and complaints arrive. uncertain is a real recipient state: a transport that failed partway cannot say which recipients it reached. suppressed marks an address that previously bounced or complained in this workspace and was held back.
When the message was tracked, tracking carries the full engagement report with per-recipient and per-link detail. When it was not tracked, the field is absent rather than zeroed, because a message with no pixel has no evidence about whether anybody read it.
Arguments
<id>RequiredThe send id,
msg_followed by 24 hex characters, as returned bysend.
Examples
nextmail emails get msg_3f9a1c07d2b84e6a9c5b1f20nextmail emails get msg_3f9a1c07d2b84e6a9c5b1f20 --jsonAlso available in
- API
GET /emails/{id}- TypeScript
nextmail.emails.get()- Python
emails.get()- Ruby
emails.get- PHP
emails->get- Go
Emails.Get- Java
emails().get- C#
Emails.GetAsync
openemail emails list-events
Read one page of the event trail of one sent email
Usage
nextmail emails list-events <id> [flags]
Returns one page of everything recorded against one send, oldest first. It is the audit behind the current status: when the message was accepted or held, when it was rescheduled or cancelled, when it went out or failed, and every delivery report, bounce, complaint, open, click and file download attributed to it afterwards.
Each event has a dotted type and a data object whose shape depends on it. email.accepted, email.queued and email.scheduled open the trail with the source and recipient count. email.sent names the transport and messageId. email.failed carries the error. email.bounced and email.complained list the affected recipients and whether they were suppressed. email.delivered, email.rescheduled, email.cancelled, email.opened, email.clicked and email.downloaded follow as they happen. email.downloaded counts a person fetching a file that went out as a download link, never a scanner, and carries no recipient: the link is the same for everyone the message went to, so a download cannot be attributed. data is an empty object when an event carries nothing.
Webhooks deliver a subset of these same events as they occur, so this is where to look when a webhook was missed or never subscribed.
Add --all to walk every page: a table on a terminal, one JSON object per line when piped or with --ndjson, and one { items, hasMore, nextCursor } document with --json. --max <n> stops after that many items.
Arguments
<id>RequiredThe
msg_send id whose trail to read.
Flags
--limit <n>Events per page, a whole number from 1 to 100, defaulting to 25.
Default25--cursor <value>The
nextCursorfrom the previous page, which is an event id. One that names no event of this send is a 400invalid_cursor.--allFetch every page and stream the items as they arrive.
--max <n>Stop after this many items. Implies
--all.--ndjsonPrint every item as one JSON object per line. Implies
--all
Examples
nextmail emails list-events msg_3f9a1c07d2b84e6a9c5b1f20nextmail emails list-events msg_3f9a1c07d2b84e6a9c5b1f20 --limit 100nextmail emails list-events msg_3f9a1c07d2b84e6a9c5b1f20 --all --max 100nextmail emails list-events msg_3f9a1c07d2b84e6a9c5b1f20 --all > emails.ndjsonAlso available in
openemail emails get-tracking
Read the engagement report for a sent email
Usage
nextmail emails get-tracking <id> [flags]
Returns the same document tracking.get serves, reached from the msg_ id a sender already holds. It has the message totals, one entry per tracked copy under recipients, and every rewritten link with its clicks under links.
A message that was never tracked is a 404 here rather than an empty report. "We were not recording" and "nobody opened it" are different answers, and a client that renders them the same way makes a claim about a reader on no evidence. Tracking applies per send: opens and clicks record what was applied when the message went out, resolved from the setting of the address it was sent from (its own, else its domain catch-all's when the catch-all caught that address, else off) and any tracking override on the send, not what is switched on now.
Read every count as a floor. An open is inferred from a mail client fetching an image, so a reader whose client blocks images is never counted, and Gmail fetches the image once through its proxy and serves later views from cache. A click is stronger evidence than an open.
Arguments
<id>RequiredThe
msg_send id returned bysend.
Examples
nextmail emails get-tracking msg_3f9a1c07d2b84e6a9c5b1f20nextmail emails get-tracking msg_3f9a1c07d2b84e6a9c5b1f20 --jsonAlso available in
openemail emails cancel
Stop a queued or scheduled email before it goes
Usage
nextmail emails cancel <id> [flags]
Cancels a message that has not been dispatched yet: a send held by scheduledAt, or an immediate send still inside its cancellableForSeconds undo window. The message moves to cancelled, nothing is delivered, and an email.cancelled event is recorded and sent to subscribed webhooks.
Only queued and scheduled messages can be cancelled. Once a message is sending, sent, partial, bounced or failed the call is a 409 email_not_cancellable, since there is no pending dispatch left to stop and mail that has gone cannot be recalled. An immediate send with no undo window is dispatched inside the send request, so by the time you hold its id it is usually past this point.
Cancelling is idempotent. Cancelling an already cancelled message resolves with the same cancelled message rather than an error, and the SDK retries the call after a network failure or a retryable status.
Arguments
<id>RequiredThe
msg_send id to cancel.
Examples
nextmail emails cancel msg_3f9a1c07d2b84e6a9c5b1f20nextmail emails cancel msg_3f9a1c07d2b84e6a9c5b1f20 --yesAlso available in
- API
POST /emails/{id}/cancel- TypeScript
nextmail.emails.cancel()- Python
emails.cancel()- Ruby
emails.cancel- PHP
emails->cancel- Go
Emails.Cancel- Java
emails().cancel- C#
Emails.CancelAsync
openemail emails reschedule
Move a queued or scheduled email to a new send time
Usage
nextmail emails reschedule <id> <scheduled-at> [flags]
Changes when a message that has not gone yet will be dispatched. scheduledAt is the only thing this call can change, and the SDK sends nothing else: the body, recipients and any translation stay exactly as they were accepted.
The new time takes a Date, an ISO 8601 instant or a duration such as PT30M or P2D, measured from when the server receives the request. It must be at least one second in the future and at most 365 days out, otherwise the call is a 422 on scheduledAt, usually invalid_parameter. Earlier and later times are both allowed.
Only queued and scheduled messages can be moved. Anything already sending, sent, partial, bounced, cancelled or failed is a 409 email_not_cancellable. A queued message inside its undo window can be rescheduled too, which turns it into a scheduled send that stays cancellable until the new time.
Arguments
<id>RequiredThe
msg_send id to move.<scheduled-at>RequiredThe new send time. A
Dateis serialised withtoISOString(), and a string is passed through as an instant or a duration.
Examples
nextmail emails reschedule msg_3f9a1c07d2b84e6a9c5b1f20 2026-10-01T00:00:00Znextmail emails reschedule msg_3f9a1c07d2b84e6a9c5b1f20 2026-10-01T00:00:00Z --jsonAlso available in
openemail emails update
Change an email that has not gone yet
editUsage
nextmail emails update <id> [flags]
Changes a queued or scheduled message before it is dispatched: when it goes with --scheduled-at, what it says with subject, html and text, the address it goes out as with from, and who it goes to with to, cc and bcc. Send any of them together, and a field you leave out keeps its value. This is what editing a scheduled message in the calendar of the app does.
A recipient list replaces the stored one whole, and takes a string such as Ada <[email protected]>, an object with email and name, or an array of either. from is checked as it is on a send, so it has to be an address the key may send as, or the call is a 403 from_address_forbidden.
Only messages that have not gone can change. Anything already sending, sent, partial, bounced, cancelled or failed is a 409 email_not_cancellable. A message translated when it was accepted keeps its approved wording, so a new subject, html or text on it is a 409 translation_locked, and one that was encrypted before it was scheduled keeps its wording and its recipients. Cancel those and send again instead.
Arguments
<id>RequiredThe
msg_send id to change.
Flags
--scheduled-at <when>A new send time: a
Date, an ISO 8601 instant or a duration such asPT2H, in the future and at most 365 days out.--subject <value>The new subject, up to 998 characters.
--html <value>The new HTML body.
--text <value>The new plain text body.
--from <value>The address it goes out as instead, one the key may send as.
--to <a,b>RepeatableReplaces the recipients, at least one and at most 50 across the three lists.
--cc <a,b>RepeatableReplaces the copied recipients.
--bcc <a,b>RepeatableReplaces the blind copied recipients.
--data <json|@file|->The whole
patchas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails update msg_3f9a1c07d2b84e6a9c5b1f20 --subject 'Your September invoice, corrected' --to [email protected],[email protected]nextmail emails update msg_3f9a1c07d2b84e6a9c5b1f20 --subject 'Your September invoice, corrected' --to [email protected],[email protected] --jsonAlso available in
- API
PATCH /emails/{id}- TypeScript
nextmail.emails.update()- Python
emails.update()- Ruby
emails.update- PHP
emails->update- Go
Emails.Update- Java
emails().update- C#
Emails.UpdateAsync
openemail emails compose
Write an email with AI
Usage
nextmail emails compose --prompt <value> [flags] nextmail emails compose --data <json|@file|-> [flags]
Writes the body of an email from prompt, an instruction, a rough draft or a few notes, in the style of the mail this workspace has sent before, as the composer of the app does. subject, to and cc help the greeting and the tone fit, and from, the address it goes out as, has it written as that address.
Give --thread-id to write a reply: the messages of that thread are read as context, which also needs threads:read, and a key limited to particular addresses can only use a thread that arrived at them.
Give draft, the body written so far, and prompt says what to change in it, as the describe bar of the composer does. withSubject: true adds subject to the answer. Give send, the send options as they stand, even {}, and prompt may change the recipients, the send time, tracking, the signature and the language: the answer's send holds only what changed, in the shape emails.send takes, and null takes an option away. Add send.fromOptions, the addresses it may go out as, and prompt may move it to one of them, which the answer names in send.from. Add send.encrypt, whether it is encrypted end to end as it stands, only when every recipient can receive encrypted mail, and prompt may turn encryption on or off. Times such as "tomorrow at 9" are read in --time-zone, or the time zone of the account.
Give templates: true and prompt may switch the email to one of the workspace's published templates, which the answer names in template: pass template: { id: template.id } to emails.send in place of body, because the template's body replaces it. Give template, the id of the template the email uses now, and prompt leaves the body alone. Give files: true and prompt may attach files the workspace holds, found by their name: the answer lists them in attach, each ready to pass to emails.send as { fileId: id } in attachments, and names in attachMissing what matched no file. templates needs templates:read and files needs files:read, and each is ignored without its scope. A key limited to particular addresses only finds the files at those addresses.
Nothing is saved or sent. Pass body to emails.send or drafts.create when it reads right. Each call spends one of the workspace's AI actions, and a workspace that has used them all for the day is refused with a 429 ai_quota_exceeded.
Flags
--prompt <value>What to write, up to 20,000 characters. With
draft, what to change in it, and it may be empty to have the draft finished as it is. Required, here or in--data.--subject <value>The subject so far, if there is one.
--from <value>The address it goes out as, so it is written as that address.
--template <value>The id of the template the email uses now, up to 128 characters. Its body is then the template, so
promptleaves the body alone.--templatesLet
promptswitch the email to one of the workspace's published templates, which the answer names intemplate. Needstemplates:read, and without it this is ignored.--filesLet
promptattach files the workspace holds, found by their name. The answer lists them inattach, each ready to send as{ fileId: id }, and what matched no file inattachMissing. Needsfiles:read, and without it this is ignored.--with-subjectAlso write a subject. The answer then carries
subject.--draft <value>The body written so far, as text or Markdown, up to 20,000 characters.
promptthen says what to change in it.--to <a,b>RepeatableWho it goes to.
--cc <a,b>RepeatableWho is copied.
--bcc <a,b>RepeatableWho is blind copied.
--send <json|@file|->{ scheduledAt?, tracking?, signature?, translate?, fromOptions?, encrypt? }, the send options as they stand. Give it, even{}, to letpromptchange them.fromOptionslists up to 100 addresses it may go out as, sopromptcan move it to one of them, andencryptsays whether it is encrypted end to end: give it only when every recipient can receive encrypted mail, sopromptcan turn encryption on or off. JSON shaped asEmailComposeSend, inline or from a file with @path.--time-zone <value>The IANA time zone to read times in, such as
Europe/Berlin. Without it, the time zone of the account.--thread-id <value>A thread to reply in, read as context.
--data <json|@file|->The whole
bodyas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails compose --prompt 'Send Ada the signed contract and ask for the invoice by Friday.'nextmail emails compose --prompt 'Send Ada the signed contract and ask for the invoice by Friday.' --from [email protected] --files --with-subjectnextmail emails compose --data @email.jsonAlso available in
openemail emails rewrite
Rewrite part of an email with AI
Usage
nextmail emails rewrite --text <value> --action <value> [flags] nextmail emails rewrite --data <json|@file|-> [flags]
Rewrites a subject or a body and resolves different versions of it, as the rewrite menu of the composer does. action is shorten, lengthen, rephrase, formal, casual or custom, and custom needs instruction to say what to change, or the call is a 422 invalid_parameter on instruction. target is body, the default, or subject, and count asks for 1 to 5 versions, 3 by default.
Give --thread-id when the text is a reply, so the rewrite fits the conversation. That also needs threads:read. The versions never repeat the original and never add facts that are not in it.
Nothing is saved. Each call spends one of the workspace's AI actions.
Flags
--text <value>The subject or body to rewrite. Required, here or in
--data.--action <value>What to do:
shorten,lengthen,rephrase,formal,casualorcustom. Required, here or in--data.--target <value>bodyorsubject. Defaults tobody.Default"body"--instruction <value>What to change, up to 500 characters. Required with
custom.--count <n>How many versions, 1 to 5. Defaults to 3.
Default3--thread-id <value>The thread the text replies in, read as context.
--data <json|@file|->The whole
bodyas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails rewrite --text 'Hey, just checking whether you had a chance to look at the contract?' --action formalnextmail emails rewrite --data @email.jsonAlso available in
openemail emails suggest-subject
Suggest a subject line
Usage
nextmail emails suggest-subject --message <value> [flags] nextmail emails suggest-subject --data <json|@file|-> [flags]
Reads the body of an email and resolves a short subject for it, under 100 characters, in the style of the mail this workspace has sent, as the subject button of the composer does.
Nothing is saved. Each call spends one of the workspace's AI actions.
Flags
--message <value>The body of the email, as text or HTML. Required, here or in
--data.--data <json|@file|->The whole
bodyas JSON, inline, from a file with @path, or - for standard input. Flags override its keys.
Examples
nextmail emails suggest-subject --message 'Thanks for the signed contract. Could you send the invoice by Friday?'nextmail emails suggest-subject --data @email.json