Sending Messages

How to Start Sending Messages

Send via HTTP

Send via SMTP

Send a Message with STO

Send a Message with TZO

Send Message with Attachments

Message Queue

Batch Sending

Mailing Lists

Templates

Scheduling Delivery

Test Mode

How to Start Sending Messages

Note:

Since Mailgun does not host mailboxes, our service does not use the POP or IMAP protocols.

There are two ways to send messages using Mailgun that work great to support the same feature set.

Choose the one you'd like to use based on your preferences and requirements.

verifydomain

Send via HTTP

When sending an email via our HTTP API, Mailgun offers two options:

  • You can send a pre-built MIME. This assumes you've built an RFC-compliant MIME in your choice of tooling
  • You can use our HTTP API to submit the individual parts (text, HTML, attachments, etc.) of your messages to Mailgun.
Note:

Some things to consider when sending API email with Mailgun:

  • The maximum message size Mailgun supports is 25MB
  • An error will be returned with "parameter is not a valid address" if the provided email address fails syntax checks in accordance with RFC5321, RFC5322, RFC6854

Please reference our API documentation to see all available options when sending emails! Here's a couple examples using cURL to get you familiar with interacting with the API:

Note:

If your domain exists in our EU region be sure to substitute “https://api.mailgun.net” with “https://api.eu.mailgun.net” in the examples below.

Sending Basic Text

Sending a simple text-based email using Mailgun's HTTP API requires a few parameters at minimum:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient-1@example.com \
    -F to=recipient-2@example.com \
    -F subject='Hello there!' \
    -F text='Testing some Mailgun awesomeness!'

What actually happened:

  • Mailgun assembled a valid MIME message based on your input parameters
  • Delivered the email to both recipients listed with the to parameters
  • Added log entries to our full text index that we Accepted the email, and if delivered successfully, added a Delivered event. (See the Events API for more details)

Send With Text and HTML Versions

By including both the 'text' and 'html' parameters, you can offer two different versions of your email to the user:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject="Hello there!" \
    -F text='This will be the text-only version' \
    --form-string html='<html><body><p>This is the HTML version</p></body></html>'
Note:

A common gotcha: note the use of --form-string in this example for the HTML part. Without this, your cURL command may fail to execute properly!

Enable Tracking on a Specific Message Only

While tracking can be enabled for all messages in your Dashboard, you can also selectively enable tracking on a per-message basis. To enable all tracking types you use the 'o:tracking="yes"' parameter. Otherwise, you can enable only specific tracking for opens ('o:tracking-opens') or clicks ('o:tracking-clicks'):

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject="Hello there!" \
    -F text='Testing some Mailgun awesomeness!' \
    -F o:tracking-opens="yes"

The 'o:deliverytime' option allows you to specify when an email should be sent. It uses RFC822 date formatting and can be no more than 3 days in the future:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject="Hello there!" \
    -F text='Testing some Mailgun awesomeness!' \
    -F o:deliverytime='Fri, 14 Oct 2011 23:10:10 -0000'
Note:

If your billing plan supports 7 or more days of storage capability, you can now schedule emails out up to 7 days.

Tagging Emails

Mailgun allows you to Tag emails for further analytics within our platform:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject="Hello there!" \
    -F text='Testing some Mailgun awesomeness!' \
    -F o:tag='September newsletter' \
    -F o:tag='newsletters'

See Tags for more information!

Re-Delivering a Previously-Sent Email

By default: emails sent through our APIs are stored for 72 hours. If you navigate to your Dashboard, check the Logs page and find a message sent within this time frame that you wish to resend, you should have a 'storage.url' field. Using that exact URL in your POST request, along with one or more 'to' parameters, you can deliver that MIME to the provided recipients:

Copy
Copied
    curl -s --user 'api:YOUR_API_KEY' {{STORAGE.URL}} \
        -F to='bob@example.com, john@example.com'

Send via SMTP

First you'll need to grab your SMTP credentials (user and password).

