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

# Manage email servers

> Configure organization Resend and SMTP servers for the Send Email workflow step.

Email servers are first-class organization resources (`ems_…`) used by
[`action.email`](/steps/action/email). Cloud Studio and on-prem deployments use
the same Settings, API, CLI, and SDK surfaces. There is **no default server**
and no deployment-file fallback: each Send Email step must select a live
server.

This is **not** the platform Resend configuration used for Studio invitations
and inbound agent mail. Workflow outbound servers do not send those messages,
and platform mail is not a fallback for `action.email`.

Secrets (Resend API keys, SMTP passwords, and optional SMTP CA PEMs) are
encrypted at rest. List and get responses never return them; they expose
configuration flags such as `apiKeyConfigured`, `passwordConfigured`, and
`caPemConfigured` instead.

Owners and admins can create, update, test, and delete servers. Other members
can list and inspect the redacted view.

## Studio

1. Open **Settings → Email servers**.
2. Add a server. Choose **Resend** (API key plus From name and address) or
   **SMTP** (host, security, port, optional username/password, optional CA PEM).
3. Send a test message to confirm delivery.
4. In a workflow, add **Send Email** and pick the server. The step stores the
   stable `ems_…` id.

You can keep several servers (for example a production SMTP relay and a Resend
account for a second From address). Disabling a server leaves it listed but
blocks sends and publish until you enable it or select another server. Deleting
a server is a soft delete: the id stops resolving, and steps that still
reference it fail until you change `with.server`.

For SMTP, paste a custom CA as PEM on the server when you need one. There is no
filesystem CA path.

When you change an SMTP host or username, send a new password or clear
authentication (`username: null`). The previous password is never reused
against a new destination. Metadata-only updates and same-host, same-username
edits may omit the password to keep the stored value.

SMTP security defaults to STARTTLS. If you omit the port, Eigenpal uses 587 for
STARTTLS, 465 for TLS, and 25 for none. Use none only for trusted internal
relays; username and password are not allowed with that mode.

## API, CLI, and SDKs

The public contract is `/v1/email-servers`:

| Operation | HTTP                               |
| --------- | ---------------------------------- |
| List      | `GET /v1/email-servers`            |
| Create    | `POST /v1/email-servers`           |
| Get       | `GET /v1/email-servers/{id}`       |
| Update    | `PATCH /v1/email-servers/{id}`     |
| Delete    | `DELETE /v1/email-servers/{id}`    |
| Test      | `POST /v1/email-servers/{id}/test` |

Request and response schemas, including the paginated list envelope, live in
the [API reference](/api-reference). Do not put secrets in query strings or CLI
flags.

The CLI matches that surface:

```bash theme={null}
eigenpal email-servers list --json
eigenpal email-servers create --transport resend --name Alerts \
  --from-email alerts@example.com --from-name Alerts --api-key-stdin
eigenpal email-servers test ems_... --to you@example.com
```

See [`eigenpal email-servers`](/cli/email-servers) for every subcommand and
flag. Provide Resend API keys, SMTP passwords, and CA PEMs with `--*-stdin`,
`--*-file`, or the secure prompt.

TypeScript (`@eigenpal/sdk`) and Python (`eigenpal`) wrap the same operations:

```ts theme={null}
const page = await client.emailServers.list();
await client.emailServers.test('ems_…', { to: 'you@example.com' });
```

```python theme={null}
page = client.email_servers.list()
client.email_servers.test("ems_…", {"to": "you@example.com"})
```

See the [TypeScript](/sdks/typescript/reference) and [Python](/sdks/python/reference)
references for every method, and the [API reference](/api-reference) for HTTP
shapes they wrap.

A test send delivers a real connectivity message through the stored server.
Disabled servers reject the test. Workflow evaluation runs still skip
[`action.email`](/steps/action/email) delivery, including invoked child
workflows.
