Messages

Sending

There are two ways to send emails using Mailgun API:

  • You can pass the components of the messages such as To, From, Subject, HTML and text parts, attachments, etc. Mailgun will build a MIME representation of the message and send it. This is the preferred method.
  • You can also build a MIME string yourself using a MIME library for your programming language and submit it to Mailgun.

Note

You can also use good old SMTP to send messages. But you will have to specify all advanced sending options via MIME headers

POST /<domain>/messages

Sends a message by assembling it from the components. Note that you can specify most parameters multiple times, HTTP supports this out of the box. This makes sense for parameters like cc, to or attachment.

Parameter Description
from Email address for From header
to Email address of the recipient(s). Example: "Bob <bob@host.com>". You can use commas to separate multiple recipients.
cc Same as To but for Cc
bcc Same as To but for Bcc
subject Message subject
text Body of the message. (text version)
html Body of the message. (HTML version)
attachment File attachment. You can post multiple attachment values. Important: You must use multipart/form-data encoding when sending attachments.
inline Attachment with inline disposition. Can be used to send inline images (see example). You can post multiple inline values.
o:tag Tag string. See Tagging for more information.
o:campaign Id of the campaign the message belongs to. See Campaign Analytics for details.
o:dkim Enables/disables DKIM signatures on per-message basis. Pass yes or no
o:deliverytime Desired time of delivery. See Date Format. Note: Messages can be scheduled for a maximum of 3 days in the future.
o:testmode Enables sending in test mode. Pass yes if needed. See Sending in Test Mode
o:tracking Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no.
o:tracking-clicks Toggles clicks tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes, no or htmlonly.
o:tracking-opens Toggles opens tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes or no.
h:X-My-Header h: prefix followed by an arbitrary value allows to append a custom MIME header to the message (X-My-Header in this case). For example, h:Reply-To to specify Reply-To address.
v:my-var v: prefix followed by an arbitrary name allows to attach a custom JSON data to the message. See Attaching Data to Messages for more information.
POST /<domain>/messages.mime

Posts a message in MIME format. Note: you will need to build a MIME string yourself. Use a MIME library for your programming language to do this. Pass the resulting MIME string as message parameter.

Note

You must use multipart/form-data encoding.

Parameter Description
to Email address of the recipient(s). Example: "Bob <bob@host.com>". You can use commas to separate multiple recipients. Make sure to include all To, Cc and Bcc recipients of the message.
message MIME string of the message. Make sure to use multipart/form-data to send this as a file upload.
o:tag Tag string. See Tagging for more information.
o:campaign Id of the campaign the message belongs to. See Campaign Analytics for details.
o:deliverytime Desired time of delivery. See Date Format. Note: Messages can be scheduled for a maximum of 3 days in the future.
o:dkim Enables/disabled DKIM signatures on per-message basis. Pass yes or no
o:testmode Enables sending in test mode. Pass yes if needed. See Sending in Test Mode
o:tracking Toggles tracking on a per-message basis, see Tracking Messages for details. Pass yes or no.
o:tracking-clicks Toggles clicks tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes, no or htmlonly.
o:tracking-opens Toggles opens tracking on a per-message basis. Has higher priority than domain-level setting. Pass yes or no.
h:X-My-Header h: prefix followed by an arbitrary value allows to append a custom MIME header to the message (X-My-Header in this case). For example, h:Reply-To to specify Reply-To address.
v:my-var v: prefix followed by an arbitrary name allows to attach a custom JSON data to the message. See Attaching Data to Messages for more information.

Retrieving Stored Messages

