Mail apps, SMTP and forwarding
Send from any SMTP library, read and answer an inbox in Apple Mail, Thunderbird or Outlook over IMAP, and forward an inbox's mail to other addresses.
SMTP submission
SMTP is an alternative to POST /v1/emails. A message goes through the same pipeline: the sender must be on a
verified domain of the key's workspace, and plan limits, suppressions, DKIM, message.* events, webhooks and the
Sending log all apply. See Sending.
| Setting | Value | |
|---|---|---|
| Host | smtp.runearc.com | |
| Port | 465 (implicit TLS) or 587 (STARTTLS) | Sign in is only accepted over TLS. |
| Username | runearc | |
| Password | An API key with sending or full access (mb_live_...) | Inbox limited keys cannot send. A sending key limited to one domain sends only from it. |
| From | Any address on a verified domain of the key's workspace |
import nodemailer from "nodemailer";
const transport = nodemailer.createTransport({
host: "smtp.runearc.com",
port: 465,
secure: true, // port 587 with secure: false and requireTLS: true also works
auth: { user: "runearc", pass: process.env.RUNEARC_API_KEY },
});
await transport.sendMail({ from: "Acme <noreply@acme.com>", to: "user@example.com", subject: "Welcome", text: "Hello" });| Limit | Value | |
|---|---|---|
| Message size | 25 MB | Larger gets 552 5.3.4. |
| Recipients | 50 per message | 452 4.5.3. |
| Rate | 600 messages an hour per key and per client IP | 451 4.7.1. Self hosted: SUBMISSION_RATE_PER_HOUR. |
| Failed logins | 10 from one IP in 15 minutes lock it out for 15 minutes | 535 5.7.8, then 454 4.7.0. |
250 2.0.0 OK queued as eml_... is returned only after the email is stored and handed to the mail transport;
temporary failures are 451 4.3.0 so clients retry. A message whose Message-ID was already accepted in the
workspace is not sent again; the server answers 250 with the original email id. A sender outside your verified
domains gets 550 5.7.1 with a fix. Bcc headers are removed. To use a template over SMTP,
see the headers on Emails API.
App passwords
Mail apps use an app password for one inbox instead of an API key. It acts as the user who made it, limited to that inbox and capped at the Support role: it reads, and sends or replies only if the user's role may reply (a Viewer's reads only). It stops working as soon as the user is removed from the workspace or loses the inbox.
| Request | Body | Returns |
|---|---|---|
| POST /v1/inboxes/{id}/app-passwords | name | 201 with password (abcd-efgh-ijkl-mnop, shown once, stored hashed), username (the inbox address), the IMAP and SMTP hosts and ports. |
| GET /v1/inboxes/{id}/app-passwords | none | Yours; inbox managers see everyone's. Never includes the password. |
| DELETE /v1/app-passwords/{id} | none | 204. Members revoke their own; inbox managers revoke any. |
Dashes and case in the password do not matter. At most 20 per user per inbox (app_password_limit_reached).
Creating and revoking are in the audit log. App passwords are made from a dashboard session; there is no CLI
command or MCP tool.
IMAP
| Setting | Value | |
|---|---|---|
| IMAP host | imap.runearc.com | Port 993 (SSL/TLS) or 143 (STARTTLS). |
| SMTP host | smtp.runearc.com | Port 465 (SSL/TLS) or 587 (STARTTLS). |
| Username | The inbox address, such as support@acme.com | |
| Password | An app password | Plain login (LOGIN or AUTHENTICATE PLAIN), only after TLS. |
Runearc serves an IMAP4rev1 subset with IDLE, MOVE, UIDPLUS, UNSELECT, NAMESPACE, ID, ENABLE, SPECIAL-USE,
LITERAL+ and SASL-IR, so new mail shows within seconds. Mail the inbox sends over SMTP with the same app
password appears in Sent, and a reply continues its conversation.
| Mailbox | Shows | Moving mail here |
|---|---|---|
| INBOX | Received mail of open conversations. | From Archive: reopens the conversation. |
| Archive | Received mail of closed conversations. | From INBOX: closes the conversation. |
| Sent | Mail sent from the inbox (API, dashboard, SMTP). | Refused. APPEND is accepted and dropped, since Runearc keeps what it sends. |
| Junk | Received mail scored as spam. | Refused. |
| Trash | Always empty. | Hides the message from this app password only. |
Conversations, not single messages, are open or closed. \Seen is the dashboard's read state for the user.
Deleting and expunging hide a message from that app password only; nothing is deleted for the team. There is no
Drafts mailbox: apps keep drafts locally. UIDs are stable and UIDVALIDITY never changes.
Limits: 60 new connections per client IP a minute, 10 failed sign ins per IP and per username in 10 minutes
(then NO [UNAVAILABLE]), 60 seconds to sign in and 30 minutes idle before logout. Typical errors:
NO [AUTHENTICATIONFAILED] (wrong or revoked password, make a new one), NO [PRIVACYREQUIRED] (use TLS or
STARTTLS) and NO [NOPERM] when archiving (the role cannot reply in the inbox).
Sent, Junk Junk, Trash Trash and Archive Archive; the dashboard inbox page also offers a configuration profile. In Thunderbird choose manual configuration with the values above.Forwarding
An inbox can forward a copy of every message it receives to other addresses. Adding a target emails it a
confirmation link; it stays pending until the link is opened (valid 7 days), then active. Each inbox has at
most 10 targets.
| Request | Body | Returns |
|---|---|---|
| GET /v1/inboxes/{id}/forwards | none | Targets: id, inbox_id, forward_to, status (pending, active or disabled), verify_sent_at, verified_at. |
| POST /v1/inboxes/{id}/forwards | 201 and the target, pending. | |
| POST /v1/forwards/verify | token | Confirms the target. No auth; the token is in the email link. |
| DELETE /v1/forwards/{id} | none | 204. |
The copy is sent from "Original Name via Runearc" <forwarding@<inbox domain>> with Reply-To set to the inbox,
so a reply lands back in the inbox and threads. The original headers are kept as X-Original-*, and copies
carry X-Runearc-Forwarded: 1 so mail is never forwarded twice. Each copy counts as one sent email against the
plan, and suppressed targets are skipped. Forwarding has no CLI command or MCP tool.
Errors
| Code | Status | Meaning and fix |
|---|---|---|
| app_password_limit_reached | 402 | Revoke one you no longer use (20 per user per inbox). |
| forward_to_self | 400 | Forward to a different address. |
| forward_exists | 409 | That address is already a target of this inbox. |
| forward_limit_reached | 402 | At most 10 targets per inbox. |
| forward_verification_invalid | 404 | The confirmation link is wrong. Add the target again. |
| forward_verification_expired | 400 | The link is older than 7 days. Remove and add the target again. |