SMTP credentials are set and managed on a per-domain basis. You can view and modify them via our HTTP API or UI. To access them in our UI, navigate on the sidebar to Sending -> Domain Settings, select your domain from the dropdown, then select the SMTP Credentials tab.

To send an email via SMTP you can utilize Swaks via your command line.

Copy
Copied
# Swaks is the cURL equivalent for SMTP, 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 YOUR-SMTP-USER \
       --ap YOUR-SMTP-PASSWORD \
       --to recipient@example.com \
       --h-Subject: "Hello" \
       --body 'Testing some Mailgun awesomness!'

Mailgun SMTP servers listen on ports 25, 465, 587, and 2525. Port 465 requires a TLS connection. Ports 25, 587, and 2525 require a non-TLS connection but may be upgraded to TLS using the STARTTLS command. We offer many different ports due to some ISPs blocking / throttling certain SMTP ports.

Learn more about ports by reading our article, WHich SMTP Port Should I Use? Undertsanding Ports 25, 465,& 587.

Port Requirements
25 Requires a non-TLS connection but may be upgraded to TLS using the STARTTLS command.
465 Requires a TLS connection
587 Requires a non-TLS connection but may be upgraded to TLS using the STARTTLS command.
2525 Requires a non-TLS connection but may be upgraded to TLS using the STARTTLS command.
Note:
  • Some ISPs are blocking or throttling SMTP port 25. Using port 587 is recommended.
  • Google Compute Engine allows port 2525 for SMTP submission.
  • SMTP send will error with "Cannot parse to address" or "cannot parse from address" if the provided email address fails syntax checks in accordance with RFC5321, RFC5322, RFC6854
Warning!

IP addresses for HTTP and SMTP API endpoints will change frequently and be subjected to change without notice. Be sure there are no IP-based ACLs that would prevent communication to new IP addresses that may be added or removed at any time. .

Passing Sending Options

When sending a message via SMTP, you can pass additional sending options via custom MIME headers listed in the table below:

Header Description
X-Mailgun-Template-Name Template name for the template to be rendered.
X-Mailgun-Template-Version Template version of the template name to be used.
X-Mailgun-Template-Template_variables Template specific variables to be used when rendering a template. Note: These variables will be preferred over X-Mailgun-Variables, e.g. user variables
X-Mailgun-Tag The Tag string is used for aggregating stats. You can make a message with several categories by setting multiple X-Mailgun-Tag headers.
X-Mailgun-Dkim Enables/disables DKIM signatures on a per-message basis. Use yes or no
X-Mailgun-Deliver-By Use this to indicate the desired time of delivery.
X-Mailgun-Drop-Message Enables sending in test mode. Nte: Sending in Test Mode will not actually deliver an email but will emit a delivered event with a 650 status code Pass, yes, or no if needed.
X-Mailgun-Track Toggles tracking on a per-message basis. Pass, yes or no.
X-Mailgun-Track-Clicks Toggles clicks tracking on a per-message basis. It has a higher priority than the domain-level setting. Pass, yes, no, or htmlonly
X-Mailgun-Track-Opens Toggles opens tracking on a per-message basis. It has a higher priority than the domain-level setting. Pass, yes or no
X-Mailgun-Sending-Ip Used to specify an IP Address to send an email that is owned by your account
X-Mailgun-Sending-Ip-Pool If an IP Pool ID is provided, the email will be delivered with an IP that belongs in that pool
X-Mailgun-Require-TLS Use this header to control TLS connection settings. If set, Mailgun will only deliver the message over a secure TLS connection with the ESP. If TLS is not available, the delivery will fail
X-Mailgun-Skip-Verification Use this header to control TLS (Transport Layer Security) connection settings.
X-Mailgun-Secondary-DKIM Specify a second domain key to sign the email with. the value is formatted as signing_domain/selector, e.g. example.com/s1. This tells Mailgun to also sign the message with the signing domaing example.com uaing the selector s1. Note: the domain key specified must have been created and is active.
X-Mailgun-Secondary-DKIM-Public This header specified an alias of the domain key specified in X-Mailgun-SEcondary-DKIM. Also formatted as public_signing_domain/selector. The X-Mailgun-Secondary-DKIM header must also be provided if this header is used. Mailgun will sign the message with the provate key of the secondary DKIM, but use the public secondary SKIM name and selector. Note: We will perform a DNS check prior to singing the message to ensure the public keye matches the secondiary DKIM.
X-Mailgun-Recipient-Variables Use this header to provide a JSON dictionary of variables to substitute for Batch messages.
X-Mailgun-Variables Use this header to attach custom JSON data to the message.
X-Mailgun-Delivery-Time-Optimize-Period Toggles STO on a per-message basis. The string should be set to the number of hours in [0-9]+h format.
X-Mailgun-Time-Zone-Localize Toggles TZO on a per-message basis. The string should be set to the preferred delivery time in HH:mm or hh:mmaa format, where HH:mm is used for a 24-hour format without AM/PM, and hh:mmaa is used for 12-hour format with AM/PM.
Tip:

Yes, you can customize your SMTP Credentials. Go to the article, Can I Customize My SMTP Credentials? for more information.

Sending a Message with STO

Mailgun's Send Time Optimization (STO) feature uses machine learning to analyze engagement data (opens and clicks) for a recipient to determine when a user is most engaged with their messages. If there is enough engagement data to determine when the user is most engaged, Mailgun will hold onto the message and deliver it during that optimal period. The idea is to deliver the message to the recipient at a time when they are most likely to be engaged with their messages.

Sending an STO message via API and SMTP

  • Send a message via API by passing the parameter: o:deliverytime-optimize-period
  • Send an SMTP message using the MIME header: X-Mailgun-Delivery-Time-Optimize-Period
    • The value should be a string in the [0-9] +h format. This format defines the window in which Mailgun will run optimization algorithm against the data that has been delivered to the message.
    • Using a minimum value of 24h for best results, and the max value is 72h is highly recommended.
    Note:

    For more information on STO, see the article, What is Send Time Optimization?. Also, check out the Send Time Optimization FAQ

Sending a Message with TZO

Time Zone Optimization (TZO) allows senders to schedule messages to be delivered in a recipient's local time zone. TZO is like message scheduling, however, the focus is on passing the message on to the desired delivery time based on the recipient's local time zone.

Note:

Mailgun will convert the message to use the recipient's local time zone, when there is data present for the recipient. If Mailgun does not have data for that recipient, the message will be delivered immediately.

  • Time zones are based on a recipient's IP address
    • Mailgun collects IP addresses on click events and uses a geo-location service to translate the IP address into a time zone for the user.
    • The time zone is hashed and stored in a database, which Mailgun will look up for that user when a TZO message is sent.

Sending TZO message via API and SMTP

  • Send a message via API by passing the parameter: o:time-zone-localize
  • Send a message via SMTP using a MIME header: X-Mailgun-Time-Zone-Localize
    • The value (String) should be set to the preferred delivery time in HH:mm or hh:mmaa format, where HH:mm is used for 24 hours format without AM/PM and hh:mmaa is used for 12-hour format with AM/PM.

Sending an AMP Message

Google's Accelerated Mobile Pages (AMP) for email is a web component framework that you can use to easily create user-first websites, stories, emails, and ads. The AMP email format provides a subset of AMPHTML components for use in email messages, that allows recipients of AMP emails to interact dynamically with content directly in the message. Mailgun allows senders to include AMP components within their email message(s) using the amp-html parameter. This allows recipients to interact within the email message.

Some examples include:

  • Answering surveys
  • Replying to documents
  • Viewing inventory in real-time
  • Submitting updates

AMP Requirements

While AMP is a really exciting email tool, it takes a bit of setup before you can successfully send an AMP email message to your recipients.

Registration

Here's what you'll need to know to register:

  • In order to send AMP emails to mailboxes that support it (Gmail for now), you’ll need to register your sending domain with Google. Click here to register.

Content

Note:

If you follow the AMP requirements set by Google, you should be well on your way to sending AMP messages.