To retrieve an inbound message that has been stored via the store() action, use the URL found in the stored event (which you can find through the Events API, or in the notify webhook set when creating the store action (store(notify="http:mydomain.com/callback")).

  • By default the message will be returned in JSON form with parsed parts. Links to the attachments will be included.
  • You can also retrieve the full raw mime message (attachments and all) if you make the request to the URL with the Accept header set to message/rfc2822.
GET domains/<domain>/messages

You don’t have to construct this URL on your own. You can just use the URL provided in the Events API or the notification webhook. A sample URL returned from the Events API is https://api.mailgun.net/v2/domains/mydomain.com/messages/WyJhOTM4NDk1ODA3Iiw.

These are the parameters of the JSON returned from a GET request to a stored message url.

Parameter Type Description
recipients string recipient of the message as reported by MAIL TO during SMTP chat.
sender string sender of the message as reported by MAIL FROM during SMTP chat. Note: this value may differ from From MIME header.
from string sender of the message as reported by From message header, for example “Bob Lee <blee@mailgun.net>”.
subject string subject string.
body-plain string text version of the email. This field is always present. If the incoming message only has HTML body, Mailgun will create a text representation for you.
stripped-text string text version of the message without quoted parts and signature block (if found).
stripped-signature string the signature block stripped from the plain text message (if found).
body-html string HTML version of the message, if message was multipart. Note that all parts of the message will be posted, not just text/html. For instance if a message arrives with “foo” part it will be posted as “body-foo”.
stripped-html string HTML version of the message, without quoted parts.
attachments string contains a json list of metadata objects, one for each attachment, see below.
message-url string a URL that you can use to get and/or delete the message.
content-id-map string contains mappings from content ids to attachment urls.
message-headers string list of all MIME headers dumped to a json string (order of headers preserved).
content-id-map string JSON-encoded dictionary which maps Content-ID (CID) of each attachment to the corresponding attachment-x parameter. This allows you to map posted attachments to tags like <img src='cid'> in the message body.

Note

Do not rely on the body-plain, stripped-text, and stripped-signature fields for HTML sanitization. These fields merely provide content from the text/plain portion of an incoming message. This content may contain unescaped HTML.

The attachments JSON contains the following items.

Parameter Type Description
size integer indicates the size of the attachment in bytes.
url string contains the url where the attachment can be found. This does not support DELETE.
name string the name of the attachment
content-type string the content type of the attachment

These are the parameters when the Accept header is set to message/rfc2822

Parameter Type Description
recipient string recipient of the message.
sender string sender of the message as reported by SMTP MAIL FROM.
from string sender of the message as reported by From message header, for example “Bob <bob@example.com>”.
subject string subject string.
body-mime string full MIME envelope. You will need a MIME parsing library to process this data.

Deleting Stored Messages

To delete an inbound message that has been stored via the store() action, use the URL found in the stored event, or in the notify webhook.

DELETE domains/<domain>/messages/<message>

You don’t have to construct this URL on your own. You can just use the URL provided in the Events API or the notification webhook. A sample URL returned from the Events API is https://api.mailgun.net/v2/domains/mydomain.com/messages/WyJhOTM4NDk1ODA3Iiw.

Examples

Warning

Some samples are using curl utility for API examples. UNIX shells require that some characters must be escaped, for example $ becomes \$.

If your API key contains unescaped characters you may receive HTTP error 401 (Unauthorized).

Sending a plain text message:

curl -s --user 'api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0' \
    https://api.mailgun.net/v2/samples.mailgun.org/messages \
    -F from='Excited User <me@samples.mailgun.org>' \
    -F to=baz@example.com \
    -F to=bar@example.com \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!'
public static ClientResponse SendSimpleMessage() {
       Client client = Client.create();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org" +
                               "/messages");
       MultivaluedMapImpl formData = new MultivaluedMapImpl();
       formData.add("from", "Excited User <me@samples.mailgun.org>");
       formData.add("to", "bar@example.com");
       formData.add("to", "baz@example.com");
       formData.add("subject", "Hello");
       formData.add("text", "Testing some Mailgun awesomness!");
       return webResource.type(MediaType.APPLICATION_FORM_URLENCODED).
               post(ClientResponse.class, formData);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = "samples.mailgun.org";

# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
    'from'    => 'Excited User <me@samples.mailgun.org>',
    'to'      => 'Baz <baz@example.com>',
    'subject' => 'Hello',
    'text'    => 'Testing some Mailgun awesomness!'
));
def send_simple_message():
    return requests.post(
        "https://api.mailgun.net/v2/samples.mailgun.org/messages",
        auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
        data={"from": "Excited User <me@samples.mailgun.org>",
              "to": ["bar@example.com", "baz@example.com"],
              "subject": "Hello",
              "text": "Testing some Mailgun awesomness!"})
