# How to Configure the Email Notification System with SMTP Settings in INFINI Console

> Configure INFINI Console email notifications using SMTP settings via the REST API. Easily set up your SMTP host, port, TLS, and authentication for timely alerts.

- Repository: [INFINI Labs/console](https://github.com/infinilabs/console)
- Tags: how-to-guide
- Published: 2026-03-04

---

**To configure email notifications in INFINI Console, create an EmailServer record via the REST API with SMTP host, port, TLS settings, and authentication; when enabled, the system auto-generates a pipeline configuration that routes alert messages through the specified SMTP server.**

INFINI Console delivers email alerts through a pipeline-based SMTP processor that decouples alert generation from message delivery. This guide explains how to configure the email notification system using the REST API, manage TLS encryption settings, and verify connectivity before production deployment.

## Understanding the EmailServer Data Model

The foundation of email notifications in INFINI Console is the `EmailServer` struct defined in [`model/email_server.go`](https://github.com/infinilabs/console/blob/main/model/email_server.go). This model encapsulates all SMTP connection parameters, authentication credentials, and TLS security settings.

### Core SMTP Configuration Fields

The `EmailServer` struct includes the following key fields:

```go
type EmailServer struct {
    Name          string           `json:"name"`
    Host          string           `json:"host"`
    Port          int              `json:"port"`
    TLS           bool             `json:"tls"`               // use STARTTLS / SSL
    Auth          *model.BasicAuth `json:"auth"`              // username/password
    Enabled       bool             `json:"enabled"`           // auto-load into pipeline
    CredentialID  string           `json:"credential_id"`     // optional credential reference
    TLSMinVersion string           `json:"tls_min_version"`   // TLS10-TLS13 (default TLS12)
}

```

### TLS Version Support

INFINI Console supports TLS versions 1.0 through 1.3 via the `TLSMinVersion` field. The system defines constants in [`model/email_server.go`](https://github.com/infinilabs/console/blob/main/model/email_server.go):

```go
const (
    TLSVersion10 = "TLS10"
    TLSVersion11 = "TLS11"
    TLSVersion12 = "TLS12"
    TLSVersion13 = "TLS13"
)

func GetTLSVersion(version string) (uint16, error) { … }

```

If `tls_min_version` is omitted, the system defaults to **TLS 1.2**.

## Creating and Enabling an SMTP Server via REST API

The REST API for email server management is implemented in [`plugin/api/email/server.go`](https://github.com/infinilabs/console/blob/main/plugin/api/email/server.go), providing endpoints for creating, updating, and testing SMTP configurations.

### API Endpoint and Payload Structure

To create a new SMTP server, send a POST request to `/api/email/server`:

```bash
curl -X POST http://localhost:8080/api/email/server \
  -H "Content-Type: application/json" \
  -d '{
        "name":"prod-smtp",
        "host":"smtp.example.com",
        "port":587,
        "tls":true,
        "auth":{
          "username":"alert@example.com",
          "password":"s3cr3t"
        },
        "tls_min_version":"TLS12",
        "enabled":true
      }'

```

The `createEmailServer` and `updateEmailServer` methods handle these requests, validating the payload and storing the record in the Elasticsearch-backed `email-server` index.

### Authentication Options

You can provide credentials in two ways:

- **Inline authentication**: Include the `auth` object with `username` and `password` directly in the JSON payload.
- **Credential reference**: Provide a `credential_id` instead of the raw `auth` block. The system retrieves the stored BasicAuth credential using `GetBasicAuth` and stores the password securely in the keystore.

When `enabled:true` is set, the handler automatically triggers `common.RefreshEmailServer()` to regenerate the pipeline configuration.

## How the Pipeline Configuration Works

INFINI Console uses an internal queue-and-pipeline architecture to process email notifications asynchronously. The pipeline generation logic resides in [`plugin/api/email/common/pipeline.go`](https://github.com/infinilabs/console/blob/main/plugin/api/email/common/pipeline.go).

### Automatic Pipeline Generation

The `RefreshEmailServer()` function performs the following steps:

1. **Query enabled servers** from the `email-server` index.
2. **Validate** each entry using the `Validate` method.
3. **Resolve credentials** via `GetBasicAuth` (or the `credential_id`).
4. **Store passwords** securely using `keystore.SetValue`.
5. **Generate a YAML pipeline** via `GeneratePipelineConfig`.
6. Write the configuration to **[`send_email.yml`](https://github.com/infinilabs/console/blob/main/send_email.yml)** in the console's config directory (`global.Env().GetConfigDir()`).

### The send_email.yml Structure

The generated pipeline configuration maps server IDs to SMTP processors:

```yaml
pipeline:
  - name: send_email_service
    auto_start: true
    processor:
      - consumer:
          queue_selector:
            keys: ["email_messages"]
          processor:
            - smtp:
                idle_timeout_in_seconds: 1
                servers:
                  "server-id-123":
                    server:
                      host: smtp.example.com
                      port: 587
                      tls: true
                      refresh_timestamp: 1709280000000
                    min_tls_version: TLS12
                    auth:
                      username: alert@example.com
                      password: $[[keystore.server-id-123_password]]
                templates:
                  raw:
                    content_type: "text/plain"
                    subject: "$[[subject]]"
                    body: "$[[body]]"

```

The password is referenced via a keystore placeholder (`$[[keystore.<id>_password]]`), ensuring credentials are not exposed in plain text.

### Message Flow from Alert to SMTP

When an alert rule triggers an email action, the `EmailAction.Execute()` method in [`service/alerting/action/email.go`](https://github.com/infinilabs/console/blob/main/service/alerting/action/email.go) constructs a message and pushes it to the queue:

```go
func (act *EmailAction) Execute() ([]byte, error) {
    queueCfg := queue.GetOrInitConfig(EmailQueueName) // "email_messages"
    emailMsg := util.MapStr{
        "server_id": act.Data.ServerID,
        "email":     act.Data.Recipients.To,
        "template":  "raw",
        "variables": util.MapStr{
            "subject": act.Subject,
            "body":    act.Body,
        },
    }
    return nil, queue.Push(queueCfg, util.MustToJSONBytes(emailMsg))
}

```

The pipeline's consumer reads from the `email_messages` queue and forwards the message to the SMTP server specified in the `server_id` field, using the TLS version configured for that server.

## Testing Your SMTP Configuration

Before relying on email alerts in production, verify your SMTP settings using the built-in test endpoint implemented in [`plugin/api/email/server.go`](https://github.com/infinilabs/console/blob/main/plugin/api/email/server.go).

### Using the Test Endpoint

Send a POST request to `/api/email/server/_test`:

```bash
curl -X POST http://localhost:8080/api/email/server/_test \
  -H "Content-Type: application/json" \
  -d '{
        "send_to":["admin@example.com"],
        "host":"smtp.example.com",
        "port":587,
        "tls":true,
        "auth":{
          "username":"alert@example.com",
          "password":"s3cr3t"
        },
        "tls_min_version":"TLS13"
      }'

```

### TLS Version Defaults in Testing

The `testEmailServer` method follows the same defaults as the main configuration. If `tls_min_version` is omitted, the code explicitly defaults to TLS 1.2:

```go
if reqBody.TLSMinVersion == "" {
    reqBody.TLSMinVersion = model.TLSVersion12
}
tlsMinVersion, err := model.GetTLSVersion(reqBody.TLSMinVersion)

```

A successful test returns **HTTP 200** with a JSON acknowledgement, confirming that the console can establish the SMTP connection and authenticate using the specified TLS version.

## Complete Configuration Workflow

Follow these steps to fully configure email notifications in INFINI Console:

1. **Define the EmailServer record** via POST `/api/email/server` with your SMTP host, port, TLS settings, and authentication credentials.
2. **Enable the server** by setting `"enabled": true` in the payload; this triggers automatic pipeline generation.
3. **Verify the pipeline** by checking that [`send_email.yml`](https://github.com/infinilabs/console/blob/main/send_email.yml) exists in the console's config directory (`global.Env().GetConfigDir()`).
4. **Test connectivity** using the `/api/email/server/_test` endpoint before creating alert rules.
5. **Create alert rules** that reference the email server ID as a destination (defined in [`model/alerting/destination.go`](https://github.com/infinilabs/console/blob/main/model/alerting/destination.go)).
6. **Monitor the queue**; when alerts trigger, `EmailAction.Execute()` pushes messages to `email_messages`, which the pipeline consumes and forwards via SMTP.

## Summary

- **EmailServer Model**: Defined in [`model/email_server.go`](https://github.com/infinilabs/console/blob/main/model/email_server.go), supports TLS 1.0-1.3 with TLS 1.2 as the default.
- **REST API**: Managed via [`plugin/api/email/server.go`](https://github.com/infinilabs/console/blob/main/plugin/api/email/server.go); create servers with POST `/api/email/server` and test with `/_test`.
- **Pipeline Generation**: `RefreshEmailServer()` in [`plugin/api/email/common/pipeline.go`](https://github.com/infinilabs/console/blob/main/plugin/api/email/common/pipeline.go) auto-generates [`send_email.yml`](https://github.com/infinilabs/console/blob/main/send_email.yml) when servers are enabled.
- **Secure Storage**: Passwords are stored in the keystore and referenced via placeholders in the pipeline configuration.
- **Message Flow**: Alert rules use `EmailAction` in [`service/alerting/action/email.go`](https://github.com/infinilabs/console/blob/main/service/alerting/action/email.go) to queue messages; the pipeline's SMTP processor delivers them.

## Frequently Asked Questions

### What TLS versions does INFINI Console support for SMTP?

INFINI Console supports TLS 1.0, 1.1, 1.2, and 1.3 through the `tls_min_version` field in the EmailServer model. The system uses the `GetTLSVersion` function in [`model/email_server.go`](https://github.com/infinilabs/console/blob/main/model/email_server.go) to map string constants like "TLS12" to Go's TLS version constants. If no version is specified, the system defaults to TLS 1.2 for secure connections.

### Can I use stored credentials instead of plaintext passwords?

Yes. Instead of including an `auth` object with plaintext credentials in your API request, you can provide a `credential_id` field referencing a pre-stored BasicAuth credential. The system retrieves the credential using `GetBasicAuth` and stores the password securely in the internal keystore via `keystore.SetValue`. The generated pipeline configuration references the password using the placeholder `$[[keystore.<server_id>_password]]`, ensuring credentials never appear in plain text on disk.

### Where is the SMTP pipeline configuration stored?

The SMTP pipeline configuration is stored in a YAML file named [`send_email.yml`](https://github.com/infinilabs/console/blob/main/send_email.yml) located in the console's configuration directory, accessible via `global.Env().GetConfigDir()`. This file is automatically generated or updated by the `RefreshEmailServer()` function in [`plugin/api/email/common/pipeline.go`](https://github.com/infinilabs/console/blob/main/plugin/api/email/common/pipeline.go) whenever you create, update, or toggle the enabled status of an email server through the REST API.

### How do I troubleshoot email delivery failures?

Start by using the `/api/email/server/_test` endpoint to verify SMTP connectivity and authentication without waiting for an alert to trigger. Check that the [`send_email.yml`](https://github.com/infinilabs/console/blob/main/send_email.yml) pipeline file exists in the config directory and contains your server ID in the `servers` map with the correct keystore password reference. Verify that the email server record has `"enabled": true` and that your alert rule references the correct `server_id`. Monitor the `email_messages` queue to confirm that `EmailAction.Execute()` in [`service/alerting/action/email.go`](https://github.com/infinilabs/console/blob/main/service/alerting/action/email.go) is successfully pushing messages when alerts trigger.