How to start sending email¶
Send with SMTP or API¶
It’s up to you, whatever you find easier is fine with us. Here’s something to consider:
SMTP | API |
---|---|
Flexible with existing apps | Faster (x3) |
Open protocol | Assembly (don't worry about MIME) |
Scales better (Batch sending) |
In short, SMTP is an open and established protocol with large ecosystem, while Mailgun API is better long term performance and maintenance wise.
Send via API¶
Run this:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
-F from='Excited User <mailgun@YOUR_DOMAIN_NAME>' \
-F to=YOU@YOUR_DOMAIN_NAME \
-F to=bar@example.com \
-F subject='Hello' \
-F text='Testing some Mailgun awesomeness!'
import com.mailgun.api.v3.MailgunMessagesApi;
import com.mailgun.model.message.Message;
import com.mailgun.model.message.MessageResponse;
// ...
public MessageResponse sendSimpleMessage() {
MailgunMessagesApi mailgunMessagesApi = MailgunClient.config(API_KEY)
.createApi(MailgunMessagesApi.class);
Message message = Message.builder()
.from("Excited User <USER@YOURDOMAIN.COM>")
.to("artemis@example.com")
.subject("Hello")
.text("Testing out some Mailgun awesomeness!")
.build();
return mailgunMessagesApi.sendMessage(YOUR_DOMAIN_NAME, message);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = "YOUR_DOMAIN_NAME";
$params = array(
'from' => 'Excited User <YOU@YOUR_DOMAIN_NAME>',
'to' => 'bob@example.com',
'subject' => 'Hello',
'text' => 'Testing some Mailgun awesomness!'
);
# Make the call to the client.
$mgClient->messages()->send($domain, $params);
def send_simple_message():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
auth=("api", "YOUR_API_KEY"),
data={"from": "Excited User <mailgun@YOUR_DOMAIN_NAME>",
"to": ["bar@example.com", "YOU@YOUR_DOMAIN_NAME"],
"subject": "Hello",
"text": "Testing some Mailgun awesomness!"})
def send_simple_message
RestClient.post "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages",
:from => "Excited User <mailgun@YOUR_DOMAIN_NAME>",
:to => "bar@example.com, YOU@YOUR_DOMAIN_NAME",
:subject => "Hello",
:text => "Testing some Mailgun awesomness!"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class SendSimpleMessageChunk
{
public static void Main (string[] args)
{
Console.WriteLine (SendSimpleMessage ().Content.ToString ());
}
public static IRestResponse SendSimpleMessage ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/messages";
request.AddParameter ("from", "Excited User <mailgun@YOUR_DOMAIN_NAME>");
request.AddParameter ("to", "bar@example.com");
request.AddParameter ("to", "YOU@YOUR_DOMAIN_NAME");
request.AddParameter ("subject", "Hello");
request.AddParameter ("text", "Testing some Mailgun awesomness!");
request.Method = Method.POST;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func SendSimpleMessage(domain, apiKey string) (string, error) {
mg := mailgun.NewMailgun(domain, apiKey)
m := mg.NewMessage(
"Excited User <mailgun@YOUR_DOMAIN_NAME>",
"Hello",
"Testing some Mailgun awesomeness!",
"YOU@YOUR_DOMAIN_NAME",
)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
_, id, err := mg.Send(ctx, m)
return id, err
}
const API_KEY = 'YOUR_API_KEY';
const DOMAIN = 'YOUR_DOMAIN_NAME';
import formData from 'form-data';
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(formData);
const client = mailgun.client({username: 'api', key: API_KEY});
const messageData = {
from: 'Excited User <me@samples.mailgun.org>',
to: 'foo@example.com, bar@example.com',
subject: 'Hello',
text: 'Testing some Mailgun awesomeness!'
};
client.messages.create(DOMAIN, messageData)
.then((res) => {
console.log(res);
})
.catch((err) => {
console.error(err);
});
NOTE: If you’re sending from our EU infrastructure, be sure to substitute the beginning of the endpoint “https://api.mailgun.net” with “https://api.eu.mailgun.net”
What actually happened:
- Mailgun assembled a MIME message.
- Added the log entries to our full text search index.
- Delivered the email.
You can find your private API key on your dashboard.
Send via SMTP¶
Run this:
# Swaks is an smtp of CURL, install it first:
curl http://www.jetmore.org/john/code/swaks/files/swaks-20130209.0/swaks -o swaks
# Set the permissions for the script so you can run it
chmod +x swaks
# It's based on perl, so install perl
sudo apt-get -y install perl
# now send!
./swaks --auth \
--server smtp.mailgun.org \
--au postmaster@YOUR_DOMAIN_NAME \
--ap 3kh9umujora5 \
--to bar@example.com \
--h-Subject: "Hello" \
--body 'Testing some Mailgun awesomness!'
import java.io.*;
import java.net.InetAddress;
import java.util.Properties;
import java.util.Date;
import javax.mail.*;
import javax.mail.internet.*;
import com.sun.mail.smtp.*;
public class MGSendSimpleSMTP {
public static void main(String args[]) throws Exception {
Properties props = System.getProperties();
props.put("mail.smtps.host", "smtp.mailgun.org");
props.put("mail.smtps.auth", "true");
Session session = Session.getInstance(props, null);
Message msg = new MimeMessage(session);
msg.setFrom(new InternetAddress("YOU@YOUR_DOMAIN_NAME"));
InternetAddress[] addrs = InternetAddress.parse("bar@example.com", false));
msg.setRecipients(Message.RecipientType.TO, addrs)
msg.setSubject("Hello");
msg.setText("Testing some Mailgun awesomness");
msg.setSentDate(new Date());
SMTPTransport t =
(SMTPTransport) session.getTransport("smtps");
t.connect("smtp.mailgun.org", "postmaster@YOUR_DOMAIN_NAME", "YOUR_SMTP_PASSWORD");
t.sendMessage(msg, msg.getAllRecipients());
System.out.println("Response: " + t.getLastServerResponse());
t.close();
}
}
// Using Awesome https://github.com/PHPMailer/PHPMailer
<?php
require 'PHPMailerAutoload.php';
$mail = new PHPMailer;
$mail->isSMTP(); // Set mailer to use SMTP
$mail->Host = 'smtp.mailgun.org'; // Specify main and backup SMTP servers
$mail->SMTPAuth = true; // Enable SMTP authentication
$mail->Username = 'postmaster@YOUR_DOMAIN_NAME'; // SMTP username
$mail->Password = 'secret'; // SMTP password
$mail->SMTPSecure = 'tls'; // Enable encryption, only 'tls' is accepted
$mail->From = 'YOU@YOUR_DOMAIN_NAME';
$mail->FromName = 'Mailer';
$mail->addAddress('bar@example.com'); // Add a recipient
$mail->WordWrap = 50; // Set word wrap to 50 characters
$mail->Subject = 'Hello';
$mail->Body = 'Testing some Mailgun awesomness';
if(!$mail->send()) {
echo 'Message could not be sent.';
echo 'Mailer Error: ' . $mail->ErrorInfo;
} else {
echo 'Message has been sent';
}
import smtplib
from email.mime.text import MIMEText
msg = MIMEText('Testing some Mailgun awesomness')
msg['Subject'] = "Hello"
msg['From'] = "foo@YOUR_DOMAIN_NAME"
msg['To'] = "bar@example.com"
s = smtplib.SMTP('smtp.mailgun.org', 587)
s.login('postmaster@YOUR_DOMAIN_NAME', '3kh9umujora5')
s.sendmail(msg['From'], msg['To'], msg.as_string())
s.quit()
# install `mail` gem first: `gem install mail`
require 'mail'
Mail.defaults do
delivery_method :smtp, {
:port => 587,
:address => "smtp.mailgun.org",
:user_name => "",
:password => "",
}
end
mail = Mail.deliver do
to 'bar@example.com'
from 'foo@YOUR_DOMAIN_NAME'
subject 'Hello'
text_part do
body 'Testing some Mailgun awesomness'
end
end
using System;
using System.IO;
using MailKit;
using MailKit.Net.Smtp;
using MimeKit;
using RestSharp;
using RestSharp.Authenticators;
public class SmtpMessageChunk
{
public static void Main (string[] args)
{
SendMessageSmtp ();
}
public static void SendMessageSmtp ()
{
// Compose a message
MimeMessage mail = new MimeMessage ();
mail.From.Add (new MailboxAddress ("Excited Admin", "foo@YOUR_DOMAIN_NAME"));
mail.To.Add (new MailboxAddress ("Excited User", "bar@example.com"));
mail.Subject = "Hello";
mail.Body = new TextPart ("plain") {
Text = @"Testing some Mailgun awesomesauce!",
};
// Send it!
using (var client = new SmtpClient ()) {
// XXX - Should this be a little different?
client.ServerCertificateValidationCallback = (s, c, h, e) => true;
client.Connect ("smtp.mailgun.org", 587, false);
client.AuthenticationMechanisms.Remove ("XOAUTH2");
client.Authenticate ("postmaster@YOUR_DOMAIN_NAME", "3kh9umujora5");
client.Send (mail);
client.Disconnect (true);
}
}
}
import (
"github.com/jordan-wright/email"
)
func main() {
e := email.NewEmail()
e.From = "Your Name <foo@YOUR_DOMAIN_NAME>"
e.To = []string{"bar@example.com"}
e.Subject = "Hello"
e.Text = []byte("Testing some Mailgun awesomeness")
err := e.Send("smtp.mailgun.org:587", smtp.PlainAuth("", "YOUR_USERNAME", "YOUR_PASSWORD", "smtp.mailgun.org"))
if err != nil {
panic(err)
}
}
// Using Nodemailer https://nodemailer.com/
import nodemailer from 'nodemailer';
async function main() {
// create reusable transporter object using the default SMTP transport
let transporter = nodemailer.createTransport({
host: "smtp.mailgun.org",
port: 587,
auth: {
user: "postmaster@YOUR_DOMAIN_NAME",
pass: "YOUR_SMTP_PASSWORD",
},
});
// send mail with defined transport object
let info = await transporter.sendMail({
from: 'foo@YOUR_DOMAIN_NAME',
to: "bar@example.com",
subject: "Hello",
text: "Testing some Mailgun awesomness"
});
console.log("Message sent: %s", info.messageId);
}
main().catch(console.error);
You can find your SMTP credentials for each domain on your domains tab.
Verify Your Domain¶
Add a domain you own and verify it by setting up the DNS records we provide (known as SPF and DKIM) at your DNS provider.
Why you need to verify your domain:
- To prove that you are an authorized sender for the domain.
- Verified domains are not subject to a sending limit of 300 emails per day.
- No more “sent via Mailgun.org” message in your emails.
- Establishing a positive email reputation for your own domain.
- Mailgun is less suspicious of traffic that is being sent on verified domains and so using one reduces the likelihood of being disabled.
How to verify your domain¶
- Add your domain or subdomain.
- Open your DNS provider and add the two TXT DNS records provided.
- If you want Mailgun to track clicks and opens you can also add the CNAME record.
- MX records should also be added, unless you already have MX records for your domain pointed at another email service provider (e.g. Gmail).
Once you’ve added the records and they’ve propagated, your domain will be verified.
Note
It can take 24-48 hours for DNS changes to propagate.
If you will be creating a lot of domains, Mailgun offers an API endpoint for adding/editing/removing domains from your account. See the Domains endpoint for more information.
Add Sending & Tracking DNS Records¶
- SPF: Sending server IP validation. Used by majority of inbound mail servers. SPF Information.
- DKIM: Like SPF, but uses cryptographic methods for validation. Supported by many inbound mail servers. DKIM Information
- CNAME: Used for tracking opens and clicks, when enabled. Tracking Messages
Type | Value | Purpose |
---|---|---|
TXT | “v=spf1 include:mailgun.org ~all” | SPF (Required) |
TXT | Find this record in your Control Panel, Domains Tab | DKIM (Required) |
CNAME | “mailgun.org” | Tracking (Optional) |
Note
While the CNAME is listed as optional, it is required to enable Unsubscribe and Click tracking links.
Add Receiving MX Records¶
Mail server for handling inbound messages. MX Information
Type | Value | Purpose |
---|---|---|
MX | mxa.mailgun.org | Receiving (Optional) |
MX | mxb.mailgun.org | Receiving (Optional) |
Warning
Do not configure Receiving MX DNS records if you already have another provider handling inbound mail delivery (e.g. Gmail).
Common DNS Providers¶
Common providers are listed below. If yours is not listed, contact your DNS provider for assistance.
NameCheap: All Records
Network Solutions: MX - CNAME - TXT
Rackspace Email & Apps: All Records
Rackspace Cloud DNS: Developer Guide
Amazon Route 53: Developer Guide
DigitalOcean: Mailgun and DigitalOcean Guide
You are all set!
Read more about How to start receiving inbound email and How to start tracking email events.