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

# SMTP

> Send through smtp.hiveku.com from any app or service that speaks SMTP

Use SMTP when your framework, CMS plugin or sign-in service sends email over SMTP instead of calling an API. Each message goes through the same checks, limits and logs as the [REST API](https://docs.hiveku.com/email/sending.md).

## Settings

| Setting | Value |
| - | - |
| Host | `smtp.hiveku.com` |
| Port | `465` with TLS from the start (recommended), or `587` and `2587` with STARTTLS |
| Username | `apikey` |
| Password | Your Hiveku email API key: `hk_live_...`, `hk_test_...`, or `hvk_email_...` |
| Authentication | `PLAIN` or `LOGIN` |

**Settings > Email Service > SMTP Credentials** shows the host, port `465` and the username, with copy buttons. Port `2587` is a second STARTTLS port, for networks that block `587`.

## Before you start

You need two things:

1. **A verified domain.** The sender address must be on it. See [Domains](https://docs.hiveku.com/email/domains.md).
2. **An API key with the Send Emails permission**, used as the password. See [API keys](https://docs.hiveku.com/email/api-keys.md). A test key works too: its mail is simulated, not delivered.

## Examples

**Nodemailer**

```ts theme={null}
import nodemailer from "nodemailer";

const transporter = nodemailer.createTransport({
  host: "smtp.hiveku.com",
  port: 465,
  secure: true,
  auth: { user: "apikey", pass: process.env.HIVEKU_EMAIL_API_KEY },
});

const info = await transporter.sendMail({
  from: "Acme <noreply@mail.acme.com>",
  to: "customer@example.com",
  subject: "Your order shipped",
  text: "On the way. Tracking: ABC123",
  html: "<p>On the way. Tracking: <b>ABC123</b></p>",
});

console.log(info.response); // 250 Message queued: <the email's id>
```

**Python**

```python theme={null}
import os
import smtplib
from email.message import EmailMessage

msg = EmailMessage()
msg["From"] = "Acme <noreply@mail.acme.com>"
msg["To"] = "customer@example.com"
msg["Subject"] = "Your order shipped"
msg.set_content("On the way. Tracking: ABC123")
msg.add_alternative("<p>On the way. Tracking: <b>ABC123</b></p>", subtype="html")

with smtplib.SMTP_SSL("smtp.hiveku.com", 465) as smtp:
    smtp.login("apikey", os.environ["HIVEKU_EMAIL_API_KEY"])
    smtp.send_message(msg)
```

**Environment**

```bash theme={null}
SMTP_HOST=smtp.hiveku.com
SMTP_PORT=465
SMTP_SECURE=true
SMTP_USER=apikey
SMTP_PASS=hk_live_...
SMTP_FROM=noreply@mail.acme.com
```

In a third-party service, open its custom SMTP settings and enter the values above. Use a sender address on your verified domain.

## How Hiveku reads a message

* **Sign-in.** The username must be `apikey` and the password a key that may send. The key is checked when the client signs in.
* **Sender.** The envelope sender (`MAIL FROM`) must be an address on one of your verified domains, or the message is refused. The From header, with its name, is used when it is on a verified domain. Otherwise Hiveku sends from the envelope address, without a name.
* **Recipients.** The envelope decides who receives the message. Addresses in the To and Cc headers are shown as To and Cc. Every other recipient gets a hidden copy, as Bcc. At most 50 recipients per message.
* **Size.** At most 25 MB per message, as sent.
* **What is kept.** Reply-To, attachments (inline images too), and these headers: `List-Unsubscribe`, `List-Unsubscribe-Post`, `List-Id`, `In-Reply-To`, `References`, `Auto-Submitted`, `Precedence`, and `X-` headers except reserved ones such as `X-Hiveku-`. At most 15 headers. Other headers are dropped, and Hiveku sets From, To, Cc and Subject itself.
* **Subject.** A message without one is sent as "(No Subject)".
* **Tags.** SMTP messages carry no tags. Use the [REST API](https://docs.hiveku.com/email/sending.md#tags) if you need them.
* **Retries.** A client that sends the same message again, byte for byte, after a lost reply gets the first email's answer. The message goes out once.
* **Allowed domains.** A key limited to some domains refuses a sender on any other, over SMTP too.

> [!NOTE]
>
> `X-` headers reach your recipients as they are. Remove headers meant only for an old provider, so they do not leak internal data.

## Replies

A message Hiveku takes is answered `250 Message queued:` and the email's id. Find it in **Settings > Email Service > Email Logs**. With a key that is not a production key, the reply says the message was simulated and nothing was delivered.

When Hiveku refuses, the reply code says whether to retry:

| Code | Meaning | Retry? |
| - | - | - |
| `451` | Try again later: the key's rate, the [daily volume check](https://docs.hiveku.com/email/api-keys.md#daily-volume-check), a message still being sent, or a temporary error. | Yes. Clients retry on their own. |
| `454` | The key could not be checked at sign-in. | Yes |
| `452` | More than 50 recipients. | Send the rest in another message. |
| `535` | Sign-in refused: the username is not `apikey`, the key is wrong, paused or deleted, the key may not send, or sending is off for the account. | No |
| `550` | The sender's domain is not verified or not allowed for the key, every recipient is on the suppression list, or Hiveku's checks refused the message. | No |
| `552` | Over 25 MB. | No |
| `554` | The month's emails are used up, billing blocks sending, or the message was refused. | No |

The reply text says what happened.

## Limits

SMTP shares the limits of the REST API: your plan's monthly emails and each key's rate. See [Limits](https://docs.hiveku.com/email/api-keys.md#limits). SMTP messages also fire [webhook](https://docs.hiveku.com/email/webhooks.md) events, like any other email.


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