## Top-level commands for the jobs agents and people do most

Send a message, read one with its trust verdict, wait for a message or a verification code, and follow events live.

| Command | Summary |
| --- | --- |
| [`send`](/content/docs/cli/commands/mail#send/index.html) | Send an email from an inbox |
| [`read`](/content/docs/cli/commands/mail#read/index.html) | Show a message: headers, trust verdict and agent-safe text |
| [`wait`](/content/docs/cli/commands/mail#wait/index.html) | Wait for a message to arrive (and extract a code or magic link with —otp) |
| [`tail`](/content/docs/cli/commands/mail#tail/index.html) | Follow live events (messages, deliveries, inboxes) as they happen |

Every command also takes the [global flags](/content/docs/cli/commands#global-flags/index.html).

## [send](/content/docs/cli/commands/mail#send/index.html)

Send an email from an inbox.

Sends through POST /v0/inboxes/{inbox_id}/messages/send. The body comes from —text, —html or —file (a .html/.htm file is sent as HTML, anything else as text); pass - to any of them to read stdin. Stdin is never read unless you ask. —from defaults to MACHINEMAIL_INBOX, the profile inbox from `machinemail register`, or the inbox of an inbox-scoped key.

```shell
machinemail send [flags]
```

#### [Flags](/content/docs/cli/commands/mail#flags/index.html)

| Field | Description |
| --- | --- |
| `--from <inbox-id>` | Inbox to send from. |
| `--to <address>` | Recipient (repeat or comma-separate). Repeat the flag for several values. |
| `--cc <address>` | CC recipient. Repeat the flag for several values. |
| `--bcc <address>` | BCC recipient. Repeat the flag for several values. |
| `-s, --subject <text>` | Subject. |
| `--text <text|->` | Plain-text body, or - for stdin. |
| `--html <html|->` | HTML body, or - for stdin. |
| `-f, --file <path|->` | Body from a file (.html is HTML), or - for stdin. |
| `--attach <path>` | Attach a file (10 MB of files per message in total). Repeat the flag for several values. |
| `--reply-to <address>` | Reply-To address. Repeat the flag for several values. |
| `--label <label>` | Label for the sent message. Repeat the flag for several values. |
| `--header <Name: value>` | Extra header. Repeat the flag for several values. |

#### [Examples](/content/docs/cli/commands/mail#examples/index.html)

```shell
machinemail send --from agent@machinemail.dev --to ada@acme.dev -s "Hello" --text "Hi Ada"
echo "Build passed" | machinemail send --to ops@acme.dev -s "CI" --text -
machinemail send --to ada@acme.dev -s "Report" --file report.html --attach report.pdf
```

## [read](/content/docs/cli/commands/mail#read/index.html)

Show a message: headers, trust verdict and agent-safe text.

Shows one message with its trust report summary (verdict, score, authentication, flags) and the agent-safe body (trust.content.text: hidden text, zero-width characters, quotes and signatures removed). —original shows the text as the sender wrote it, labelled untrusted; —raw prints the raw RFC 5322 source.

```shell
machinemail read <message-id> [flags]
```

#### [Arguments](/content/docs/cli/commands/mail#arguments/index.html)

| Field | Description |
| --- | --- |
| `<message-id>` | Required message id (msg_...), optionally preceded by its inbox |

#### [Flags](/content/docs/cli/commands/mail#flags-1/index.html)

| Field | Description |
| --- | --- |
| `--inbox <inbox-id>` | Inbox the message is in (found automatically when omitted). |
| `--original` | Show the original text instead of the agent-safe text (untrusted). |
| `--full` | JSON output: the whole API message (original text and HTML included, untrusted) instead of the agent view. |
| `--raw` | Print the raw RFC 5322 message. |

#### [Examples](/content/docs/cli/commands/mail#examples-1/index.html)

```shell
machinemail read msg_01m4g46p1y0000bqmf6m6yv7h5
machinemail read agent@machinemail.dev msg_01m4...
machinemail read msg_01m4... --json | jq -r .body
machinemail read msg_01m4... --json --full | jq .trust
```

## [wait](/content/docs/cli/commands/mail#wait/index.html)

Wait for a message to arrive (and extract a code or magic link with —otp).

Blocks until a new inbound message matching the filters arrives in the inbox, then prints it. Listens on the SSE event stream and polls as a fallback. Only mail received after the command starts counts; —since 5m also accepts mail from the last five minutes (use it when you triggered the email before calling wait).

Piped (or with —json) it prints the agent view of the message: headers, the trust verdict, untrusted: true unless the sender authenticated, and the agent-safe body (withheld for quarantined mail); —full prints the whole API object instead, original text included.

```shell
machinemail wait [flags]
```

#### [Flags](/content/docs/cli/commands/mail#flags-2/index.html)

| Field | Description |
| --- | --- |
| `--inbox <inbox-id>` | Inbox to watch (default: MACHINEMAIL_INBOX or the profile inbox). |
| `--from <address|domain>` | Sender is this address, or on this domain or a subdomain of it; a bare word matches inside the local part (any of several matches). Repeat the flag for several values. |
| `--subject <text>` | Subject contains this, case-insensitive (any of several matches). Repeat the flag for several values. |
| `-t, --timeout <duration>` | Give up after this long: 90, 90s, 5m (default 5m; 0 waits forever). |
| `--since <duration|iso>` | Also accept mail received this long ago (5m) or since this time. |
| `--otp` | Print only the verification code, or the magic link when there is none. |
| `--link` | With --otp: print the magic link even when there is a code. |
| `--pattern <regex>` | With --otp: extract with this regex (first group, else the match). |
| `--link-domain <domain>` | With --otp: the magic link must be on this domain or a subdomain of it (default: the sender domain). |
| `--allow-unauthenticated` | With --otp: also use mail whose sender did not authenticate, or that has no trust report (never suspicious or quarantined mail). |
| `--full` | JSON output: the whole API message (original text and HTML included, untrusted) instead of the agent view. |
| `--poll` | Poll only; do not use the event stream. |

#### [Examples](/content/docs/cli/commands/mail#examples-2/index.html)

```shell
machinemail wait --inbox signup-7f3k@machinemail.dev --otp
CODE=$(machinemail wait --inbox "$ADDR" --from github.com --otp --timeout 2m)
machinemail wait --inbox "$ADDR" --subject invoice --json | jq .trust.level
machinemail wait --inbox "$ADDR" --otp --allow-unauthenticated   # e.g. a test sender without SPF/DKIM
```

## [tail](/content/docs/cli/commands/mail#tail/index.html)

Follow live events (messages, deliveries, inboxes) as they happen.

Streams GET /v0/events/stream. On a terminal: one line per event with the trust badge of inbound mail, and a status line. Piped: NDJSON, one {id, event, data} per line. Reconnects on its own and resumes with Last-Event-ID; pass —last-event-id to resume from an earlier run. Ctrl-C stops it (exit 0).

```shell
machinemail tail [flags]
```

#### [Flags](/content/docs/cli/commands/mail#flags-3/index.html)

| Field | Description |
| --- | --- |
| `--inbox <inbox-id>` | Only these inboxes. Repeat the flag for several values. |
| `--pod <pod-id>` | Only these pods. Repeat the flag for several values. |
| `-e, --event-types` | Only these event types (comma-separated or repeated). Repeat the flag for several values. |
| `--last-event-id <evt_...>` | Replay events after this one first. |
| `--max <n>` | Stop after n events. |

#### [Examples](/content/docs/cli/commands/mail#examples-3/index.html)

```shell
machinemail tail
machinemail tail --inbox agent@machinemail.dev -e message.received
machinemail tail -e message.bounced,message.complained | jq -c .data.message.to
```