HTTPS URLs

All URLs must use HTTPS, including tracking and unsubscribe URLs. If you're using Mailgun for your open/click tracking and unsubscribe UR:s, you'll need to Follow these steps to enable HTTPS on your Mailgun tracking URLs.

Sending AMP emails

Mailgun has made it easy to send an AMP email using our API by providing the optional amp-html parameter along with your AMP content. Mailgun will take care of building the proper text/x-amp-html MIME portion. As long as you’re following the AMP requirements set by Google, you should be well on your way to sending your AMP messages.

Testing your AMP email messages

Note:

You can build and test your AMP email messages even while you're waiting for Google to register your domain.

AMP Best Practices

  1. Visit your Gmail settings page ( GSuite users will need their admins to enable the Dynamic Email Option )
  2. Click the Dynamic Email section, check the box to Enable Dynamic Email .
  3. Click Developer Settings
  4. Enter your sending address in the field – This will whitelist your sending address.
  5. Click OK

Following the proper requirements and these steps for sending AMP messages will allow you to be able to receive an AMP email from your sending address to your Gmail account.

Send with Attachments

Adding attachments uses the 'attachment' parameter. This example attaches 2 files to the email:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject="Hello there!" \
    -F text='Testing some Mailgun awesomeness!' \
    -F attachment=@tps-report.txt \
    -F attachment=@cover-letter.txt

You can also use the 'inline' parameter to include inline files that are intended to be displayed in the message itself (note the cid:email.jpg reference):

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject="Hello there!" \
    -F inline=@email.jpg \
    --form-string html='<html><body><p>Hello from <img src="cid:email.jpg"/></p></body></html>'

Attaching Data to Messages

When sending messages, you can attach data for later retrieval. For instance, you can attach campaign or recipient identifiers to messages to help relate webhook payloads or events retrieved from mailgun back to marketing campaigns or individual recipients in your system.

There are two methods for attaching data to emails depending on if you're sending messages via SMTP or via API.

Attaching Data to emails via SMTP

When sending messages via SMTP, you can attach data by providing a X-Mailgun-Variables header. You can provide multiple X-Mailgun-Variables headers, their map values will be combined. The header data must be in JSON map format, as shown in the example below.

Copy
Copied
X-Mailgun-Variables: {"first_name": "John", "last_name": "Smith"}
X-Mailgun-Variables: {"my_message_id": 123}
Note:

The value of the "X-Mailgun-Variables" header must be a valid JSON string, otherwise Mailgun won't be able to parse it. If your "X-Mailgun-Variables" header exceeds 998 characters, you should use folding to spread the variables over multiple lines.

Attaching Data to emails via API

If you are sending email via the HTTP API, you can attach data by providing a form parameter with v:

For example:

Copy
Copied
v:first_name=John
v:last_name=Smith
v:my_message_id=123

The data provided will be included in the recipient's email via a header called X-Mailgun-Variables. Additionally, the data will also be available via webhook payloads, and events returned from the events API. The data will be attached to these payloads via the user-variables field as a JSON map. For example:

Copy
Copied
 {
    "event": "delivered",
    "user-variables": {
        "first_name": "John",
        "last_name": "Smith",
        "my_message_id": "123"
    }
}

When sending batches of emails, you can use values from recipient variables to provide a custom variable per recipient using templating. For example, given a variable of v:recipient-id=%recipient.id%and a recipient variable of{"user1@example.com" : { "id": 123 }}events andwebhooks associated with the recipient user1@example.comwill contain auser-variablefield with the content of{ "recipient-id": "123" }

When using variables, the X-Mailgun-Variables header will be included in the MIME of the delivered email. This means that recipients who receive emails when variables are used will be able to see the variables if they view the MIME headers.

Sending at a Specific Time

Message Queue

