> ## Documentation Index
> Fetch the complete documentation index at: https://ahasend.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

> ## Agent Instructions
> AhaSend stores all message data in the EU. See /facts.
> The API base URL is https://api.ahasend.com. Send the API key in the Authorization: Bearer header. See /api-reference/authentication.
> Use send.ahasend.com for SMTP. Ports 25, 587 and 2525 use STARTTLS. Port 465 is not supported. See /smtp.
> For send-only integrations, create an API Key v2 under Credentials → Add and scope it to messages:send:{your-domain}. See /send-api/credentials and /api-reference/scopes.

# ahasend smtp: SMTP Credentials and Test Sends

> Create, list, and delete AhaSend SMTP relay credentials from the CLI, and send test emails through send.ahasend.com on port 587 to verify your setup.

AhaSend CLI `smtp` commands let you manage SMTP credentials and send test emails through AhaSend's SMTP server; this page lists their arguments and flags. For host, ports and TLS, see [SMTP settings](https://ahasend.com/docs/smtp.md). For dashboard setup, see [SMTP credential setup](https://ahasend.com/docs/smtp/credentials.md).

Before running the examples, [log in](https://ahasend.com/docs/cli/authentication.md) with an API key that has the read, write and delete [SMTP credential scopes](https://ahasend.com/docs/api-reference/scopes.md#smtp-credentials) for all domains, and replace `YOUR_RESOURCE_ID` with the ID of one of your SMTP credentials. In the scoped credential example, replace `notifications.example.com` with a domain in your account; for any other domain, the API answers 400 `invalid domain: <domain>`. In the `smtp send` examples, replace `sender@example.com` with an address on your verified sender domain; the sends use sandbox mode. The delete example needs [jq](https://jqlang.org).

## Overview

```text theme={null}
ahasend smtp [subcommand] [flags]
```

Available subcommands:

* `list` - List SMTP credentials
* `create` - Create an SMTP credential
* `get` - Get an SMTP credential
* `delete` - Delete an SMTP credential
* `send` - Send an email via SMTP protocol

## List SMTP Credentials

```bash theme={null}
# List SMTP credentials
ahasend smtp list

# Fetch 10 credentials, then the page after them
ahasend smtp list --limit 10
ahasend smtp list --limit 10 --after YOUR_CURSOR
```

Passwords are never shown. Pages work as [Lists and Pagination](https://ahasend.com/docs/cli/configuration.md#lists-and-pagination) describes; replace `YOUR_CURSOR` with the cursor of the previous page.

## Create SMTP Credential

```bash theme={null}
# Global credential, which can send from any verified domain
ahasend smtp create --name "Main Server"

# Scoped credential, which can send only from the domains you give
ahasend smtp create \
  --name "Notifications" \
  --scope scoped \
  --domains notifications.example.com

# Sandbox credential for testing
ahasend smtp create --name "Development" --sandbox
```

`--scope` is `global` (the default) or `scoped`. `--scope scoped` needs at least one `--domains`, and `--domains` needs `--scope scoped`. Repeat `--domains`, or separate domains with commas, to allow several.

The output shows the generated password once. It cannot be retrieved later, so save it. When `--name` is missing, the command asks for it, as [Missing Values](https://ahasend.com/docs/cli/configuration.md#missing-values) describes.

## Get SMTP Details

```bash theme={null}
ahasend smtp get YOUR_RESOURCE_ID
```

The password shows as `[HIDDEN]` in table and plain output.

## Delete SMTP Credential

Applications that use the credential lose access at once. The command asks for confirmation first, as [Prompts](https://ahasend.com/docs/cli/configuration.md#prompts) describes; `--force` (`-f`) skips it.

```bash theme={null}
TEST_ID=$(ahasend smtp create --name "Docs deletion test" --sandbox --non-interactive --output json | jq -er '.id')
ahasend smtp delete "$TEST_ID"
```

## Send via SMTP

`smtp send` sends one email over SMTP, to test SMTP credentials. It connects to `--server`, which defaults to `send.ahasend.com:587`. Give `--server` as `host:port`, or as `host` for port 587.

A send needs `--from`, a recipient (`--to`, `--cc` or `--bcc`), `--subject`, content (`--text`, `--html`, `--text-file` or `--html-file`), `--username` and the password. When one is missing, the command asks for it, as [Missing Values](https://ahasend.com/docs/cli/configuration.md#missing-values) describes, and hides the password as you type.

Set `SMTP_USERNAME` and `SMTP_PASSWORD` in your shell from the values returned when you created the sandbox credential. The CLI cannot retrieve an existing credential's password.

```bash theme={null}
# Send a sandbox email, with the password from an environment variable
printf '%s\n' "$SMTP_PASSWORD" | ahasend smtp send --sandbox \
  --username "$SMTP_USERNAME" \
  --password-stdin \
  --from sender@example.com \
  --to recipient@example.com \
  --subject "SMTP Test" \
  --text "Testing SMTP sending"

# Simulate a bounce in sandbox mode
printf '%s\n' "$SMTP_PASSWORD" | ahasend smtp send --sandbox --sandbox-result bounce \
  --username "$SMTP_USERNAME" \
  --password-stdin \
  --from sender@example.com \
  --to recipient@example.com \
  --subject "Bounce test" \
  --text "This send simulates a bounce"
```

### Password Input

Other users of the machine can see `--password` in the process list, and your shell may keep it in its history. `--password-stdin` reads the password from the first line of stdin instead, without its line break. With it, the command asks for no value, so a missing flag fails as with `--non-interactive`. `--password` and `--password-stdin` cannot be used together.

### Encryption

The command starts TLS at once on port 465, and otherwise with STARTTLS when the server offers it. It never sends the username, the password or the message without TLS, except to `localhost`, `127.0.0.1` or `::1`. When any other server offers no STARTTLS, the command fails before it logs in, with exit code 1. It also fails with exit code 1 when the server offers no login (AUTH). AhaSend's server offers STARTTLS on ports 587, 25 and 2525, and does not offer implicit TLS on port 465; see [SMTP settings](https://ahasend.com/docs/smtp.md).

The command logs in with CRAM-MD5 when the server offers it, with LOGIN when the server offers LOGIN but not PLAIN, and with PLAIN otherwise. For AhaSend's own servers, see [SMTP settings](https://ahasend.com/docs/smtp.md).

### Test the Connection

`--test` connects to `--server`, starts TLS when the server offers it, logs in when you give the username and the password, and quits. It sends no message, so it needs no message flags, and the message flags have no effect. Without `--username` and the password, it tests only the connection: a server that offers no STARTTLS then passes the test, over a connection without TLS.

```bash theme={null}
# Test the connection and the login
printf '%s\n' "$SMTP_PASSWORD" | ahasend smtp send --test \
  --username "$SMTP_USERNAME" \
  --password-stdin

# Test only the connection to a server
ahasend smtp send --test --server send.ahasend.com:587
```

```text theme={null}
SMTP Test Result:
  Connection: Successful
  Authentication: Passed
  Status: No message was sent
```

Without credentials, Authentication shows `Not tested (no --username and --password)`. A failed login shows Authentication as `Failed`, with the reason in the Error row, and exits with code 1. The reason is the server's reply when the server refused the login, and the CLI's own message when the server offered no STARTTLS or no AUTH. When the server closes the connection during the login, the command exits with code 7.

### Headers

Headers such as `AhaSend-Track-Opens`, `AhaSend-Tags` and `AhaSend-Sandbox` control AhaSend features over SMTP; see [special headers](https://ahasend.com/docs/smtp/special-headers.md). The flags `--track-opens`, `--track-clicks`, `--tag`, `--sandbox` and `--sandbox-result` set them. `--header` can set such a header only when its flag is not given. `--sandbox` sets both `AhaSend-Sandbox` and `AhaSend-Sandbox-Result`, so with `--sandbox`, `--header` cannot set `AhaSend-Sandbox-Result` even without `--sandbox-result`.

`--header` cannot set `From`, `Sender`, `To`, `Cc`, `Bcc`, `Subject`, `Mime-Version`, `Content-Type` or `Content-Transfer-Encoding`, which the command builds itself. It can set `Date` and `Message-ID`. Header names ignore case, and each name may be given once. A header value that holds a comma goes in double quotes inside the shell quotes, as in `--header '"X-Note: first, second"'`.

### Results and Exit Codes

When the server refuses any recipient, nothing is sent, and the error names the recipient.

A sent message's output shows its Message-ID: the one `--header` gave, or the one the command sets, a UUID at the domain of `--from`, such as `<0d371db4-00d0-5eec-851c-e1db1e2b190d@example.com>`. AhaSend keeps it, so [`messages get`](https://ahasend.com/docs/cli/commands/messages#get-a-message) finds the message by it.

`--output json` prints the CLI's own result object, not an API response, with the same keys as CSV output:

* After a sent message: `success` (`true`) and `message_id`.
* After a test that passed or failed: `test_mode` (`true`), `success` (whether the test passed), `connected` (whether it connected to the server), `authenticated` (whether it logged in) and `error` (why it failed, or an empty string).

A failed send prints no result object: it prints the error object that [JSON Output](https://ahasend.com/docs/cli/configuration.md#json-output) describes.

| Exit code | Meaning |
| - | - |
| 0 | The message was sent, or the test passed |
| 1 | The server refused the send or the login, offered no STARTTLS, or offered no login |
| 4 | Invalid input, such as a missing flag, an invalid `--from` address or an invalid `--server` |
| 7 | The server could not be reached, stopped answering or closed the connection |

Exit code 7 after the whole message was sent means the server may have accepted it. Check whether it arrived before you send it again.

## Command Flags

These flags come from the CLI's `--help`. All commands also accept the [global flags](https://ahasend.com/docs/cli/configuration.md#global-flags).

### `smtp create`

| Flag | Description and default |
| - | - |
| `--domains strings` | Allowed domain for a scoped credential (can be used multiple times) |
| `--idempotency-key string` | Idempotency key for safe retries (generated when omitted) |
| `--name string` | Credential name (required) |
| `--non-interactive` | Never prompt; fail when a required flag is missing |
| `--sandbox` | Create as sandbox credential for testing |
| `--scope string` | Credential scope: global or scoped (default "global") |

### `smtp delete`

| Flag | Description and default |
| - | - |
| `-f`, `--force` | Skip confirmation prompt |

### `smtp get`

This command has no command-specific flags. See [global flags](https://ahasend.com/docs/cli/configuration.md#global-flags).

### `smtp list`

| Flag | Description and default |
| - | - |
| `--after string` | Return the page after this cursor |
| `--before string` | Return the page before this cursor |
| `--limit int32` | Maximum number of items to return (0-100; 0 uses the API default) |

### `smtp send`

| Flag | Description and default |
| - | - |
| `--attach strings` | File to attach (can be used multiple times) |
| `--bcc strings` | BCC recipient (can be used multiple times) |
| `--cc strings` | CC recipient (can be used multiple times) |
| `--from string` | Sender email address (required) |
| `--header strings` | Custom header in `Name: value` format, each name once in any case, in double quotes when the value holds a comma: `'"Name: a, b"'`; not From, Sender, To, Cc, Bcc, Subject or the MIME headers (can be used multiple times) |
| `--html string` | HTML content |
| `--html-file string` | File with the HTML content |
| `--non-interactive` | Never prompt; fail when a required flag is missing |
| `--password string` | SMTP password (required, except by `--test`); other users of the machine can see it in the process list, so prefer `--password-stdin` |
| `--password-stdin` | Read the SMTP password from the first line of stdin, in place of `--password`; the command then asks for nothing |
| `--sandbox` | Send in sandbox mode, which delivers nothing |
| `--sandbox-result string` | Sandbox result simulation: deliver, bounce, defer, fail or suppress (needs `--sandbox`) (default "deliver") |
| `--server string` | SMTP server address (default "send.ahasend.com:587") |
| `--subject string` | Email subject (required) |
| `--tag strings` | Message tag (can be used multiple times) |
| `--test` | Connect to `--server`, and log in when `--username` and `--password` are given, then quit without sending |
| `--text string` | Plain text content |
| `--text-file string` | File with the plain text content |
| `--to strings` | Recipient email address (can be used multiple times) |
| `--track-clicks` | Track clicks (`--track-clicks=false` turns it off); the account's setting applies when omitted |
| `--track-opens` | Track opens (`--track-opens=false` turns it off); the account's setting applies when omitted |
| `--username string` | SMTP username (required, except by `--test`) |

## Next Steps

* [Send messages via API](https://ahasend.com/docs/cli/commands/messages.md)
* [Manage API keys](https://ahasend.com/docs/cli/commands/apikeys.md)

## Related Guides

* [Install the CLI](https://ahasend.com/docs/cli/installation.md), [CLI authentication](https://ahasend.com/docs/cli/authentication.md), [SMTP credential setup](https://ahasend.com/docs/smtp/credentials.md).
* [SMTP credential API](https://ahasend.com/docs/api-reference/smtp-credentials/create-smtp-credential.md), [SMTP settings](https://ahasend.com/docs/smtp.md), [CLI configuration and output](https://ahasend.com/docs/cli/configuration.md).
* [API authentication](https://ahasend.com/docs/api-reference/authentication.md), [Permission scopes](https://ahasend.com/docs/api-reference/scopes.md), [Domain setup](https://ahasend.com/docs/domains.md).
* [Sandbox behavior](https://ahasend.com/docs/send-api/sandbox.md), [Tracking setup](https://ahasend.com/docs/tracking/open-tracking.md), [Command-line SMTP sending](https://ahasend.com/docs/smtp/cli.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.