def send_simple_message
  RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/messages",
  :from => "Excited User <me@samples.mailgun.org>",
  :to => "bar@example.com, baz@example.com",
  :subject => "Hello",
  :text => "Testing some Mailgun awesomness!"
end
public static IRestResponse SendSimpleMessage() {
       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/messages";
       request.AddParameter("from", "Excited User <me@samples.mailgun.org>");
       request.AddParameter("to", "bar@example.com");
       request.AddParameter("to", "baz@example.com");
       request.AddParameter("subject", "Hello");
       request.AddParameter("text", "Testing some Mailgun awesomness!");
       request.Method = Method.POST;
       return client.Execute(request);
}
func SendSimpleMessage(domain, apiKey string) (string, error) {
  mg := mailgun.NewMailgun(domain, apiKey, publicApiKey)
  m := mg.NewMessage(
    "Excited User <me@samples.mailgun.org>",
    "Hello",
    "Testing some Mailgun awesomeness!",
    "bar@example.com",
  )
  _, id, err := mg.Send(m)
  return id, err
}

Sample response:

{
  "message": "Queued. Thank you.",
  "id": "<20111114174239.25659.5817@samples.mailgun.org>"
}

Sending a message with HTML and text parts. This example also attaches two files to the message:

curl -s --user 'api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0' \
    https://api.mailgun.net/v2/samples.mailgun.org/messages \
    -F from='Excited User <me@samples.mailgun.org>' \
    -F to='foo@example.com' \
    -F cc='bar@example.com' \
    -F bcc='baz@example.com' \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!' \
    --form-string html='<html>HTML version of the body</html>' \
    -F attachment=@files/cartman.jpg \
    -F attachment=@files/cartman.png
public static ClientResponse SendComplexMessage() {
       Client client = Client.create();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org/" +
                               "messages");
       FormDataMultiPart form = new FormDataMultiPart();
       form.field("from", "Excited User <me@samples.mailgun.org>");
       form.field("to", "foo@example.com");
       form.field("bcc", "bar@example.com");
       form.field("cc", "baz@example.com");
       form.field("subject", "Hello");
       form.field("text", "Testing some Mailgun awesomness!");
       String file_separator = System.getProperty("file.separator");
       File txtFile = new File("." + file_separator +
                       "files" + file_separator + "test.txt");
       form.bodyPart(new FileDataBodyPart("attachment",txtFile,
                       MediaType.TEXT_PLAIN_TYPE));
       File jpgFile = new File("." + file_separator +
                       "files" + file_separator + "test.jpg");
       form.bodyPart(new FileDataBodyPart("attachment",jpgFile,
                       MediaType.APPLICATION_OCTET_STREAM_TYPE));
       return webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE).
               post(ClientResponse.class, form);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = "samples.mailgun.org";

# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
    'from'    => 'Excited User <me@samples.mailgun.org>',
    'to'      => 'foo@example.com',
    'cc'      => 'baz@example.com',
    'bcc'     => 'bar@example.com',
    'subject' => 'Hello',
    'text'    => 'Testing some Mailgun awesomness!',
    'html'    => '<html>HTML version of the body</html>'
), array(
    'attachment' => array('@/path/to/file.txt', '@/path/to/file.txt')
));
def send_complex_message():
    return requests.post(
        "https://api.mailgun.net/v2/samples.mailgun.org/messages",
        auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
        files=[("attachment", open("files/test.jpg")),
               ("attachment", open("files/test.txt"))],
        data={"from": "Excited User <me@samples.mailgun.org>",
              "to": "foo@example.com",
              "cc": "baz@example.com",
              "bcc": "bar@example.com",
              "subject": "Hello",
              "text": "Testing some Mailgun awesomness!",
              "html": "<html>HTML version of the body</html>"})
def send_complex_message
  data = Multimap.new
  data[:from] = "Excited User <me@samples.mailgun.org>"
  data[:to] = "foo@example.com"
  data[:cc] = "baz@example.com"
  data[:bcc] = "bar@example.com"
  data[:subject] = "Hello"
  data[:text] = "Testing some Mailgun awesomness!"
  data[:html] = "<html>HTML version of the body</html>"
  data[:attachment] = File.new(File.join("files", "test.jpg"))
  data[:attachment] = File.new(File.join("files", "test.txt"))
  RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/messages", data
