---
title: "Send over SMTP"
description: "The same send as POST /emails, for software that speaks SMTP."
url: "https://openemail.uk/docs/api/emails/smtp"
area: "API"
category: "Emails"
---

# Send over SMTP

The same send as POST /emails, for software that speaks SMTP.

## Connect

Anything that sends mail through an SMTP server can send through OpenEmail: a framework mailer, a CMS, a monitoring tool, a printer. Sign in with the username `openemail` and an API key as the password. The key needs the `emails:send` scope, and a message it hands over is the same send as `POST /emails` made with that key.

| Setting | Value |
| --- | --- |
| Host | `smtp.openemail.uk` |
| Port | `465` with SSL/TLS, or `587` with STARTTLS |
| Username | `openemail` |
| Password | An API key with the `emails:send` scope |
| Sign-in | PLAIN or LOGIN, which most software calls a normal password |

> Nothing is accepted unencrypted, and on port 587 the sign-in opens only after STARTTLS. An API key signs in to send only. Reading a mailbox over IMAP or POP3 takes an app password.

## Send a test message

Save a message as `message.eml` and hand it over with curl. `From` has to be an address the key may send as.

**message.eml**

```
From: Acme <hello@acme.com>
To: ada@example.com
Subject: Hello over SMTP
Message-ID: <first-test@acme.com>

It works.
```

**Port 465**

```
curl --url "smtps://smtp.openemail.uk:465" \
  --user "openemail:$OPENEMAIL_API_KEY" \
  --mail-from "hello@acme.com" \
  --mail-rcpt "ada@example.com" \
  --upload-file message.eml --crlf
```

**Port 587**

```
curl --ssl-reqd --url "smtp://smtp.openemail.uk:587" \
  --user "openemail:$OPENEMAIL_API_KEY" \
  --mail-from "hello@acme.com" \
  --mail-rcpt "ada@example.com" \
  --upload-file message.eml --crlf
```

The answer to an accepted message is `250 2.0.0 OK queued as` followed by its id. That id is the one `GET /emails/{id}` takes, so the message, its events and its tracking are read like those of any other send.

## How a message becomes a send

The message is read and sent through the same path as a REST send, so it is rebuilt from its parts and not passed on byte for byte.

| In the message | In the send |
| --- | --- |
| `From` | `from`. It is required, and it is the sender the key is checked against. The address in `MAIL FROM` only has to be there. |
| `RCPT TO` | Who the message is delivered to, 50 at most. A recipient named in `To` is a `to`, one named in `Cc` is a `cc`, and one named in neither is a `bcc`. At least one has to be in `To`. |
| `Reply-To` | `replyTo`, the first address. |
| `Subject` | `subject`. |
| The text and HTML parts | `text` and `html`. An image the HTML uses as `cid:` is embedded where it appears. |
| Attachments | `attachments`: 20 files at most and 5 MB in all. |
| Other headers | `X-*`, `List-*`, Precedence, Auto-Submitted, Importance, Priority and Feedback-ID are kept. Every other header is left out. |
| `X-OpenEmail-Stream` | `stream`: `transactional` or `broadcast`. The header is removed before the message leaves. |

## What applies

Everything a REST send is held to holds here, because it is one path.

- The scopes of the key, and the addresses and domains it is limited to.
- The sender check: `From` is an address on a domain that can send, and one the key may send as.
- The send quota of the workspace and its suppression list.
- The signature and the open and click tracking of the address it is sent from, as on a REST send that sets neither `signature` nor `tracking`.
- The lane: while the broadcast lane is paused, a message with `X-OpenEmail-Stream: broadcast` is refused.
- Webhooks and delivery events, which name the message by the id in the `250` reply.

## Retries

A message with a `Message-ID` is sent once. Handing over the same `Message-ID` for the same recipients again answers with the id of the first message and sends nothing, so software that retries after a dropped connection cannot send it twice. The same message for other recipients is another send. See Idempotency.

## Replies and limits

| Reply | When |
| --- | --- |
| `250 2.0.0` | The message is queued, and its id follows. |
| `535 5.7.8` | The sign-in failed: a wrong, revoked or expired key, a key without `emails:send`, or an API key under another username. |
| `452 4.5.3` | More than 50 recipients in one message. Mail software sends the rest in another one by itself. |
| `552 5.3.4` | The message is larger than 25 MB. |
| `550 5.6.0` | The message cannot be sent as written: no `From`, nobody in `To`, too many or too large attachments, an unknown lane. The text says which. |
| `550 5.7.1` | The send was refused: the key may not send as that address, the domain cannot send yet, or the broadcast lane is paused. |
| `452 4.7.0` | The send quota of the workspace is used up. |
| `451 4.7.1` | More than 300 messages from one key in a minute. Mail software waits and tries again. |
| `451 4.3.0` | A fault on our side. Try again shortly. |

> A connection with nothing to send closes after five minutes. One connection can carry any number of messages, one after another.

## In the request log

Every message a key hands over is a line in its request log, with the method `SMTP`, the path `/emails` and the status a REST send would have had: 202 when it was queued, and 403, 422 or 429 with the same error `code` when it was refused. `GET /keys/{id}/requests?path=/emails` lists them beside the REST sends. A sign-in that fails with a real key shows in the activity of that key.
