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

> ## Agent Instructions
> Install the Courier skill before writing code: `npx skills add trycourier/courier-skills`. It carries the verified SDK shapes and the rules you cannot get wrong.
> Authenticate every request with `Authorization: Bearer <API_KEY>`. A workspace has several environments and each has its own keys, which are plain `pk_` strings with no environment prefix. Start with Test.
> Send with `client.send.message`, the default import of the v7 Node SDK. Reference a template by its `nt_` id or its alias.
> A send accepts a bare Elemental element list, but storing content on a template requires the top-level elements wrapped in a channel element.
> Templates and journeys can be built in the Courier app or created through the API. Either way they live in the workspace and are referenced by ID when you send.
> The hosted MCP server is https://mcp.courier.com. For a briefing on what Courier is and when to use it, read https://www.courier.com/llms.txt.
> Prefer the Guides tab for how-do-I questions and the Docs tab for how-does-it-behave questions. The API reference lives under /api-reference.

# Send email with SMTP through Courier

> Connect any SMTP server with host, port, and credentials, then override transport fields per send.

export const AppLink = ({href, children, name, bare}) => {
  const label = children || name || "Open in Courier";
  if (bare) {
    return <a href={href} target="_blank" rel="noreferrer">{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="app" href={href} target="_blank" rel="noreferrer">
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method" aria-hidden="true">↗</span>
    </a>;
};

export const Doc = ({href, children, name, bare}) => {
  const label = children || name || href;
  if (bare) {
    return <a href={href}>{label}</a>;
  }
  return <a className="cx-endpoint" data-kind="doc" href={href}>
      <span className="cx-endpoint-label">{label}</span>
      <span className="cx-endpoint-method">DOC</span>
    </a>;
};

## Prerequisites

* An SMTP server you can send through
* The host, username, and password for that server

## Setup

Courier's SMTP integration uses [NodeMailer](https://nodemailer.com).

Open the <AppLink href="https://app.courier.com/integrations/catalog/smtp">SMTP integration</AppLink> in Courier, enter your SMTP host, username, password, and From Address, then save.

A provider override can change any of these for a single message.

<Info>
  Courier connects to your SMTP server from AWS-hosted infrastructure and does not use fixed outbound IPs. If your server requires IP allowlisting, see <Doc href="/docs/integrations/email/overview#allowlist-for-aws-ip-addresses">Allowlist for AWS IP Addresses</Doc> on the Email Providers page.
</Info>

Addressing a recipient and sending are the same on every email provider, so they are documented once: <Doc href="/docs/integrations/email/overview#profile-requirements">profile requirements</Doc> and <Doc href="/docs/integrations/email/overview#send-to-a-recipient">send to a recipient</Doc>.

## Overrides

<Doc href="/docs/send/overrides#how-overrides-work">How overrides work</Doc> covers the two levels and which one wins. <Doc href="/docs/integrations/email/overview#channel-overrides">Email channel overrides</Doc> lists the fields every email provider takes.

Provider overrides in the Send API change the message content and the SMTP transport configuration, one message at a time.

### Message override

An override changes what Courier sends over SMTP through NodeMailer. Overrides are deep-merged into the request: fields you set replace their counterparts, and everything you leave out is still sent. For example, add an attachment:

<CodeGroup>
  ```javascript Node.js highlight={8-21} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com",
      },
      providers: {
        smtp: {
          override: {
            body: {
              attachments: [
                {
                  filename: "document.pdf",
                  content: "aGVsbG8gd29ybGQh",
                  encoding: "base64",
                  contentType: "application/pdf",
                },
              ],
            },
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={8-21} theme={null}
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "to": {
              "email": "sarah@acme-corp.com",
          },
          "providers": {
              "smtp": {
                  "override": {
                      "body": {
                          "attachments": [
                              {
                                  "filename": "document.pdf",
                                  "content": "aGVsbG8gd29ybGQh",
                                  "encoding": "base64",
                                  "contentType": "application/pdf",
                              },
                          ],
                      },
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={11-24} wrap theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "to": {
          "email": "sarah@acme-corp.com"
        },
        "providers": {
          "smtp": {
            "override": {
              "body": {
                "attachments": [
                  {
                    "filename": "document.pdf",
                    "content": "aGVsbG8gd29ybGQh",
                    "encoding": "base64",
                    "contentType": "application/pdf"
                  }
                ]
              }
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={8-21} theme={null}
  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com"
      },
      providers: {
        smtp: {
          override: {
            body: {
              attachments: [
                {
                  filename: "document.pdf",
                  content: "aGVsbG8gd29ybGQh",
                  encoding: "base64",
                  contentType: "application/pdf"
                }
              ]
            }
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={10-23} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				Email: courier.String("sarah@acme-corp.com"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Providers: shared.MessageProvidersParam{
  			"smtp": shared.MessageProvidersTypeParam{
  				Override: map[string]any{
  					"body": map[string]any{
  						"attachments": []any{
  							map[string]any{
  								"filename": "document.pdf",
  								"content": "aGVsbG8gd29ybGQh",
  								"encoding": "base64",
  								"contentType": "application/pdf",
  							},
  						},
  					},
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={6-17} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().email("sarah@acme-corp.com").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .providers(MessageProviders.builder()
              .putAdditionalProperty("smtp", JsonValue.from(java.util.Map.of("override", java.util.Map.of(
                      "body", java.util.Map.of(
                          "attachments", java.util.List.of(
                              java.util.Map.of(
                                  "filename", "document.pdf",
                                  "content", "aGVsbG8gd29ybGQh",
                                  "encoding", "base64",
                                  "contentType", "application/pdf"
                              )
                          )
                      )
                  ))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={8-21} theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'to' => [
        'email' => 'sarah@acme-corp.com',
      ],
      'providers' => [
        'smtp' => [
          'override' => [
            'body' => [
              'attachments' => [
                [
                  'filename' => 'document.pdf',
                  'content' => 'aGVsbG8gd29ybGQh',
                  'encoding' => 'base64',
                  'contentType' => 'application/pdf',
                ],
              ],
            ],
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={9-30} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { Email = "sarah@acme-corp.com" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Providers = new Dictionary<string, MessageProvidersType>()
          {
              {
                  "smtp",
                  new()
                  {
                      Override = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
                          """
                          {
                            "body": {
                              "attachments": [
                                {
                                  "filename": "document.pdf",
                                  "content": "aGVsbG8gd29ybGQh",
                                  "encoding": "base64",
                                  "contentType": "application/pdf"
                                }
                              ]
                            }
                          }
                          """
                      ),
                  }
              },
          },
      },
  };

  var response = await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={5} wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"email": "sarah@acme-corp.com"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.providers '{"smtp": {"override": {"body": {"attachments": [{"filename": "document.pdf", "content": "aGVsbG8gd29ybGQh", "encoding": "base64", "contentType": "application/pdf"}]}}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template to sarah@acme-corp.com and override what goes out over SMTP.
  ```
</CodeGroup>

Courier merges everything inside `message.providers.smtp.override.body` into its generated message and passes it to NodeMailer. For every option, see the [NodeMailer message options documentation](https://nodemailer.com/message).

### Transport override

Values in `message.providers.smtp.override.config` override the [SMTP transport configuration](https://nodemailer.com/smtp). They replace your stored provider configuration for that one message.

**Basic example:**

<CodeGroup>
  ```javascript Node.js highlight={8-20} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com",
      },
      providers: {
        smtp: {
          override: {
            config: {
              auth: {
                user: "username",
                pass: "hunter2",
              },
              host: "smtp.example.com",
              secure: true,
              port: 465,
            },
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={8-20} theme={null}
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "to": {
              "email": "sarah@acme-corp.com",
          },
          "providers": {
              "smtp": {
                  "override": {
                      "config": {
                          "auth": {
                              "user": "username",
                              "pass": "hunter2",
                          },
                          "host": "smtp.example.com",
                          "secure": True,
                          "port": 465,
                      },
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={11-23} wrap theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "to": {
          "email": "sarah@acme-corp.com"
        },
        "providers": {
          "smtp": {
            "override": {
              "config": {
                "auth": {
                  "user": "username",
                  "pass": "hunter2"
                },
                "host": "smtp.example.com",
                "secure": true,
                "port": 465
              }
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={8-20} theme={null}
  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com"
      },
      providers: {
        smtp: {
          override: {
            config: {
              auth: {
                user: "username",
                pass: "hunter2"
              },
              host: "smtp.example.com",
              secure: true,
              port: 465
            }
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={10-22} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				Email: courier.String("sarah@acme-corp.com"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Providers: shared.MessageProvidersParam{
  			"smtp": shared.MessageProvidersTypeParam{
  				Override: map[string]any{
  					"config": map[string]any{
  						"auth": map[string]any{
  							"user": "username",
  							"pass": "hunter2",
  						},
  						"host": "smtp.example.com",
  						"secure": true,
  						"port": 465,
  					},
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={6-16} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().email("sarah@acme-corp.com").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .providers(MessageProviders.builder()
              .putAdditionalProperty("smtp", JsonValue.from(java.util.Map.of("override", java.util.Map.of(
                      "config", java.util.Map.of(
                          "auth", java.util.Map.of(
                              "user", "username",
                              "pass", "hunter2"
                          ),
                          "host", "smtp.example.com",
                          "secure", true,
                          "port", 465
                      )
                  ))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={8-20} theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'to' => [
        'email' => 'sarah@acme-corp.com',
      ],
      'providers' => [
        'smtp' => [
          'override' => [
            'config' => [
              'auth' => [
                'user' => 'username',
                'pass' => 'hunter2',
              ],
              'host' => 'smtp.example.com',
              'secure' => true,
              'port' => 465,
            ],
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={9-29} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { Email = "sarah@acme-corp.com" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Providers = new Dictionary<string, MessageProvidersType>()
          {
              {
                  "smtp",
                  new()
                  {
                      Override = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
                          """
                          {
                            "config": {
                              "auth": {
                                "user": "username",
                                "pass": "hunter2"
                              },
                              "host": "smtp.example.com",
                              "secure": true,
                              "port": 465
                            }
                          }
                          """
                      ),
                  }
              },
          },
      },
  };

  var response = await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={5} wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"email": "sarah@acme-corp.com"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.providers '{"smtp": {"override": {"config": {"auth": {"user": "username", "pass": "hunter2"}, "host": "smtp.example.com", "secure": true, "port": 465}}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template to sarah@acme-corp.com through a different SMTP server.
  ```
</CodeGroup>

**STARTTLS (port 587, recommended):**

<CodeGroup>
  ```javascript Node.js highlight={8-21} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com",
      },
      providers: {
        smtp: {
          override: {
            config: {
              host: "smtp.yourdomain.com",
              port: 587,
              secure: false,
              requireTLS: true,
              auth: {
                user: "user@yourdomain.com",
                pass: "your-password",
              },
            },
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={8-21} theme={null}
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "to": {
              "email": "sarah@acme-corp.com",
          },
          "providers": {
              "smtp": {
                  "override": {
                      "config": {
                          "host": "smtp.yourdomain.com",
                          "port": 587,
                          "secure": False,
                          "requireTLS": True,
                          "auth": {
                              "user": "user@yourdomain.com",
                              "pass": "your-password",
                          },
                      },
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={11-24} wrap theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "to": {
          "email": "sarah@acme-corp.com"
        },
        "providers": {
          "smtp": {
            "override": {
              "config": {
                "host": "smtp.yourdomain.com",
                "port": 587,
                "secure": false,
                "requireTLS": true,
                "auth": {
                  "user": "user@yourdomain.com",
                  "pass": "your-password"
                }
              }
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={8-21} theme={null}
  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com"
      },
      providers: {
        smtp: {
          override: {
            config: {
              host: "smtp.yourdomain.com",
              port: 587,
              secure: false,
              requireTLS: true,
              auth: {
                user: "user@yourdomain.com",
                pass: "your-password"
              }
            }
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={10-23} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				Email: courier.String("sarah@acme-corp.com"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Providers: shared.MessageProvidersParam{
  			"smtp": shared.MessageProvidersTypeParam{
  				Override: map[string]any{
  					"config": map[string]any{
  						"host": "smtp.yourdomain.com",
  						"port": 587,
  						"secure": false,
  						"requireTLS": true,
  						"auth": map[string]any{
  							"user": "user@yourdomain.com",
  							"pass": "your-password",
  						},
  					},
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={6-17} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().email("sarah@acme-corp.com").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .providers(MessageProviders.builder()
              .putAdditionalProperty("smtp", JsonValue.from(java.util.Map.of("override", java.util.Map.of(
                      "config", java.util.Map.of(
                          "host", "smtp.yourdomain.com",
                          "port", 587,
                          "secure", false,
                          "requireTLS", true,
                          "auth", java.util.Map.of(
                              "user", "user@yourdomain.com",
                              "pass", "your-password"
                          )
                      )
                  ))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={8-21} theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'to' => [
        'email' => 'sarah@acme-corp.com',
      ],
      'providers' => [
        'smtp' => [
          'override' => [
            'config' => [
              'host' => 'smtp.yourdomain.com',
              'port' => 587,
              'secure' => false,
              'requireTLS' => true,
              'auth' => [
                'user' => 'user@yourdomain.com',
                'pass' => 'your-password',
              ],
            ],
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={9-30} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { Email = "sarah@acme-corp.com" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Providers = new Dictionary<string, MessageProvidersType>()
          {
              {
                  "smtp",
                  new()
                  {
                      Override = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
                          """
                          {
                            "config": {
                              "host": "smtp.yourdomain.com",
                              "port": 587,
                              "secure": false,
                              "requireTLS": true,
                              "auth": {
                                "user": "user@yourdomain.com",
                                "pass": "your-password"
                              }
                            }
                          }
                          """
                      ),
                  }
              },
          },
      },
  };

  var response = await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={5} wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"email": "sarah@acme-corp.com"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.providers '{"smtp": {"override": {"config": {"host": "smtp.yourdomain.com", "port": 587, "secure": false, "requireTLS": true, "auth": {"user": "user@yourdomain.com", "pass": "your-password"}}}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template to sarah@acme-corp.com over STARTTLS on port 587.
  ```
</CodeGroup>

**Implicit TLS (port 465):**

<CodeGroup>
  ```javascript Node.js highlight={8-20} theme={null}
  const { requestId } = await courier.send.message({
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com",
      },
      providers: {
        smtp: {
          override: {
            config: {
              host: "smtp.yourdomain.com",
              port: 465,
              secure: true,
              auth: {
                user: "user@yourdomain.com",
                pass: "your-password",
              },
            },
          },
        },
      },
    },
  });
  ```

  ```python Python highlight={8-20} theme={null}
  response = client.send.message(
      message={
          "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
          "to": {
              "email": "sarah@acme-corp.com",
          },
          "providers": {
              "smtp": {
                  "override": {
                      "config": {
                          "host": "smtp.yourdomain.com",
                          "port": 465,
                          "secure": True,
                          "auth": {
                              "user": "user@yourdomain.com",
                              "pass": "your-password",
                          },
                      },
                  },
              },
          },
      },
  )
  ```

  ```bash cURL highlight={11-23} wrap theme={null}
  curl -X POST https://api.courier.com/send \
    -H "Authorization: Bearer $COURIER_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "message": {
        "template": "nt_01kx4h2jdafq8bk9aftxak4b40",
        "to": {
          "email": "sarah@acme-corp.com"
        },
        "providers": {
          "smtp": {
            "override": {
              "config": {
                "host": "smtp.yourdomain.com",
                "port": 465,
                "secure": true,
                "auth": {
                  "user": "user@yourdomain.com",
                  "pass": "your-password"
                }
              }
            }
          }
        }
      }
    }'
  ```

  ```ruby Ruby highlight={8-20} theme={null}
  response = courier.send_.message(
    message: {
      template: "nt_01kx4h2jdafq8bk9aftxak4b40",
      to: {
        email: "sarah@acme-corp.com"
      },
      providers: {
        smtp: {
          override: {
            config: {
              host: "smtp.yourdomain.com",
              port: 465,
              secure: true,
              auth: {
                user: "user@yourdomain.com",
                pass: "your-password"
              }
            }
          }
        }
      }
    }
  )
  ```

  ```go Go highlight={10-22} theme={null}
  response, err := client.Send.Message(context.TODO(), courier.SendMessageParams{
  	Message: courier.SendMessageParamsMessage{
  		To: courier.SendMessageParamsMessageToUnion{
  			OfUserRecipient: &shared.UserRecipientParam{
  				Email: courier.String("sarah@acme-corp.com"),
  			},
  		},
  		Template: courier.String("nt_01kx4h2jdafq8bk9aftxak4b40"),
  		Providers: shared.MessageProvidersParam{
  			"smtp": shared.MessageProvidersTypeParam{
  				Override: map[string]any{
  					"config": map[string]any{
  						"host": "smtp.yourdomain.com",
  						"port": 465,
  						"secure": true,
  						"auth": map[string]any{
  							"user": "user@yourdomain.com",
  							"pass": "your-password",
  						},
  					},
  				},
  			},
  		},
  	},
  })
  ```

  ```java Java highlight={6-16} theme={null}
  SendMessageParams params = SendMessageParams.builder()
      .message(SendMessageParams.Message.builder()
          .to(UserRecipient.builder().email("sarah@acme-corp.com").build())
          .template("nt_01kx4h2jdafq8bk9aftxak4b40")
          .providers(MessageProviders.builder()
              .putAdditionalProperty("smtp", JsonValue.from(java.util.Map.of("override", java.util.Map.of(
                      "config", java.util.Map.of(
                          "host", "smtp.yourdomain.com",
                          "port", 465,
                          "secure", true,
                          "auth", java.util.Map.of(
                              "user", "user@yourdomain.com",
                              "pass", "your-password"
                          )
                      )
                  ))))
              .build())
          .build())
      .build();
  SendMessageResponse response = client.send().message(params);
  ```

  ```php PHP highlight={8-20} theme={null}
  $response = $client->send->message(
    message: [
      'template' => 'nt_01kx4h2jdafq8bk9aftxak4b40',
      'to' => [
        'email' => 'sarah@acme-corp.com',
      ],
      'providers' => [
        'smtp' => [
          'override' => [
            'config' => [
              'host' => 'smtp.yourdomain.com',
              'port' => 465,
              'secure' => true,
              'auth' => [
                'user' => 'user@yourdomain.com',
                'pass' => 'your-password',
              ],
            ],
          ],
        ],
      ],
    ],
  );
  ```

  ```csharp C# highlight={9-29} theme={null}
  SendMessageParams parameters = new()
  {
      Message = new()
      {
          To = new UserRecipient { Email = "sarah@acme-corp.com" },
          Template = "nt_01kx4h2jdafq8bk9aftxak4b40",
          Providers = new Dictionary<string, MessageProvidersType>()
          {
              {
                  "smtp",
                  new()
                  {
                      Override = JsonSerializer.Deserialize<Dictionary<string, JsonElement>>(
                          """
                          {
                            "config": {
                              "host": "smtp.yourdomain.com",
                              "port": 465,
                              "secure": true,
                              "auth": {
                                "user": "user@yourdomain.com",
                                "pass": "your-password"
                              }
                            }
                          }
                          """
                      ),
                  }
              },
          },
      },
  };

  var response = await client.Send.Message(parameters);
  ```

  ```bash CLI highlight={5} wrap theme={null}
  courier send message \
    --api-key "$COURIER_API_KEY" \
    --message.to '{"email": "sarah@acme-corp.com"}' \
    --message.template nt_01kx4h2jdafq8bk9aftxak4b40 \
    --message.providers '{"smtp": {"override": {"config": {"host": "smtp.yourdomain.com", "port": 465, "secure": true, "auth": {"user": "user@yourdomain.com", "pass": "your-password"}}}}}'
  ```

  ```text MCP theme={null}
  With Courier MCP, send my template to sarah@acme-corp.com over implicit TLS on port 465.
  ```
</CodeGroup>

**Common provider settings:**

| Provider              | Host                  | Port | secure | requireTLS |
| --------------------- | --------------------- | ---- | ------ | ---------- |
| Office 365            | `smtp.office365.com`  | 587  | false  | true       |
| Gmail (app password)  | `smtp.gmail.com`      | 587  | false  | true       |
| On-prem Exchange      | `mail.yourdomain.com` | 587  | false  | true       |
| Custom (implicit TLS) | varies                | 465  | true   | -          |

**Transport options reference:**

| Option              | Type    | Description                                                                      |
| ------------------- | ------- | -------------------------------------------------------------------------------- |
| `host`              | string  | SMTP server hostname                                                             |
| `port`              | number  | SMTP port (commonly 25, 465, 587)                                                |
| `secure`            | boolean | Use SSL (true for port 465)                                                      |
| `requireTLS`        | boolean | Require STARTTLS (true for port 587)                                             |
| `auth`              | object  | Authentication credentials `{ user, pass }`                                      |
| `tls`               | object  | TLS options (see [NodeMailer TLS docs](https://nodemailer.com/smtp#tls-options)) |
| `connectionTimeout` | number  | Connection timeout in milliseconds                                               |
| `socketTimeout`     | number  | Socket timeout in milliseconds                                                   |

**All options:** See the [NodeMailer SMTP transport documentation](https://nodemailer.com/smtp) for every `config` override option.

## Security best practices

* Use app-specific passwords for Office 365 and Gmail, not regular account passwords.
* Send from a dedicated service account, not a personal one.
* Store credentials in Courier Studio instead of passing them in every API request.
* Always use TLS: set `requireTLS: true` for port 587, `secure: true` for port 465.
* For HIPAA or data residency requirements, use a direct connection to your on-premises SMTP server.

## Troubleshooting

Courier verifies your SMTP connection before each send. If verification fails, Courier does not send the message and returns an error. Courier retries connection timeouts (`ETIMEDOUT`) and temporary server unavailability.

<AccordionGroup>
  <Accordion title="Connection Timeouts">
    * Check that firewall rules allow outbound connections to your SMTP server
    * Check the SMTP host and port
    * Check that your SMTP server is reachable from Courier's infrastructure
  </Accordion>

  <Accordion title="Authentication Failures">
    * Check the username and password
    * For Office 365 with MFA enabled, use an app-specific password
    * Check that the account may send email over SMTP
  </Accordion>

  <Accordion title="TLS/SSL Errors">
    * Check that your SMTP server supports the encryption method you requested
    * Check certificate validity if you use custom certificates
    * Check that `secure` and `requireTLS` match your server configuration
  </Accordion>
</AccordionGroup>

## Provider details

```text theme={null}
smtp
```

Courier recommends routing to the channel. Naming this key in `routing.channels` instead is supported, and sends through just this provider.

<Card title="Send to a specific provider" icon="bullseye-arrow" href="/docs/send/send-to-a-provider" horizontal arrow="true">
  When that is worth doing, and what you give up: failover, channel priority, and providers you add later.
</Card>
