Routes¶
Mailgun Routes are a powerful way to handle the incoming traffic. See Routes section in the User Manual to learn more about how they work. This API allows you to work with routes programmatically.
The routes API endpoint is available at:
v3/routes
Routes are comprised of the following arguments:
- A filter (when to do something).
- A priority (in what order).
- An action (what to do).
Filters¶
Route filters are expressions that determine when an action is triggered. You can create a filter based on the recipient of the incoming email, the headers in the incoming email or use a catch-all filter. Filters support regular expressions in the pattern to give you a lot of flexibility when creating them.
match_recipient(pattern)
Matches smtp recipient of the incoming message against the regular expression pattern. For example this will match all messages coming to any recipient at @bar.com:
match_recipient(".*@bar.com")
match_header(header, pattern)
Similar to match_recipient
but instead of looking at a message recipient, it applies
the pattern to an arbitrary MIME header of the message. For this will match any message
with a word “support” in its subject:
match_header("subject", ".*support")
catch_all()
Matches if no preceeding routes matched. Usually you need to use it in a route with a lowest priority, to make sure it evaluates last.
Actions¶
If a route expression evaluates to true, Mailgun executes the corresponding action.
Currently you can use the following three actions in your routes: forward()
, store()
and stop()
.
forward(destination)
Forwards the message to a specified destination, which can be another email address or a URL. A few examples:
forward("mailbox@myapp.com")
forward("http://myapp.com/messages")
store(notification endpoint)
Stores the message temporarily (for up to 3 days) on Mailgun’s servers so that you can retrieve them later. This is helpful for large messages that may cause time outs or if you just want to retrieve them later.
You can specify a URL and we will notify you when the email arrives along with a URL where you can use to retrieve the message:
store(notify="http://mydomain.com/callback")
You can see a full list of parameters we will post to your URL in the Routes section of the User Manual. You can also get the locations of messages through the Events API and then retrieve the message through the Messages API.
stop()
Simply stops the priority waterfall so the subsequent routes will not be evaluated. Without a stop() action executed, all lower priority Routes will also be evaluated.
GET /routes
Fetches the list of routes. Note that routes are defined globally, per account, not per domain as most of other API calls.
Parameter | Description |
---|---|
limit | Maximum number of records to return. (100 by default) |
skip | Number of records to skip. (0 by default) |
GET /routes/<id>
Returns a single route object based on its ID. See examples below.
Parameter | Description |
---|---|
id | ID of the route |
POST /routes
Creates a new route.
Parameter | Description |
---|---|
priority | Integer: smaller number indicates higher priority. Higher priority routes are handled first. Defaults to 0. |
description | An arbitrary string. |
expression | A filter expression like
match_recipient('.*@gmail.com') |
action | Route action. This action is executed when the expression
evaluates to True. Example: forward("alice@example.com")
You can pass multiple action parameters. |
PUT /routes/<id>
Updates a given route by ID. All parameters are optional: this API call only updates the specified fields leaving others unchanged.
Parameter | Description |
---|---|
id | ID of the route |
priority | Integer: smaller number indicates higher priority. Higher priority routes are handled first. |
description | An arbitrary string. |
expression | A filter expression like
match_recipient('.*@gmail.com') |
action | Route action. This action is executed when the expression
evaluates to True. Example: forward("alice@example.com")
You can pass multiple action parameters. |
DELETE /routes/<id>
Deletes a route based on the id.
Parameter | Description |
---|---|
id | ID of the route |
Examples¶
Create a route of the highest priority with multiple actions:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/routes \
-F priority=0 \
-F description='Sample route' \
-F expression='match_recipient(".*@YOUR_DOMAIN_NAME")' \
-F action='forward("http://myhost.com/messages/")' \
-F action='stop()'
import com.mailgun.api.v3.MailgunRoutesApi;
import com.mailgun.model.routes.RoutesRequest;
import com.mailgun.model.routes.RoutesResponse;
// ...
public RoutesResponse createRoute() {
MailgunRoutesApi mailgunRoutesApi = MailgunClient.config(API_KEY)
.createApi(MailgunRoutesApi.class);
RoutesRequest routesRequest = RoutesRequest.builder()
.priority(0)
.description("sample route")
.expression("match_recipient('.*@YOUR_DOMAIN_NAME')")
.action("forward('http://myhost.com/messages/')")
.action("stop()")
.build();
return mailgunRoutesApi.createRoute(routesRequest);
}
# 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');
# Define your expression, actions, and description
$expression = 'match_recipient(".*@mg.example.com")';
$actions = array('forward("my_address@example.com")', 'stop()');
$description = 'Catch All and Forward';
# Issue the call to the client.
$result = $mgClient->routes()->create($expression, $actions, $description);
def create_route():
return requests.post(
"https://api.mailgun.net/v3/routes",
auth=("api", "YOUR_API_KEY"),
data={"priority": 0,
"description": "Sample route",
"expression": "match_recipient('.*@YOUR_DOMAIN_NAME')",
"action": ["forward('http://myhost.com/messages/')", "stop()"]})
def create_route
data = {}
data[:priority] = 0
data[:description] = "Sample route"
data[:expression] = "match_recipient('.*@YOUR_DOMAIN_NAME')"
data[:action] = []
data[:action] << "forward('http://myhost.com/messages/')"
data[:action] << "stop()"
RestClient.post "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/routes", data
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class CreateRouteChunk
{
public static void Main (string[] args)
{
Console.WriteLine (CreateRoute ().Content.ToString ());
}
public static IRestResponse CreateRoute ()
{
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.Resource = "routes";
request.AddParameter ("priority", 0);
request.AddParameter ("description", "Sample route");
request.AddParameter ("expression", "match_recipient('.*@YOUR_DOMAIN_NAME')");
request.AddParameter ("action",
"forward('http://myhost.com/messages/')");
request.AddParameter ("action", "stop()");
request.Method = Method.POST;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func CreateRoute(domain, apiKey string) (mailgun.Route, error) {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.CreateRoute(ctx, mailgun.Route{
Priority: 1,
Description: "Sample Route",
Expression: "match_recipient(\".*@YOUR_DOMAIN_NAME\")",
Actions: []string{
"forward(\"http://example.com/messages/\")",
"stop()",
},
})
}
import formData from 'form-data';
import Mailgun from 'mailgun.js';
const mailgun = new Mailgun(formData);
const client = mailgun.client({ username: 'api', key: 'YOUR_API_KEY' || '' });
(async () => {
try {
const createdRoute = await client.routes.create({
expression: 'match_recipient(".*@YOUR_DOMAIN_NAME")',
action: ['forward("http://myhost.com/messages/")', 'stop()'],
description: 'Sample route'
});
console.log('createdRoute', createdRoute);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"message": "Route has been created",
"route": {
"description": "Sample route",
"created_at": "Wed, 15 Feb 2012 13:03:31 GMT",
"actions": [
"forward(\"http://myhost.com/messages/\")",
"stop()"
],
"priority": 0,
"expression": "match_recipient(\".*@samples.mailgun.org\")",
"id": "4f3bad2335335426750048c6"
}
}
Listing routes:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/routes \
-d skip=1 \
-d limit=1
import com.mailgun.api.v3.MailgunRoutesApi;
import com.mailgun.model.routes.RoutesListResponse;
import com.mailgun.model.routes.RoutesPageRequest;
// ...
public RoutesListResponse getRoutes() {
MailgunRoutesApi mailgunRoutesApi = MailgunClient.config(API_KEY)
.createApi(MailgunRoutesApi.class);
RoutesPageRequest pageRequest = RoutesPageRequest.builder()
.skip(0)
.limit(5)
.build();
return mailgunRoutesApi.getRoutesList(pageRequest);
}
# 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');
# Issue the call to the client.
$result = $mgClient->routes()->index();
def get_routes():
return requests.get(
"https://api.mailgun.net/v3/routes",
auth=("api", "YOUR_API_KEY"),
params={"skip": 1,
"limit": 1})
def get_routes
RestClient.get "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/routes", :params => {
:skip => 1,
:limit => 1
}
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetRoutesChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetRoutes ().Content.ToString ());
}
public static IRestResponse GetRoutes ()
{
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.Resource = "routes";
request.AddParameter ("skip", 1);
request.AddParameter ("limit", 1);
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func ListRoutes(domain, apiKey string) ([]mailgun.Route, error) {
mg := mailgun.NewMailgun(domain, apiKey)
it := mg.ListRoutes(nil)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
var page, result []mailgun.Route
for it.Next(ctx, &page) {
result = append(result, page...)
}
if it.Err() != nil {
return nil, it.Err()
}
return result, nil
}
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: 'YOUR_API_KEY' || '' });
(async () => {
try {
const list = await client.routes.list({"skip": 0, "limit": 5});
console.log('list', list);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"total_count": 266,
"items": [
{
"description": "Sample route",
"created_at": "Wed, 15 Feb 2012 12:58:12 GMT",
"actions": [
"forward(\"http://myhost.com/messages/\")",
"stop()"
],
"priority": 0,
"expression": "match_recipient(\".*@samples.mailgun.org\")",
"id": "4f3babe4ba8a481c6400476a"
}
]
}
Access the route by id:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/routes/4f3bad2335335426750048c6
import com.mailgun.api.v3.MailgunRoutesApi;
import com.mailgun.model.routes.SingleRouteResponse;
// ...
public SingleRouteResponse getSingleRoute() {
MailgunRoutesApi mailgunRoutesApi = MailgunClient.config(API_KEY)
.createApi(MailgunRoutesApi.class);
return mailgunRoutesApi.getSingleRoute(YOUR_ROUTE_ID);
}
# 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');
$route_id = '5d9fde0fd8b861ec16cf2549'
# Issue the call to the client.
$result = $mgClient->routes()->show($route_id);
def get_route():
return requests.get(
"https://api.mailgun.net/v3/routes/4e97c1b2ba8a48567f007fb6",
auth=("api", "YOUR_API_KEY"))
def get_route
RestClient.
get("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/routes/"\
"4e97c1b2ba8a48567f007fb6"){|response, request, result| response }
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetRouteChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetRoute ().Content.ToString ());
}
public static IRestResponse GetRoute ()
{
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.Resource = "routes/{id}";
request.AddUrlSegment ("id", "4e97c1b2ba8a48567f007fb6");
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func GetRoute(domain, apiKey string) (mailgun.Route, error) {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.GetRoute(ctx, "route_id")
}
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: 'YOUR_API_KEY' || '' });
(async () => {
try {
const route = await client.routes.get('your_route_id');
console.log('route', route);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"route": {
"description": "Sample route",
"created_at": "Wed, 15 Feb 2012 13:03:31 GMT",
"actions": [
"forward(\"http://myhost.com/messages/\")",
"stop()"
],
"priority": 0,
"expression": "match_recipient(\".*@samples.mailgun.org\")",
"id": "4f3bad2335335426750048c6"
}
}
Sample payload for a store()
webhook:
Content-Type: multipart/alternative; boundary="001a114490d2c5be3d05433e6d03"
Date: Fri, 9 Dec 2016 13:04:51 -0600
From: Excited User <user@samples.mailgun.com>
Message-Id: <CABPem2N_Ucj3wRRZnLVpVF_fRjkTBXHZReZC3zY-hHsRa=T51g@samples.mailgun.com>
Mime-Version: 1.0
Subject: Message Routes
To: hook@sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org
X-Envelope-From: <user@samples.mailgun.com>
X-Mailgun-Incoming: Yes
X-Originating-Ip: [2001:xxx:xxxx:xxx::beef:93]
body-html: <div dir="ltr">Testing Mailgun's forwarded and stored message routes :)</div>
body-plain: Testing Mailgun's forwarded and stored message routes :)
domain: sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org
from: Excited User <user@samples.mailgun.com>
message-headers: [["X-Mailgun-Incoming", "Yes"], ["X-Envelope-From", "<user@samples.mailgun.com>"], ["Mime-Version", "1.0"], ["X-Originating-Ip", "[2001:xxx:xxxx:xxx::beef:93]"], ["From", "Excited User <user@samples.mailgun.com>"], ["Date", "Fri, 9 Dec 2016 13:04:51 -0600"], ["Message-Id", "<CABPem2N_Ucj3wRRZnLVpVF_fRjkTBXHZReZC3zY-hHsRa=T51g@samples.mailgun.com>"], ["Subject", "Message Routes"], ["To", "hook@sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org"], ["Content-Type", "multipart/alternative; boundary=\"001a114490d2c5be3d05433e6d03\""]]
message-url: https://si.api.mailgun.net/v3/domains/sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org/messages/eyJwIjpmYWxzZSwiayI6IjFlOTZmNTkyLTAyOWItNDJkYi1iNjM5LTgzNTgwYzMxYjNhOCIsInMiOiIyMmNkYTRkZWFhIiwiYyI6InNhaWFkIn0=
recipient: hook@sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org
sender: user@samples.mailgun.com
signature: 6ed72df4b5f00af436fff03730dc8bda31bf5800fdf431d1da5c0009a639d57e
stripped-html: <div dir="ltr">Testing Mailgun's forwarded and stored message routes :)</div>
stripped-signature:
stripped-text: Testing Mailgun's forwarded and stored message routes :)
subject: Message Routes
timestamp: 1481310293
token: f2a24f20007696fb23fd66ff0f59f17fac3f885324caaaec50
Sample payload for a forward()
webhook:
Content-Type: multipart/alternative; boundary="001a114490d2c5be3d05433e6d03"
Date: Fri, 9 Dec 2016 13:04:51 -0600
From: Excited User <user@samples.mailgun.com>
Message-Id: <CABPem2N_Ucj3wRRZnLVpVF_fRjkTBXHZReZC3zY-hHsRa=T51g@samples.mailgun.com>
Mime-Version: 1.0
Subject: Message Routes
To: hook@sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org
X-Envelope-From: <user@samples.mailgun.com>
X-Mailgun-Incoming: Yes
X-Originating-Ip: [2001:xxx:xxxx:xxx::beef:93]
body-html: <div dir="ltr">Testing Mailgun's forwarded and stored message routes :)</div>
body-plain: Testing Mailgun's forwarded and stored message routes :)
from: Excited User <user@samples.mailgun.com>
message-headers: [["X-Mailgun-Incoming", "Yes"], ["X-Envelope-From", "<user@samples.mailgun.com>"], ["Mime-Version", "1.0"], ["X-Originating-Ip", "[2001:xxx:xxxx:xxx::beef:93]"], ["From", "Excited User <user@samples.mailgun.com>"], ["Date", "Fri, 9 Dec 2016 13:04:51 -0600"], ["Message-Id", "<CABPem2N_Ucj3wRRZnLVpVF_fRjkTBXHZReZC3zY-hHsRa=T51g@samples.mailgun.com>"], ["Subject", "Message Routes"], ["To", "hook@sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org"], ["Content-Type", "multipart/alternative; boundary=\"001a114490d2c5be3d05433e6d03\""]]
recipient: hook@sandboxdb91ab935a414789809f96c91229a0ee.mailgun.org
sender: user@samples.mailgun.com
signature: 17436304dd4dd094e9b8c3addb975acc6297718da468c2900dac4a43787c97596
stripped-html: <div dir="ltr">Testing Mailgun's forwarded and stored message routes :)</div>
stripped-signature:
stripped-text: Testing Mailgun's forwarded and stored message routes :)
subject: Message Routes
timestamp: 1481310293
token: a71d0000ed34da6768198da96f9daaf8fb98adbccfdbd2fdaf