The queuing algorithms are one of the most important features of Mailgun. If you try sending bulk mailings all at once, most ISPs will block you. Mailgun will put your messages in a message queue when you submit them for delivery.

  • A large number of messages can be submitted.
    • Mailgun will automatically queue for the delivery in compliance with the receiving domains' guidelines and maximum sending rate optimized for each ESP (email service provider), such as Yahoo, Gmail, etc.
  • The messaging queue is dynamic.
    • Your messages may take longer at first, however, your sending rates will increase the more you send messages.
    • As your reputation grows, your sending rate will grow too.
Note:

Note: It is important to make sure you are sending quality traffic to ensure sending rates.

It is important to gradually increase your sending rates according to many factors, including:

  • Consistency of traffic
  • IP address sending history
  • Domain reputation.

Batch Sending

Mailgun supports the ability to send to a group of recipients through a single API call, or SMTP session. This is achieved by:

  • Using Batch Sending by specifying multiple recipient email addresses as to parameters and using Recipient Variables.
  • Using Mailing Lists with the Template Variables
Warning!

When using Batch Sending, it is important to also use Recipient Variables. This will ensure that Mailgun will send an individual to each recipient in the to field. If this is not done, the email will show all recipients emails in the to field for all recipients

Recipient Variables

Recipient Variables are custom variables that you define to allow the ability to send a custom message to each recipient while using a single API call (or SMTP session).

To access a Recipient Variable within your email, simply reference %recipient.yourkey%. For example, consider the following JSON:

Copy
Copied
{
  "user1@example.com" : {"unique_id": "ABC123456789"},
  "user2@example.com" : {"unique_id": "ZXY987654321"}
}

To reference the above variable within your email, use %recipient.unique_id%

Recipient Variables allow to:

  • Submit a message template
  • Include multiple recipients
  • Include a set of key value pairs with unique data for each recipient
Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=alice@example.com \
    -F to=bob@example.com \
    -F subject="Hey %recipient.name%" \
    -F text='If you wish to unsubscribe, click <https://mailgun.com/unsubscribe/%recipient.id%>' \
    -F recipient-variables='{"alice@example.com": {"name":"Alice", "id":1}, "bob@example.com": {"name":"Bob", "id":2}}' \

The example above: Alice and Bob both will get personalized subject lines, "Hey, Alice", and "Hey, Bob", as well as unique unsubscribe links.

Note:
  • The maximum number of recipients allowed for batch is 1,000
  • Recipient variables should be set as a valid JSON-encoded dictionary where key is a plain recipient address, and value is a dictionary with variables.

When sent via SMTP, recipient variables can be included by adding the following header to your email:

X-Mailgun-Recipient-Variables: {"user1@example.com": {"unique\_id": "ABC123456789"}}

Example:

Copy
Copied
X-Mailgun-Recipient-Variables: {"bob@example.com": {"first":"Bob", "id":1}, "alice@example.com": {"first":"Alice", "id": 2}}
From: me@example.com
To: %recipient%
Date: 29 Mar 2016 00:23:35 -0700
Subject: Hello, %recipient.first%!
Message-Id: <20160329071939.35138.9413.6915422C@example.com>
Content-Type: text/plain; charset="us-ascii"
Content-Transfer-Encoding: quoted-printable

Hi, %recipient.first%,
=20
Please review your profile at example.com/orders/%recipient.id%.
=20
Thanks,
Example.com Team
Note:
  • The value of the "X-Mailgun-Recipient-Variables" header should be a valid JSON string, otherwise Mailgun won't be able to parse it.
  • If your "X-Mailgun-Recipient-Variables" header exceeds 998 characters, you should use folding to spread the variables over multiple lines.

They can also be supplied through a special construct called a Variable Container.

To contain variables, create the following MIME construct:

Copy
Copied
multipart/mailgun-variables
--application/json (base64 encoded)
--message/rfc822
----original-message

In this construct, JSON will be Base64 encoded, and will be stored inside the part of the body which will handle recipient variables containing special characters.

Example:

Copy
Copied
Content-Type: multipart/mailgun-variables; boundary="8686cc907910484e9d21c54776cd791c"
Mime-Version: 1.0
From: me@example.com
Date: Thu, 26 Jul 2012 15:43:07 +0000
Message-Id: <20120726154307.29852.44460@definebox.com>
Sender: bob=bob-mg@definebox.com

