/documentation
Point, authenticate, send.
justsmtp is a drop-in SMTP relay in front of Amazon SES. Point your existing mailer at smtp.justsmtp.com, authenticate with a credential pair generated in the dashboard, and send. No AWS account, no IAM policies.
- Add your domain and publish the DNS records we show you — three DKIM CNAMEs.
- Generate an SMTP credential. The password is shown once, so put it in your secrets manager as you copy it.
- Point your mail config at
smtp.justsmtp.com:587and send.
Connection settings
These don't change — safe to hard-code or drop straight into an env file.
| setting | value | notes |
|---|---|---|
| host | smtp.justsmtp.com | nearest region answers |
| port | 587 | STARTTLS required |
| fallback port | 2525 | if your host blocks 587 outbound |
| auth mechanisms | AUTH LOGIN, AUTH PLAIN | only after STARTTLS |
| username / password | justsmtp_****** | from Credentials, shown once at creation |
| from address | anything@your-verified-domain | the domain must be verified |
Port 25 is not offered. It is for server-to-server relay and is blocked outbound from practically every application host anyway.
How it works
Your application connects to smtp.justsmtp.com over STARTTLS
and authenticates with the username and password from a credential pair.
We accept the message over SMTP, check the sending domain is one you have verified, and hand it off to Amazon SES for delivery.
Every attempt — sent, deferred, bounced, dropped — lands in your activity log with the real upstream SMTP response. We don't retain message bodies; the log keeps metadata and the subject line only.
your app ──SMTP──▶ smtp.justsmtp.com ──▶ Amazon SES ──▶ recipient
│ │
└── quota, auth └── events ──▶ activity log
Integrations
justsmtp works with any SMTP client. Swap the host, port and credentials into your existing mailer — nothing else changes.
// npm install nodemailer import nodemailer from 'nodemailer'; const transport = nodemailer.createTransport({ host: 'smtp.justsmtp.com', port: 587, secure: false, auth: { user: process.env.SMTP_USER, pass: process.env.SMTP_PASS }, }); await transport.sendMail({ from: '"Acme" <hello@mail.acme.io>', to: 'sarah@example.com', subject: 'Welcome to Acme', html: '<b>You are in.</b>', });
import os, smtplib from email.message import EmailMessage msg = EmailMessage() msg["From"] = "Acme <hello@mail.acme.io>" msg["To"] = "sarah@example.com" msg["Subject"] = "Welcome to Acme" msg.set_content("You are in.") with smtplib.SMTP("smtp.justsmtp.com", 587) as server: server.starttls() server.login(os.environ["SMTP_USER"], os.environ["SMTP_PASS"]) server.send_message(msg)
# gem install mail require 'mail' Mail.defaults do delivery_method :smtp, { address: 'smtp.justsmtp.com', port: 587, user_name: ENV['SMTP_USER'], password: ENV['SMTP_PASS'], authentication: :plain, enable_starttls_auto: true, } end Mail.deliver do from 'hello@mail.acme.io' to 'sarah@example.com' subject 'Welcome to Acme' body 'You are in.' end
// composer require symfony/mailer use Symfony\Component\Mailer\Transport; use Symfony\Component\Mailer\Mailer; use Symfony\Component\Mime\Email; $transport = Transport::fromDsn( 'smtp://'.getenv('SMTP_USER').':'.getenv('SMTP_PASS').'@smtp.justsmtp.com:587' ); $mailer = new Mailer($transport); $mailer->send((new Email()) ->from('hello@mail.acme.io') ->to('sarah@example.com') ->subject('Welcome to Acme') ->html('<b>You are in.</b>'));
Using something else? If it has a host field and a port field, it
already works. help@justsmtp.com if it does not.
HTML forms
A contact form on a static site with no backend of yours and no JavaScript. Paste the snippet, and a visitor's submission arrives as email from your own verified domain, with their address as the reply-to. It counts as one message against your plan and lands in your activity log like any other send.
Bots find public form actions within hours, so the defence is on by default: a signed token, a beacon that measures how long the form was open, two hidden decoy fields, and rate limits. A dropped submission gets exactly the answer a real one gets — the counters on the form's page are where you see what happened.
<form method="POST" action="https://api.justsmtp.com/f/PUBLIC_ID" accept-charset="UTF-8">
<input type="hidden" name="_ftk" value="TOKEN">
<img src="https://api.justsmtp.com/f/PUBLIC_ID/start" width="1" height="1" alt="" class="jsf-hp">
<input type="text" name="company" tabindex="-1" autocomplete="off" aria-hidden="true" class="jsf-hp">
<input type="text" name="website" tabindex="-1" autocomplete="off" aria-hidden="true" class="jsf-hp">
<label>Name <input type="text" name="name" required></label>
<label>Email <input type="email" name="email" required></label>
<label>Message <textarea name="message" required></textarea></label>
<button type="submit">Send</button>
</form>
<style>.jsf-hp{position:absolute;left:-9999px;width:1px;height:1px;overflow:hidden}</style>
| bound or limit | value | notes |
|---|---|---|
| forms per account | 1 / 5 / 25 | hobby / starter / pro |
| submissions per form per day | 50 / 250 / 1,000 | on top of your monthly quota, so a flood cannot spend it |
| fields per submission | 50 | 64 values each, 10,000 characters per value, 64-character names |
| request body | 128 KB | over a bound is a 400; file parts are refused |
| per visitor, per form | 4 / 10 min | 30 per form per hour, 10 per destination address per hour |
| success | 303 or 200 | redirect to your URL if set, else a
thank-you page; {"ok":true} with Accept: application/json |
A field named email becomes the reply-to. Nothing a visitor typed is stored on our
side — the email is the record. Create a form, copy its snippet and read its counters on
Forms.