end
public static IRestResponse SendComplexMessage() {
       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/messages";
       request.AddParameter("from", "Excited User <me@samples.mailgun.org>");
       request.AddParameter("to", "foo@example.com");
       request.AddParameter("cc", "baz@example.com");
       request.AddParameter("bcc", "bar@example.com");
       request.AddParameter("subject", "Hello");
       request.AddParameter("text", "Testing some Mailgun awesomness!");
       request.AddParameter("html", "<html>HTML version of the body</html>");
       request.AddFile("attachment", Path.Combine("files", "test.jpg"));
       request.AddFile("attachment", Path.Combine("files","test.txt"));
       request.Method = Method.POST;
       return client.Execute(request);
}
func SendComplexMessage(domain, apiKey string) (string, error) {
  mg := mailgun.NewMailgun(domain, apiKey, "")
  m := mg.NewMessage(
    "Excited User <me@samples.mailgun.org>",
    "Hello",
    "Testing some Mailgun awesomeness!",
    "foo@example.com",
  )
  m.AddCC("baz@example.com")
  m.AddBCC("bar@example.com")
  m.SetHtml("<html>HTML version of the body</html>")
  m.AddAttachment("files/test.jpg")
  m.AddAttachment("files/test.txt")
  _, id, err := mg.Send(m)
  return id, err
}

Sending a MIME message which you pre-build yourself using a MIME library of your choice:

curl -s --user 'api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0' \
    https://api.mailgun.net/v2/samples.mailgun.org/messages.mime \
    -F to='bob@example.com' \
    -F message=@files/message.mime
public static ClientResponse SendMimeMessage() {
       Client client = Client.create();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org" +
                               "/messages.mime");
       FormDataMultiPart form = new FormDataMultiPart();
       form.field("to", "bar@example.com");
       String file_separator = System.getProperty("file.separator");
       File mimeFile = new File("." + file_separator + "files" +
                       file_separator + "message.mime");
       form.bodyPart(new FileDataBodyPart("message", mimeFile,
                       MediaType.APPLICATION_OCTET_STREAM_TYPE));
       return webResource.type(MediaType.MULTIPART_FORM_DATA_TYPE).
               post(ClientResponse.class, form);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = "samples.mailgun.org";

# Make the call to the client.
$result = $mgClient->sendMessage(
    $domain, array(
        'from' => 'Excited User <me@samples.mailgun.org>',
        'to'   => 'foo@example.com'
    ),
    '<Pass fully formed MIME string here>'
);
def send_mime_message():
    return requests.post(
        "https://api.mailgun.net/v2/samples.mailgun.org/messages.mime",
        auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
        data={"to": "bar@example.com"},
        files={"message": open("files/message.mime")})
def send_mime_message
  RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/messages.mime",
  :to => "bar@example.com",
  :message => File.new(File.join("files", "message.mime"))
end
public static IRestResponse SendMimeMessage() {
       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/messages.mime";
       request.AddParameter("to", "bar@example.com");
       request.AddFile("message", Path.Combine("files", "message.mime"));
       request.Method = Method.POST;
       return client.Execute(request);
}
func SendMimeMessage(domain, apiKey string) (string, error) {
  mg := mailgun.NewMailgun(domain, apiKey, "")
  mimeMsgReader, err := os.Open("files/message.mime")
  if err != nil {
    return "", err
  }
  m := mg.NewMIMEMessage(mimeMsgReader, "bar@example.com")
  _, id, err := mg.Send(m)
  return id, err
}

An example of how to toggle tracking on a per-message basis. Note the o:tracking option. This will disable link rewriting for this message:

curl -s --user 'api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0' \
    https://api.mailgun.net/v2/samples.mailgun.org/messages \
    -F from='Sender Bob <sbob@samples.mailgun.org>' \
    -F to='alice@example.com' \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!' \
    -F o:tracking=False
