API Reference
API Reference
GitHub ↗
SMTP and Domains

SMTP Servers

Configure SMTP servers for email delivery

An SMTP server is a route out. A project can hold several, arranged into groups that decide which one a given message tries and what it falls back to. The server’s IP is what receivers see, so its reverse DNS and TLS are two of the bulk sender requirements that are met here rather than in Mailyard.

Adding one

POST /api/v1/smtp-servers

name is required and is how you refer to the server everywhere else. host and port are required for an ordinary SMTP relay — a provider reached over an API has neither.

curl -X POST http://localhost:3000/api/v1/smtp-servers \
  -H "Authorization: Bearer myk_..." \
  -H "Content-Type: application/json" \
  -d '{
    "name": "primary-relay",
    "host": "smtp.relay.example.net",
    "port": 587,
    "username": "acme-industrial",
    "password": "'"$SMTP_PASSWORD"'",
    "encryption": "starttls",
    "allowed_emails": ["noreply@yourdomain.com", "alerts@yourdomain.com"]
  }'

username and password are both optional — a relay authenticated by IP address, or an internal one that requires nothing, is a legitimate configuration. The password is sealed at rest and never returned by any read.

On PATCH /api/v1/smtp-servers/{id} an empty password leaves the stored one in place, so a form can send the field blank without erasing it. An empty username clears the login.

Encryption Options

ValuePortDescription
none25No encryption (not recommended)
starttls587Upgrade to TLS after connecting
ssl465TLS from the start

Testing Connections

Verify SMTP credentials and connectivity before sending via POST /api/v1/smtp-servers/{id}/test. This validates the hostname, port, credentials, and encryption.

A passing test puts an invalid server back to enabled, a failing one marks an enabled server invalid. A disabled server stays disabled either way - the result is recorded, and only Enable puts it back.

Taken out of rotation

A server that refuses its login (SMTP 535, 534 or 538, or SES rejecting the access key) or presents a certificate that does not verify is marked invalid by the delivery worker. The message moves on to the next server in the group and the project gets a notification. An invalid server is not tried again until a test succeeds, which puts it back to enabled. A temporary refusal such as 454, a timeout or a refused connection does not take a server out.

Editing a server never changes its status. When the edit touches what the dial uses - host, port, encryption, username, password or a provider option - an invalid server’s reason becomes “settings changed”, and it stays out of rotation until the next test passes.

The shared pool and relay nodes are never marked this way - they are not the project’s to fix.

Private network targets are refused

A project’s server cannot point at loopback, RFC 1918 or other reserved address space, and neither can a provider’s endpoint override. The host is a project member’s choice and the connection test reports what the peer answered, so without that guard the button is a scanner of the network Mailyard runs in. The check happens when the row is written and again at every dial, after the name has resolved.

A relay node enrolled into a project is a project server like any other: a private hostname is refused at enrolment and at every dial. sending.allow_private_smtp_targets lifts it, for a relay that genuinely is on the same network. The shared pool, its relay nodes included, is never subject to it - an operator placed those.

Sender Restrictions

Use allowed_emails to restrict which sender addresses can use a specific SMTP server. This is useful when different servers are configured for different brands or departments. Each entry is an exact address or *@domain, and allowed_domains takes bare domain names. Anything else is refused when the server is saved, since an entry that matches no sender would only show up as a send with no server to carry it.

Note

Passwords are never returned in API responses.

Common SMTP Providers

ProviderHostPortEncryption
Gmailsmtp.gmail.com587starttls
Outlooksmtp.office365.com587starttls
Amazon SESemail-smtp.us-east-1.amazonaws.com587starttls
Mailgunsmtp.mailgun.org587starttls
Postfix (local)localhost25none

Grouping and order

Servers belong to groups , which is how a send picks one and how failover decides what to try next. A project that never creates a group has exactly one, the default, holding every server - which is the behaviour that existed before groups.

If a project has no server

A project that has configured no SMTP server delivers through the platform’s shared pool , if an administrator has set one up. Adding a server here takes delivery over completely: from that point the pool is not consulted, even if the server you added is disabled or refuses the sender.

Providers

A server row says how it is reached, not only where. Two providers today:

ProviderHowFields it asks for
smtpA dialhost, port, encryption, optional username and password
sesThe Amazon SES APIregion, optional configuration set, optional access key

Everything else about a row is the same whichever it is: it sits in a group , takes a priority, honours its allowed senders, and takes part in failover. A group can hold both, and failover walks it in the same order - which is what lets an SES row be the primary and a plain relay the fallback.

provider is set when the server is created and cannot be patched afterwards. The credentials mean something different to each one - an SMTP login on one, an access key on the other - so switching in place would leave the wrong ones in the fields a PATCH does not touch. Delete and recreate instead.

A row reached over an API shows no host and no encryption, and the console says so rather than leaving the cells blank: “none” under encryption would read as cleartext when the call is HTTPS.