Email

Email & SMTP

Connect your own SMTP provider so a project sends auth codes, welcome emails, API sends and broadcasts from your domain, or rely on the rate-limited shared sender for auth email.

Each project can send email through an SMTP server you configure for it. That covers the automatic auth emails, the Email API and marketing broadcasts. Projects without SMTP still send auth emails through a shared OrbitNest sender, with rate limits and the built-in templates.

How project email works

ChannelTriggered byWith project SMTPWithout project SMTP
Auth emailsProject auth flows (sign-up, email OTP sign-in, password recovery)Sent through your SMTP, with your custom templates if savedSent through the shared sender with the built-in templates
Email APIYour server or edge function calling POST /api/project/:slug/email/sendSent through your SMTPFails with 400
Marketing broadcastsA workspace admin sending from Studio, or the admin APISent through your SMTPEvery recipient fails
Template previewsA workspace admin sending a test from the template editorSent through your SMTPFails with 400

To test auth without sending any email, turn on debug mode.

Emails OrbitNest sends for you

EmailTemplate typeSent when
Verification codeotp_verificationPOST /api/projects/:projectId/auth/signup, signup-with-email and signin-with-email
Password reset codepassword_resetPOST /api/projects/:projectId/auth/recover (alias recover-password), when the email belongs to an existing user
Welcome emailwelcomeAfter verify-signup creates a new user
  • Verification and reset codes are 4 digits and expire after 10 minutes.
  • If the code email fails, the auth request fails too.
  • The welcome email is sent in the background. If it fails, the error is logged and sign-up still succeeds.
  • If no account exists for the address, password recovery and email sign-in still return a success response and send nothing.

See Authentication for the full flows.

Note

Studio account emails, such as workspace invitations, Studio sign-up codes and support notifications, are sent by OrbitNest itself. They never use your project's SMTP.

Shared sender for auth email

When a project has no SMTP configured, or SMTP is turned off, the three auth emails above are sent by OrbitNest's own mail server:

  • From: "<Project name> via OrbitNest" at an OrbitNest address.
  • Reply-To: a no-reply address at the OrbitNest domain, so replies are not delivered.
  • Content: the built-in templates only, branded with your project name, logo and brand color. Your saved custom templates are used only with your own SMTP.
  • Rate limits: 100 emails per hour per project, and 5 per hour to the same recipient. Over either limit, the auth request returns 429 with code SHARED_EMAIL_RATE_LIMITED and nothing is sent.

The shared sender carries auth email only. The Email API, broadcasts and template previews always need project SMTP.

Use your own SMTP in production

Your own SMTP removes the rate limits, sends from your domain, and uses your custom templates.

Configure SMTP in Studio

Open your project and go to Settings → SMTP. Project settings are only visible to workspace admins, and only admins can change them.

FieldAPI fieldRequiredDefaultNotes
Hostsmtp_hostYesFor example smtp.sendgrid.net. Must be a public host (see Allowed hosts)
Portsmtp_portYes5871–65535
Usernamesmtp_userNoLeave blank for an unauthenticated relay. Encrypted at rest. The API returns it masked: nor***@myapp.com, or *** if the username is not an email address
Passwordsmtp_passwordYes for a new loginEncrypted at rest and never returned. Leave it blank to keep the current password
SSL/TLSsmtp_secureNoOffOn means implicit TLS (port 465). Off means STARTTLS (port 587)
From Emailsmtp_from_emailYesThe sender address. It must be allowed by your provider
From Namesmtp_from_nameNoThe display name for the sender
Enable SMTPsmtp_enabledNoOnWhen off, the project behaves as if no SMTP is configured

Click Save. After the settings are saved, a Test section and a Delete Configuration option appear.

Need credentials? → Open guide has setup steps and values for Gmail, Outlook / Microsoft 365, SendGrid, Mailgun, Amazon SES and Custom / Postfix.

Ports and TLS

  • 587 with SSL/TLS off uses STARTTLS. This is the recommended setting.
  • 465 with SSL/TLS on uses implicit TLS. Many cloud hosts block outbound port 465, so use 587 if you can.
  • Connections time out after 10 seconds, and an idle socket times out after 15 seconds.

Allowed hosts

The SMTP host must resolve to a public address. Saving a host that is, or resolves to, a private, loopback, link-local or other internal address returns 400 (SMTP host "…" is not allowed (private, loopback or internal address).). The same applies to localhost and names ending in .local, .internal, .localhost, .lan or .corp. A host that doesn't resolve also returns 400.

The host is checked again on every send, and OrbitNest connects to the address it checked. A relay on your own private network, such as a local Postfix, can't be used.