public static ClientResponse SendMessageNoTracking() {
       Client client = new Client();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org" +
                               "/messages");
       MultivaluedMapImpl formData = new MultivaluedMapImpl();
       formData.add("from", "Excited User <me@samples.mailgun.org>");
       formData.add("to", "bar@example.com");
       formData.add("to", "baz@example.com");
       formData.add("subject", "Hello");
       formData.add("text", "Testing some Mailgun awesomness!");
       formData.add("o:tracking", false);
       return webResource.type(MediaType.APPLICATION_FORM_URLENCODED).
               post(ClientResponse.class, formData);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = "samples.mailgun.org";

# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
    'from'       => 'Excited User <me@samples.mailgun.org>',
    'to'         => 'foo@example.com',
    'subject'    => 'Hello',
    'text'       => 'Testing some Mailgun awesomness!',
    'o:tracking' => false
));
def send_message_no_tracking():
    return requests.post(
        "https://api.mailgun.net/v2/samples.mailgun.org/messages",
        auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
        data={"from": "Excited User <me@samples.mailgun.org>",
              "to": ["bar@example.com", "baz@example.com"],
              "subject": "Hello",
              "text": "Testing some Mailgun awesomness!",
              "o:tracking": False})
def send_message_no_tracking
  RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/messages",
  :from => "Excited User <me@samples.mailgun.org>",
  :to => "bar@example.com, baz@example.com",
  :subject => "Hello",
  :text => "Testing some Mailgun awesomness!",
  "o:tracking" => false
end
public static IRestResponse SendMessageNoTracking() {
       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/messages";
       request.AddParameter("from", "Excited User <me@samples.mailgun.org>");
       request.AddParameter("to", "bar@example.com");
       request.AddParameter("to", "baz@example.com");
       request.AddParameter("subject", "Hello");
       request.AddParameter("text", "Testing some Mailgun awesomness!");
       request.AddParameter("o:tracking", false);
       request.Method = Method.POST;
       return client.Execute(request);
}
func SendMessageNoTracking(domain, apiKey string) (string, error) {
  mg := mailgun.NewMailgun(domain, apiKey, "")
  m := mg.NewMessage(
    "Excited User <me@samples.mailgun.org>",
    "Hello",
    "Testing some Mailgun awesomeness!",
    "foo@example.com",
  )
  m.SetTracking(false)
  _, id, err := mg.Send(m)
  return id, err
}

An example of how to set message delivery time using the o:deliverytime option:

curl -s --user 'api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0' \
    https://api.mailgun.net/v2/samples.mailgun.org/messages \
    -F from='Sender Bob <sbob@samples.mailgun.org>' \
    -F to='alice@example.com' \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!' \
    -F o:deliverytime='Fri, 14 Oct 2011 23:10:10 -0000'
public static ClientResponse SendScheduledMessage() {
       Client client = new Client();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org" +
                               "/messages");
       MultivaluedMapImpl formData = new MultivaluedMapImpl();
       formData.add("from", "Excited User <me@samples.mailgun.org>");
       formData.add("to", "bar@example.com");
       formData.add("subject", "Hello");
       formData.add("text", "Testing some Mailgun awesomness!");
       formData.add("o:deliverytime", "Fri, 14 Oct 2011 23:10:10 -0000");
       return webResource.type(MediaType.APPLICATION_FORM_URLENCODED).
               post(ClientResponse.class, formData);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = "samples.mailgun.org";

# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
    'from'           => 'Excited User <me@samples.mailgun.org>',
    'to'             => 'Baz <baz@example.com>',
    'subject'        => 'Hello',
    'text'           => 'Testing some Mailgun awesomness!',
    'o:deliverytime' => 'Fri, 25 Oct 2013 23:10:10 -0000'
));
def send_scheduled_message():
    return requests.post(
        "https://api.mailgun.net/v2/samples.mailgun.org/messages",
        auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
        data={"from": "Excited User <me@samples.mailgun.org>",
              "to": "bar@example.com",
              "subject": "Hello",
              "text": "Testing some Mailgun awesomness!",
              "o:deliverytime": "Fri, 25 Oct 2011 23:10:10 -0000"})
def send_scheduled_message
  RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/messages",
  :from => "Excited User <me@samples.mailgun.org>",
  :to => "bar@example.com",
  :subject => "Hello",
  :text => "Testing some Mailgun awesomeness!",
  "o:deliverytime" => "Fri, 25 Oct 2011 23:10:10 -0000"
