# Email (SMTP)

Send email through an SMTP server.

## Connect Email (SMTP)

1. In the sidebar, open **Connections** and press **Add connection**.
2. Type `smtp` and choose **Email (SMTP)**.
3. Fill in the fields. Each one says **Required** or **Optional**.
4. Press **Test and save**. GoRunner checks the connection before it saves anything.

The sheet asks for **SMTP server**, **Port**, **Email**, **Password**, **Require an encrypted connection (TLS)** and **Accept a certificate that can’t be checked (not safe)**.

[Connections](https://docs.gorunner.io/build/connections) says how to sign in again, rename or delete it. In a product that embeds GoRunner, **Add connection** can be missing: then [your provider makes connections](https://docs.gorunner.io/embed/customer-connections) for you.

## Do things in Email (SMTP)

Add an **Email (SMTP)** step and choose what it does. Choose a row to see its fields.

- [Send Email](https://docs.gorunner.io/apps/email-smtp#fields-f-send-email): Send an email using a custom SMTP server.
- [Send for Approval (wait for decision)](https://docs.gorunner.io/apps/email-smtp#fields-f-send-and-wait): Email an approve/reject request and suspend the run until someone answers it.

To start a workflow from Email (SMTP), use a [Schedule](https://docs.gorunner.io/apps/schedule), [Webhook](https://docs.gorunner.io/apps/webhook) or [Form](https://docs.gorunner.io/apps/form) trigger.

Later steps read a step’s output by its name: see [Use data from earlier steps](https://docs.gorunner.io/build/use-data-from-earlier-steps).

## Limits

- GoRunner Cloud reaches servers on the public internet only. On a self-hosted installation, an admin can allow private addresses with `WORKFLOW_PRIVATE_NETWORKS`.

Not in your list? See [When an app isn’t here](https://docs.gorunner.io/apps/when-an-app-isnt-here#q-not-in-list).

## For developers

In the API, which calls apps pieces, Email (SMTP) is `pieceId: "email"` with the actions `send_email`, `send_and_wait`. [Get an app](https://docs.gorunner.io/api/apps/get-app) returns every field.

What each action does outside the run: `send_email` writes_external, `send_and_wait` writes_external. See [How versions and side effects work](https://docs.gorunner.io/apps#q-versions).

### Email (SMTP) › Send Email

Send an email using a custom SMTP server.

- **From Email · Required**: Sender email address, bare or with a name (Acme \<noreply@example.com>); the name is used when Sender Name is empty.
- **Sender Name · Optional**: Display name shown to recipients.
- **To · Required**: Comma-separated recipient email addresses, bare or with a name (Ann \<ann@example.com>).
- **CC · Optional**: Comma-separated CC email addresses.
- **BCC · Optional**: Comma-separated BCC email addresses.
- **Reply To · Optional**: Email address for replies.
- **Subject · Required**: The subject line of the email (such as Your order has shipped).
- **Body Type · Required**: Format of the email body. Options: Plain Text, HTML, Both (text + HTML). Default: Plain Text.
- **Body · Required**: Email body content (plain text, or HTML when Body Type is HTML).
- **HTML Body · Optional**: HTML alternative; the Body field is used as the plain-text alternative. Left empty, the email is sent as plain text. Shows when **Body Type** is **Both (text + HTML)**.
- **Custom Headers · Optional**: Additional email headers (such as X-Priority, In-Reply-To). A name is letters, digits and punctuation without spaces or ':'; a value is written as one line.
- **Attachments · Optional**: Attach one file per row, or switch the field to an expression to pass a whole list from an earlier step (such as {{steps.unzip.files}}). Files from earlier steps work too: an unzipped entry, a generated PDF or CSV, an HTTP download.

### Email (SMTP) › Send for Approval (wait for decision)

Email an approve/reject request and suspend the run until someone answers it. One step instead of three: it mints the links, writes the message around them, sends it over this connection, and waits. The decision lands on {{steps.\<this>.status}} ("approved"/"rejected") and {{steps.\<this>.resumeData.decision}}; if the auto-continue timeout fires with no answer, status is "timed_out" and timedOut is true. Branch on the decision, never on the step merely having finished. To ask through a channel this step does not speak (Slack, Teams, an internal tool) use Approval's Create Approval Links → your own sending step → Wait for Decision, which waits exactly the same way. Only works on the main chain: inside a branch arm or loop body the step fails, because a suspended run can only re-enter the top level.

- **From Email · Required**: Sender email address.
- **Sender Name · Optional**: Display name shown to the approver.
- **To · Required**: Comma-separated approver addresses. Anyone who receives it can answer, and the first answer wins: the links work once.
- **Subject · Required**: The email's subject, and the heading shown above the buttons.
- **Details · Optional**: Context the approver needs in order to decide. Expressions work here, such as the order total from an earlier step.
- **Buttons · Optional**: Approve and Reject, or a single Approve button when the only useful answer is yes. Options: Approve and Reject, Approve only. Default: Approve and Reject.
- **CC · Optional**: Comma-separated CC addresses. They can answer too.
- **Reply To · Optional**: Address for replies.
- **Auto-continue after (timeout) · Optional**: Resume automatically after this long if no decision arrives (0 = wait indefinitely). On timeout nobody answered, so branch on status == "approved", never on the step having finished. Default: 0.
- **Timeout Unit · Optional**: The unit for the auto-continue time above. An unrecognized unit fails the step rather than silently auto-continuing after seconds. Options: Seconds, Minutes, Hours, Days. Default: Hours.
- **Public Base URL · Optional**: Public URL of this installation, used to build the approve/reject links. Defaults to the PUBLIC_API_URL env var. It must be reachable by the person deciding: a link on localhost is one nobody can answer.

Source: https://docs.gorunner.io/apps/email-smtp