--8686cc907910484e9d21c54776cd791c
Mime-Version: 1.0
Content-Type: application/json
Content-Transfer-Encoding: base64

eyJkZXNjcmlwdGlvbiI6ICJrbGl6aGVudGFzIn0=

--8686cc907910484e9d21c54776cd791c
Content-Type: message/rfc822
Mime-Version: 1.0

Date: Thu, 26 Jul 2012 19:42:55 +0400
To: %recipient.description% <support@mailgunhq.com>
From: me@example.com
Subject: (rackspace) Hello
 MSK 2012 support@mailgunhq.com %recipient.description%
Message-Id: <20120726154302.29322.40670@definebox.com>

support@mailgunhq.com %recipient.description%

--8686cc907910484e9d21c54776cd791c--

Mailing Lists

Mailing Lists are a great way to send to multiple recipients while using an email alias. When you use mailing lists, Mailgun will send a copy of the message to each subscribed member using the email alias. You can create and maintain your subscriber lists using the API or Control Panel. In addition, you can use Template Variables to create a unique message for each member of the mailing list.

Using Mailing Lists

  1. Create a mailing list email address (example: devs@example.com)
  2. Add member email addresses to the mailing list
  3. Each time you send a message using the mailing list email address (example: devs@example.com), a copy of the email is delivered to each subscribed member.

Managing a Mailing List

You can create Mailing Lists using the Mailing Lists tab in the Control Panel or through the API. To make it easier, Mailgun has support for a couple different formats to upload Mailing List members:

  • You can upload a CSV file with the members.
  • You can use a JSON array form parameter
  • You can use form-like file upload

Creating a mailing list through the API:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
   https://api.mailgun.net/v3/lists \
   -F address='LIST@YOUR_DOMAIN_NAME' \
   -F description='Mailgun developers list'

Adding a single member through the API:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/lists/LIST@YOUR_DOMAIN_NAME/members \
    -F subscribed=True \
    -F address='bar@example.com' \
    -F name='Bob Bar' \
    -F description='Developer' \
    -F vars='{"age": 26}'

Adding multiple members using the JSON array approach, you can either send a flat list of member addresses:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/lists/LIST@YOUR_DOMAIN_NAME/members.json \
    -F members='["alice@example.com","bob@example.com"]'

Members added this way are implicitly set as subscribed.

Alternatively, you can provide the full JSON payload expected for a member for the same fine-grained control when adding a single member:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/lists/LIST@YOUR_DOMAIN_NAME/members.json \
    -F members='[{"name": "Bob Bar", "address": "bar@example.com", "subscribed": true, "vars": "{}"}]'
Note:

Note the use of vars to attach a JSON dictionary with structured data to each member of the mailing list. You can reference that data in the body of the message using Template Variables.

There are two modes available when adding a new member, strict and upsert.

  • Strict will raise an error in case the member already exists.
  • Upsert will update an existing member if it's already in the list or insert a new one.

Learn how to toggle between the modes and skip malformed addresses in the API documentation pages for the Mailing Lists API

Sending to a Mailing List

Sending to a Mailing List is as easy as using one of our APIs, HTTP or SMTP, and sending an email to the address created for the Mailing List as the recipient.

You can set the access level on Mailing Lists to:

  • Only allow the administrator to post to the list (limited to an API call or authenticated SMTP session)
  • Allow Mailing List members to post to the list
  • Allow anybody to post to the list

Replying to a Mailing List

You can set the preferred method to where a reply to the list should go:

  • list Replies to the list go to the list address. This is the default setting for any new list created, except for read-only lists, where replies can only go to the sender. Reply-all will still go to the list.
  • sender Replies to the list going to the sender (FROM) address. This is the default and the only option for read-only lists.

Template Variables

