• Email DIY

Getting Started With Our Email Templates API

Sergey Chekluev
5 min read

Recently, we were thrilled to announce the launch of our recently implemented email templates API and templates design contest. While we went over where those templates came from, we only glossed over how to actually use them. For this week, we wanted to show you how you can get started with your own email templates, rather than using one of the ones we’ve already provided.

Currently, Mailgun supports the template engine: Handlebars v 3.0 template. Different people prefer different engines, but Handlebars is pretty popular and commonplace for email design these days, so that's our default.

Assuming you already have a Mailgun account and a verified domain in our system, you can go ahead with uploading templates to your account for use.

Uploading and updating templates

In order to use the templates API, you have to store a template in the system and have at least one active version. You can pull one of the templates we have in the repository, but we understand that many businesses already have templates they’re set on using. In which case, you’ll need to store it within the API.

Let’s try storing a template:

1curl -X POST https://api.mailgun.net/v3/example.com/templates
2 -F name="billing"
3 -F description = "description of your template"

The Name parameter is mandatory and used to reference the template in any future API calls you make for that template.

Now we need to store a version of the template. For the sake of this demo, we got the content from one of our older transactional email templates.

Let’s assume that the content of the template is stored on your local disc with the name billing.html. For simplicity’s sake, we used python code to show how to store the first version of the template in the API:

1import requests
3content = None
4with open("/path_to_file/billing.html", 'r') as f:
5 content = f.read()
9 auth=('api': "key"),
10 data={"tag": "v0",
11 "comment": "version comment",
12 "template": content})

There are two parameters that are mandatory in order to store a new version: tag and template. The tag helps to identify a specific template version (more on that later), while the template identifies the template content itself.

However, the first version of any template does not require a tag parameter, but all future versions will. It helps keep things nice and organized.

Also, there is a way to store template with an initial version using only one POST. This saves you a couple of steps in the future if you want to save time. All you need to provide in the POST is the tag and template parameters at the time of storage:

1curl -X POST https://api.mailgun.net/v3/example.com/templates
2 -F name="billing"
3 -F description="template description" -F tag="v0"
4 -F template=”template contents”

Or by pulling the contents from a file:

1curl -X POST https://api.mailgun.net/v3/example.com/templates
2 -F name="billing"
3 -F description="template description" -F tag="v0"
4 -F template=<code data-enlighter-language="generic" class="EnlighterJSRAW">content from file billing.html</code>

So, what about sending?

Now that we’ve stored a template and created a version of it, let’s use Mailgun’s API to send a test message. While rendering a message is nice, sending a test message allows you to see if your variable information is working as it should. In order for variable information to work, you need to make sure you are attaching your data correctly, which will depend on whether your sending via SMTP or API.

Assuming you are attaching your data properly, let’s send a message with some variables. First, using form variables in the POST

1curl -X POST https://api.mailgun.net/v3/example.com/messages
2 -F template="billing"
3 -F v:firstName="John" -F v:lastName="Doe" -F v:number="12345"
4 -F v:date="Mar 01, 2019" -F v:amount1="23.00"-F v:amount2="10.20"
5 -F v:total="33.20"

Or, alternatively using recipient variables in a JSON object:

1curl -X POST https://api.mailgun.net/v3/example.com/messages
2 -F template="billing"
3 -H "X-Mailgun-Variables: {"firstName": "John", "lastName": "Doe", "number": "12345",
4 "data":"Mar 01, 2019", "amount1": "23.00",
5 "amount2": "10.20", "total": "33.20"}"

We’re a little partial to the second method as it allows you to provide nested JSON objects. It’s a little cleaner that way. When you send the test email, it should match your rendering, with the variables in place.

It’s worth noting that if you have several versions of one template, there must always be one active version. The active version is the default version that is used when you send a message. The first version is active by default when you first upload a template, and it’s easy to update the active version with a simple request (assume there are two versions, v0 and v1, and v0 is active):

1curl -X PUT https://api.mailgun.net/v3/example.com/templates/billing/v1
2     -F active="yes"

But this is only the start of what you can do with our templates. Once you start getting into the template engines themselves, you can build out an email template that can do all the hard work for you.


As mentioned at the start, our templates support Handlebars. One of the cool things about Handlebars is its built-in helpers, which are an easy way to include dynamic content in your templates. Our implementation of Handlebars supports the following helpers: if, unless, each, with, lookup and equal. For the sake of time, here are the 3 most useful helpers, and what they do:

The if block helper

The if block helper will allow you to conditionally render a block in your template. For example, if you want to include multiple language versions of your body in your template, and only render a specific language block, you can use the if block helper.

The unless block helper

The unless helper is essentially the inverse of the if helper. The block will only be rendered if the expression returns a false value.

The each block helper

Using the each helper, you can iterate through a list.

If you are interested in learning more about Handlebars helpers, head over to our docs for more info and examples.

Using different versions for A/B testing

While versions are great for information updates, one of the most creative ways you can use them is for A/B testing different copy, design elements, CTAs, etc. and seeing which one is more successful. Creating multiple versions is easy, and sending with a specific version outside of the active version is easy with some simple flags, t:version and t:text:

1curl -X POST https://api.mailgun.net/v3/example.com/messages
2 -F template="billing"
3 -F t:version="v1"
4 -F t:text="yes"

But what about results?

We’ve covered everything up until what comes after you send. In an A/B test, you need to be able to see which version outperformed the others. Otherwise, there isn’t a whole lot of sense in A/B testing — you’re just throwing away your efforts.

That’s where our stats API comes in. In order to get the specific statistics on a tag, you need to make a GET request via the stats API.

When you send a templated message, the header has auto-populated tags both the template and the version itself. It makes it easier to see the results of any given template, which helps you determine which template works best for you.

Wrapping up

When you have anything with custom variables, you always want to be sure that they are working correctly within the template itself. Sending a test message to yourself is a good way to make sure everything is working as it should.

You can also use third party tools like jsonlint to check if your variables are valid as well. However, should you find that you run into any issues with your templates, send us a support ticket and we can help you out.

Feeling creative? Send us your template designs! You can read more on that on this blog post and in the official rules.

Last updated on May 15, 2021

  • Related posts
  • Recent posts
  • Top posts
View all

Always be in the know and grab free email resources!

No spam, ever. Only musings and writings from the Mailgun team.

By sending this form, I agree that Mailgun may contact me and process my data in accordance with its Privacy Policy.

sign up
It's easy to get started. And it's free.
See what you can accomplish with the world's best email delivery platform.
Sign up for Free