Provider notes

  • Gmail: use an App Password, which requires 2-Step Verification. Gmail rewrites the From header to the authenticated account, so a different From Email only shows up if you add it as a verified "Send mail as" alias in Gmail.
  • SendGrid: the username is the literal string apikey, and the password is an API key with Mail Send permission.
  • Amazon SES: use the SMTP credentials SES generates, not your AWS access keys, and the host for your region (email-smtp.<region>.amazonaws.com). In the SES sandbox, both the From address and every recipient must be verified identities.
  • Mailgun: use the SMTP credentials for your sending domain, not the API key. EU accounts use smtp.eu.mailgun.org.

Authenticate your domain

Set up SPF, DKIM and DMARC for your sending domain with your provider. Without them, the first emails from a new domain often land in spam.

Send a test email

In Settings → SMTP → Test, enter an address and click Send. OrbitNest connects with your saved settings, verifies the connection, and sends a short test message. Tests are limited to 10 per minute per IP address.

The API returns 200 even when the test fails, so check the success field:

JSON
{ "success": false, "message": "SMTP test failed: Invalid login: 535 Authentication failed" }
  • Connection-level failures (refused, timed out, unreachable, TLS errors) all return the same message: Could not connect to the SMTP server. Check the host, port and SSL/TLS setting.
  • Credential-like values are removed from error messages before they are returned.

Sender identity

These apply to email sent through your project SMTP:

  • From: "From Name" <from_email>, or just the address if no name is set.
  • Reply-To: your From Email, so replies reach your inbox.
  • Branding: auth emails use your project name, the logo from Settings → General → Logo and the brand color from the template editor. See Email templates.

Mail from the shared sender uses a different identity. See Shared sender.

Debug mode

The Debug mode toggle in Settings → General is for testing without email:

  • Sign-up, email OTP sign-in and password recovery skip sending email and accept the fixed code 1234.
  • Welcome emails are still attempted. If sending fails, the failure is only logged.

Caution

While debug mode is on, anyone who knows a user's email address can sign in to that account with 1234. Turn it off before real users sign up.

Manage SMTP with the API

These endpoints use a Studio admin access token, which is the access_token returned by POST /api/auth/signin. They do not accept project API keys. :projectId must be the project UUID, which appears in the Studio URL /projects/<id>/....

MethodPathRoleDescription
GET/api/projects/:projectId/smtpAny workspace memberRead settings. The password is never returned
PUT/api/projects/:projectId/smtpAdminCreate or replace settings
POST/api/projects/:projectId/smtp/testAdminSend a test email to test_email
DELETE/api/projects/:projectId/smtpAdminRemove all SMTP settings. Auth email then goes through the shared sender, and the Email API and broadcasts stop working
Terminal
curl -X PUT "https://api.orbitnest.io/api/projects/$PROJECT_ID/smtp" \
  -H "Authorization: Bearer $ORBITNEST_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "smtp_host": "email-smtp.us-east-1.amazonaws.com",
    "smtp_port": 587,
    "smtp_secure": false,
    "smtp_user": "YOUR_SMTP_USERNAME",
    "smtp_password": "YOUR_SMTP_PASSWORD",
    "smtp_from_email": "noreply@my-app.com",
    "smtp_from_name": "My App",
    "smtp_enabled": true
  }'

PUT replaces every field it does not treat as a credential. Any field you leave out goes back to its default: port 587, SSL off, no From Name, enabled. smtp_user and smtp_password are the exception: if you leave them out or send an empty string, the stored values are kept. Omit both for an unauthenticated relay.

GET and PUT return the current settings:

JSON
{
  "smtp_host": "email-smtp.us-east-1.amazonaws.com",
  "smtp_port": 587,
  "smtp_secure": false,
  "smtp_user": "***",
  "smtp_from_email": "noreply@my-app.com",
  "smtp_from_name": "My App",
  "smtp_enabled": true,
  "is_configured": true
}

is_configured is true when a host and From Email are stored.

Send a test email:

Terminal
curl -X POST "https://api.orbitnest.io/api/projects/$PROJECT_ID/smtp/test" \
  -H "Authorization: Bearer $ORBITNEST_ADMIN_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "test_email": "you@example.com" }'

The MCP server can also read and update these settings with the orbitnest_get_smtp_settings and orbitnest_update_smtp_settings tools.

Troubleshooting

When a verification or reset email can't be sent, the auth endpoint returns 503 with one of these hints, or 429 for the shared-sender limit:

ResponseLikely fix
429 SHARED_EMAIL_RATE_LIMITEDWait for the hourly window to pass, or add SMTP settings to remove the limit
This project has no email (SMTP) configured and the shared OrbitNest sender is unavailableAdd SMTP settings, or turn on debug mode for testing
The shared OrbitNest sender could not deliver the emailTry again shortly, or add SMTP settings
Could not reach the configured SMTP serverCheck the host and port and your firewall. Try 587 with SSL/TLS off
SSL/TLS handshake failedOn port 587, turn SSL/TLS off. Only port 465 uses SSL/TLS on
SMTP authentication failedCheck the username and password. For Gmail, use an App Password
SMTP server rejected the From addressUse a verified sender identity. In the SES sandbox, verify the recipient too