end
public static IRestResponse SendScheduledMessage() {
       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/messages";
       request.AddParameter("from", "Excited User <me@samples.mailgun.org>");
       request.AddParameter("to", "bar@example.com");
       request.AddParameter("subject", "Hello");
       request.AddParameter("text", "Testing some Mailgun awesomness!");
       request.AddParameter("o:deliverytime", "Fri, 14 Oct 2011 23:10:10 -0000");
       request.Method = Method.POST;
       return client.Execute(request);
}
func SendScheduledMessage(domain, apiKey string) (string, error) {
  mg := mailgun.NewMailgun(domain, apiKey, publicApiKey)
  m := mg.NewMessage(
    "Excited User <me@samples.mailgun.org>",
    "Hello",
    "Testing some Mailgun awesomeness!",
    "bar@example.com",
  )
  m.SetDeliveryTime(time.Now().Add(5 * time.Minute))
  _, id, err := mg.Send(m)
  return id, err
}

An example of how to tag a message with the o:tag option:

curl -s --user 'api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0' \
    https://api.mailgun.net/v2/samples.mailgun.org/messages \
    -F from='Sender Bob <sbob@samples.mailgun.org>' \
    -F to='alice@example.com' \
    -F subject='Hello' \
    -F text='Testing some Mailgun awesomness!' \
    -F o:tag='September newsletter' \
    -F o:tag='newsletters'
public static ClientResponse SendTaggedMessage() {
       Client client = new Client();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org" +
                               "/messages");
       MultivaluedMapImpl formData = new MultivaluedMapImpl();
       formData.add("from", "Excited User <me@samples.mailgun.org>");
       formData.add("to", "bar@example.com");
       formData.add("subject", "Hello");
       formData.add("text", "Testing some Mailgun awesomness!");
       formData.add("o:tag", "September newsletter");
       formData.add("o:tag", "newsletters");
       return webResource.type(MediaType.APPLICATION_FORM_URLENCODED).
               post(ClientResponse.class, formData);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;

# Instantiate the client.
$mgClient = new Mailgun('key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
$domain = "samples.mailgun.org";

# Make the call to the client.
$result = $mgClient->sendMessage($domain, array(
    'from'    => 'Excited User <me@samples.mailgun.org>',
    'to'      => 'Baz <baz@example.com>',
    'subject' => 'Hello',
    'text'    => 'Testing some Mailgun awesomness!',
    'o:tag'   => array('Tag1', 'Tag2')
));
def send_tagged_message():
    return requests.post(
        "https://api.mailgun.net/v2/samples.mailgun.org/messages",
        auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
        data={"from": "Excited User <me@samples.mailgun.org>",
              "to": "bar@example.com",
              "subject": "Hello",
              "text": "Testing some Mailgun awesomness!",
              "o:tag": ["September newsletter", "newsletters"]})
def send_tagged_message
  data = Multimap.new
  data[:from] = "Excited User <me@samples.mailgun.org>"
  data[:to] = "bar@example.com"
  data[:subject] = "Hello"
  data[:text] = "Testing some Mailgun awesomness!"
  data["o:tag"] = "September newsletter"
  data["o:tag"] = "newsletters"
  RestClient.post "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/messages", data
end
public static IRestResponse SendTaggedMessage() {
       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/messages";
       request.AddParameter("from", "Excited User <me@samples.mailgun.org>");
       request.AddParameter("to", "bar@example.com");
       request.AddParameter("subject", "Hello");
       request.AddParameter("text", "Testing some Mailgun awesomness!");
       request.AddParameter("o:tag", "September newsletter");
       request.AddParameter("o:tag", "newsletters");
       request.Method = Method.POST;
       return client.Execute(request);
}
func SendTaggedMessage(domain, apiKey string) (string, error) {
  mg := mailgun.NewMailgun(domain, apiKey, "")
  m := mg.NewMessage(
    "Excited User <me@samples.mailgun.org>",
    "Hello",
    "Testing some Mailgun awesomeness!",
    "bar@example.com",
  )
  m.AddTag("FooTag")
  m.AddTag("BarTag")
  m.AddTag("BlortTag")
  _, id, err := mg.Send(m)
  return id, err
}