Header Description
%recipient% Full recipient spec, like “Bob bob@example.com” (for using as value for “To” MIME header).
%recipient_email% Recipient’s email address, like bob@example.com.
%recipient_name% Recipient’s full name, like “John Q. Public”.
%recipient_fname% Recipient’s first name.
%recipient_lname% Recipient’s last name.
%unsubscribe_url% A generated URL which allows users to unsubscribe from messages.
%mailing_list_unsubscribe_url% A generated URL which allows users to unsubscribe from mailing lists.
%unsubscribe_email% An email address which can be used for automatic unsubscription by adding it to List-Unsubscribe MIME header.
%recipient.yourvar% Accessing a custom datavalue. (see Attaching Data to Messages)

Unsubscribing

To manage unsubscribes in Mailing Lists, you can use %mailing_list_unsubscribe_url%. Mailgun will generate a unique link to unsubscribe from the mailing list. Once a recipient clicks on the unsubscribe link. The recipient is marked as "unsubscribed" from this mailing list and won't get any further emails addressed to this list.

Note:

You can still override the "unsubscribe" setting via the API or the Control Panel (in case of user error or accidental unsubscribe). You can also manually unsubscribe to the customer without using any links via the API or the Control Panel. Read more in the Mailing Lists API section.

Mailing Lists and Routes

Mailing lists work independently from Routes. When there is a Mailing List or Route with the same address, the incoming message will hit the Route and Mailing List simultaneously. This can be convenient for processing replies to the Mailing List and integrating into things like forums or commenting systems.

Templates

Mailgun allows you to store predefined templates via the Template API and use them to send messages via the Sending API by providing the template name.

To learn more about templates and how to use them, see the article: What's Up with Mailgun Templates?

To send a message using the template feature:

First, you must create a template. You can do this via the Template API, or via our Template Builder in our UI.

Copy
Copied
curl -X POST -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/templates \
    --form-string template='<div class="entry"> <h1>{{title}}</h1> <div class="body"> {{body}} </div> </div>' \
    -F name='template.test' \
    -F description='Sample template'

The response returns stored template information:

Copy
Copied
{
  "template": {
     "createdAt": "Wed, 29 Aug 2018 23:31:13 UTC",
     "description": "Sample template",
     "name": "template.test",
  },
  "message": "template has been stored"
}

The template is now ready to use for sending messages:

Copy
Copied
curl -s --user 'api:YOUR_API_KEY' \
    https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/messages \
    -F from='Excited User <postmaster@YOUR_DOMAIN_NAME>' \
    -F to=recipient@example.com \
    -F subject='Hello there!' \
    -F template="template.test" \
    -F t:variables='{"title": "API documentation", "body": "Sending messages with templates"}'

If you are sending a MIME, you can instead pass template variables via the X-Mailgun-Template-Variables header.

Note:

Values can be defined via the v: option or X-Mailgun-Variables in your templates. However, if you do so, the variables are included in the delivered message via the X-Mailgun-Variables header. If this is not desired, use the t:variables option or X-Mailgun-Template-Variables header instead.

Handlebars

Mailgun's templates use a fork of the template engine, Handlebars. To provide values for substitution, you must use Attaching Data to Messages.

One of the easy ways to implement dynamic content in your template is to use Handlebar's Block Helpers. Mailgun's implementation of Handlebars supports the following block helpers: if, unless, each, with, equal.

Helper Description
if The if helper allows you to conditionally render a block in your template. For example, if you wanted to use a template that would dynamically change the language in the body.
unless The unless helper is essentially the inverse of the if helper. The block will only be rendered if the expression returns a false value.
each The each helper allows you to iterate through a list.
equal The equal helper renders a block if the string version of both arguments are equal.

Scheduling Delivery

Mailgun allows you to request a specific time for delivering messages.

Use o:deliverytime parameter if sending via the API. Use the MIME header X-Mailgun-Deliver-By when sending via SMTP.

Note:

If your billing plan supports 7 or more days of storage capability, you can now schedule emails out up to 7 days.

Sending in Test Mode

You can send messages in test mode by setting the o:testmode parameter to true. When you do this, Mailgun will accept the message but will not send it. This is useful for testing purposes.

Note:

You are charged for messages sent in test mode!