Go
The standard library speaks SMTP; net/smtp needs nothing installed.
1Send with net/smtp
package main import ( "fmt" "net/smtp" ) func main() { host := "smtp.mailclutch.com" auth := smtp.PlainAuth("", "mc_0000000000000000", "pw_0000000000000000", host) msg := []byte("To: anyone@example.com\r\n" + "From: staging@example.com\r\n" + "Subject: Sandbox check\r\n" + "\r\n" + "Hello from Go.\r\n") err := smtp.SendMail( fmt.Sprintf("%s:%d", host, 587), auth, "staging@example.com", []string{"anyone@example.com"}, msg, ) if err != nil { panic(err) } }
smtp.SendMail upgrades the connection with STARTTLS when the server offers it, which ours does on every port but 465.
2Or with a library
For attachments and HTML parts, a library saves you writing MIME by hand:
d := gomail.NewDialer("smtp.mailclutch.com", 587, "mc_0000000000000000", "pw_0000000000000000") m := gomail.NewMessage() m.SetHeader("From", "staging@example.com") m.SetHeader("To", "anyone@example.com") m.SetHeader("Subject", "Sandbox check") m.SetBody("text/html", "<h1>Hello from Go</h1>") if err := d.DialAndSend(m); err != nil { panic(err) }
Watch it land
Open the sandbox and the message is there — rendered HTML, plain text, raw source, attachments, and the SPF, DKIM and DMARC verdicts. It updates live, so you can leave it open next to your terminal.
Nothing is ever delivered onward, whatever address you send to; claim the inbox with an account and it stays.
Awaiting your email
Send from any address; it stops here rather than going onward. The inbox keeps what it catches for 24 hours.
What usually goes wrong
Headers are part of the body
net/smtpsends exactly the bytes you hand it. TheTo,FromandSubjectlines have to be in the message, separated from the body by a blank line, with CRLF endings.Port 465
Implicit TLS is not something
smtp.SendMaildoes. Usetls.Dialplussmtp.NewClientfor 465, or stay on 587.
Other stacks
The same four values in another dialect. Every guide below is filled in with the sandbox pair at the top of this page.
Frameworks and languages
- LaravelFive .env variables, no package
- SymfonyOne MAILER_DSN
- DjangoFive settings, nothing installed
- RailsAction Mailer smtp_settings
- Node.jsA Nodemailer transport
- Next.jsRoute Handler or Server Action
- SpringFive Spring Boot properties
- JavaJakarta Mail, no framework
- .NETMailKit: connect, auth, send
- PHPPHPMailer, no framework
- Pythonsmtplib, standard library
- Rustlettre over a STARTTLS relay