Suppressions¶
Mailgun keeps three lists of addresses it blocks the delivery to: bounces, unsubscribes and complaints. These lists are populated automatically as Mailgun detects undeliverable addresses you try to send to and as recipients unsubscribe from your mailings or mark your emails as a spam (for ESPs that provide FBL). You can also add/remove addresses from any of these lists using the API.
It’s important to note that these suppression lists are unique to a sending domain and are not an account level (global) suppression list. If you want to add/remove the same address(es) from multiple domains, you’ll need to do so for each domain.
You can determine if you have reached the last page of suppressions if the <next page URL> is equal to the <last page URL>.
Bounces¶
Bounce list stores events of delivery failures due to permanent recipient mailbox errors such as non-existent mailbox. Soft bounces (for example, mailbox is full) and other failures (for example, ESP rejects an email because it thinks it is spam) are not added to the list.
Subsequent delivery attempts to an address found in a bounce list are prevented to protect your sending reputation.
The bounce suppression API endpoint is available at:
v3/<domain>/bounces
Mailgun can notify your application every time a message bounces via a permanent_fail webhook.
View all bounces¶
GET /<domain>/bounces
Paginate over a list of bounces for a domain.
Note
Via this API method bounces are returned in the alphabetical order. If you wish to poll for the recently occurred bounces, please consider using the Events API.
Parameter | Description |
---|---|
limit | Maximum number of records to return (optional, default: 100, max: 1000) |
Example:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces
import com.mailgun.api.v3.suppression.MailgunSuppressionBouncesApi;
import com.mailgun.model.suppression.bounces.BouncesResponse;
// ...
public BouncesResponse getBounces() {
MailgunSuppressionBouncesApi suppressionBouncesApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionBouncesApi.class);
return suppressionBouncesApi.getBounces(YOUR_DOMAIN_NAME);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
# Issue the call to the client.
$result = $mgClient->suppressions()->bounces()->index($domain);
def get_bounces():
return requests.get(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces",
auth=("api", "YOUR_API_KEY"))
def get_bounces
RestClient.get "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetBouncesChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetBounces ().Content.ToString ());
}
public static IRestResponse GetBounces ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/bounces";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func ListBounces(domain, apiKey string) ([]mailgun.Bounce, error) {
mg := mailgun.NewMailgun(domain, apiKey)
it := mg.ListBounces(nil)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
var page, result []mailgun.Bounce
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 bounces = await client.suppressions.list(DOMAIN, 'bounces');
console.log('bounces', bounces);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"items":
[
{
"address": "alice@example.com",
"code": "550",
"error": "No such mailbox",
"created_at": "Fri, 21 Oct 2011 11:02:55 GMT"
},
...
],
"paging":
{
"first": <first page URL>,
"next": <next page URL>,
"previous": <previous page URL>,
"last": <last page URL>
}
}
View a single bounce¶
GET /<domain>/bounces/<address>
Fetch a single bounce event by a given email address. Useful to check if a given email address has bounced before.
Example:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces/foo@bar.com
import com.mailgun.api.v3.suppression.MailgunSuppressionBouncesApi;
import com.mailgun.model.suppression.bounces.BouncesItem;
// ...
public BouncesItem getBounce() {
MailgunSuppressionBouncesApi suppressionBouncesApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionBouncesApi.class);
return suppressionBouncesApi.getBounce(YOUR_DOMAIN_NAME, "foo@bar.com");
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
$recipient = 'bob@example.com';
# Issue the call to the client.
$result = $mgClient->suppressions()->bounces()->show($domain, $recipient);
def get_bounce():
return requests.get(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces/foo@bar.com",
auth=("api", "YOUR_API_KEY"))
def get_bounce
RestClient.get("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces"\
"/foo@bar.com"){|response, request, result| response }
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetBounceChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetBounce ().Content.ToString ());
}
public static IRestResponse GetBounce ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/bounces/foo@bar.com";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func GetBounce(domain, apiKey string) (mailgun.Bounce, error) {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.GetBounce(ctx, "foo@bar.com")
}
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 bouncesForAddress = await client.suppressions.get(DOMAIN, 'bounces', 'foo@bar.com');
console.log('bouncesForAddress', bouncesForAddress);
} catch (error) {
console.error(error);
}
})();
Expected responses:
200
{
"address": "foo@bar.com",
"code": "550",
"error": "No such mailbox",
"created_at": "Fri, 21 Oct 2011 11:02:55 GMT"
}
404
{
"message": "Address not found in bounces table"
}
Add a single bounce¶
POST /<domain>/bounces
Add a bounce record to the bounce list. Updates the existing record if the address is already there.
Parameter | Description |
---|---|
address | Valid email address |
code | Error code (optional, default: 550) |
error | Error description (optional, default: empty string) |
created_at | Timestamp of a bounce event in RFC2822 format (optional, default: current time) |
Example:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces \
-F address='bob@example.com'
import com.mailgun.api.v3.suppression.MailgunSuppressionBouncesApi;
import com.mailgun.model.suppression.SuppressionResponse;
import com.mailgun.model.suppression.bounces.BouncesRequest;
import java.time.ZonedDateTime;
// ...
public SuppressionResponse addBounce() {
MailgunSuppressionBouncesApi suppressionBouncesApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionBouncesApi.class);
BouncesRequest bouncesRequest = BouncesRequest.builder()
.address("bob@example.com")
.code("550")
.error(ERROR_MESSAGE)
.createdAt(ZonedDateTime.now())
.build();
return suppressionBouncesApi.addBounce(YOUR_DOMAIN_NAME, bouncesRequest);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
$recipient = 'bob@example.com';
# Issue the call to the client.
$result = $mgClient->suppressions()->bounces()->create($domain, $recipient);
def add_bounce():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces",
auth=("api", "YOUR_API_KEY"),
data={'address':'bob@example.com'})
def add_bounce
RestClient.post("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/bounces",
:address => 'bob@example.com')
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class AddBounceChunk
{
public static void Main (string[] args)
{
Console.WriteLine (AddBounce ().Content.ToString ());
}
public static IRestResponse AddBounce ()
{
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 = "{domain}/bounces";
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.AddParameter ("address", "bob@example.com");
request.Method = Method.POST;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func AddBounce(domain, apiKey string) error {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.AddBounce(ctx, "bob@example.com", "550", "Undeliverable message error")
}
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 createdBounce = await client.suppressions.create(DOMAIN, 'bounces', { address: 'bob@example.com' });
console.log('createdBounce', createdBounce);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"message": "Address has been added to the bounces table",
"address": "bob@example.com"
}
Add multiple bounces¶
POST /<domain>/bounces, Content-Type: application/json
Add multiple bounce records to the bounce list in a single API call.
Request body is expected to be a valid JSON encoded string containing up to 1000 bounce records in the following format.
[
{
"address": "alice@example.com",
"code": "550",
"error": "Bounced",
"created_at": "Thu, 13 Oct 2011 18:02:00 UTC"
},
{
"address": "bob@example.com",
"code": "550",
"error": "Bounced"
},
{
"address": "carol@example.com",
"code": "550"
},
{
"address": "dan@example.com"
}
]
Fields within each individual bounce record are the same as for the “add a single bounce” API method, with the same defaults and optionality rules.
Note
The current versions of our language libraries do not support adding multiple bounces yet.
Expected response:
200
{
"message": "4 addresses have been added to the bounces table"
}
Import a list of bounces¶
POST /<domain>/bounces/import, Content-Type: multipart/form-data
Import a CSV file containing a list of addresses to add to the bounce list.
CSV file must be 25MB or under and must contain the following column headers: address,code,error,created_at
Column Description address Valid email address code Error code (optional, default: 550) error Error description (optional, default: empty string) created_at Timestamp of a bounce event in RFC2822 format (optional, default: current time)
Expected response:
200
{
"message": "file uploaded successfully"
}
Delete a single bounce¶
DELETE /<domain>/bounces/<address>
Clears a given bounce event. The delivery to the deleted email address resumes until it bounces again.
Expected response:
200
{
"message": "Bounced address has been removed"
}
Delete an entire bounce list¶
DELETE /<domain>/bounces
Clears all bounced email addresses for a domain. Delivery to the deleted email addresses will no longer be suppressed.
Expected response:
200
{
"message": "Bounced addresses for this domain have been removed"
}
Unsubscribes¶
Unsubscribe list stores email addresses of recipients who unsubscribed from your mailings by clicking a Mailgun generated unsubscribe link.
Mailgun allows you to quickly add “Unsubscribe me” feature to your outgoing emails without any programming on your end. You can enable this in your Control Panel under your domain settings.
The unsubscribe suppression API endpoint is available at:
v3/<domain>/unsubscribes
Mailgun can notify your application every time a user unsubscribes via an unsubscribed webhook.
View all unsubscribes¶
GET /<domain>/unsubscribes
Paginate over a list of unsubscribes for a domain.
Note
Via this API method unsubscribes are returned in the alphabetical order. If you wish to poll for the recently occurred unsubscribes, please consider using the Events API.
Parameter | Description |
---|---|
limit | Number of records to return (optional, default: 100, max: 1000) |
Example:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/unsubscribes
import com.mailgun.api.v3.suppression.MailgunSuppressionUnsubscribeApi;
import com.mailgun.model.suppression.unsubscribe.UnsubscribeItemResponse;
// ...
public UnsubscribeItemResponse getUnsubscribes() {
MailgunSuppressionUnsubscribeApi suppressionUnsubscribeApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionUnsubscribeApi.class);
return suppressionUnsubscribeApi.getAllUnsubscribe(YOUR_DOMAIN_NAME);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
# Issue the call to the client.
$result = $mgClient->suppressions()->unsubscribes()->index($domain);
def get_unsubscribes():
return requests.get(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/unsubscribes",
auth=("api", "YOUR_API_KEY"))
def get_unsubscribes
RestClient.get "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/unsubscribes"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetUnsubscribesChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetUnsubscribes ().Content.ToString ());
}
public static IRestResponse GetUnsubscribes ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/unsubscribes";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func ListUnsubscribes(domain, apiKey string) ([]mailgun.Unsubscribe, error) {
mg := mailgun.NewMailgun(domain, apiKey)
it := mg.ListUnsubscribes(nil)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
var page, result []mailgun.Unsubscribe
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 unsubscribes = await client.suppressions.list(DOMAIN, 'unsubscribes');
console.log('unsubscribes', unsubscribes);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"items":
[
{
"address": "alice@example.com",
"tag": "*",
"created_at": "Fri, 21 Oct 2011 11:02:55 GMT"
},
...
],
"paging":
{
"first": <first page URL>,
"next": <next page URL>,
"previous": <previous page URL>,
"last": <last page URL>
}
}
View a single unsubscribe¶
GET /<domain>/unsubscribes/<address>
Fetch a single unsubscribe record. Can be used to check if a given address is present in the list of unsubscribed users.
Expected responses:
200
{
"address": "alice@example.com",
"tag": "*",
"created_at": "Fri, 21 Oct 2011 11:02:55 GMT"
}
404
{
"message": "Address not found in unsubscribers table"
}
Add a single unsubscribe¶
POST /<domain>/unsubscribes
Add an address to the unsubscribe table.
Parameter | Description |
---|---|
address | Valid email address |
tag | Tag to unsubscribe from, use * to unsubscribe
an address from all domain’s correspondence (optional,
default: * ) |
created_at | Timestamp of an unsubscribe event in RFC2822 format (optional, default: current time) |
Example:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/unsubscribes \
-F address='bob@example.com' \
-F tag='*'
import com.mailgun.api.v3.suppression.MailgunSuppressionUnsubscribeApi;
import com.mailgun.model.suppression.SuppressionResponse;
import com.mailgun.model.suppression.unsubscribe.UnsubscribeSingleItemRequest;
import java.time.ZonedDateTime;
// ...
public SuppressionResponse addUnsubscribeAll() {
MailgunSuppressionUnsubscribeApi suppressionUnsubscribeApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionUnsubscribeApi.class);
UnsubscribeSingleItemRequest unsubscribeSingleItemRequest = UnsubscribeSingleItemRequest.builder()
.address("bob@example.com")
.tag("*")
.createdAt(ZonedDateTime.now())
.build();
return suppressionUnsubscribeApi.addAddressToUnsubscribeTable(YOUR_DOMAIN_NAME, unsubscribeSingleItemRequest);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
$recipient = 'bob@example.com';
$tag = '*';
# Issue the call to the client.
$result = $mgClient->suppressions()->unsubscribes()->create($domain, $recipient, $tag);
def unsubscribe_from_all():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/unsubscribes",
auth=("api", "YOUR_API_KEY"),
data={'address':'bob@example.com', 'tag': '*'})
def unsubscribe_from_all
RestClient.post "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/unsubscribes",
:address => 'bob@example.com',
:tag => '*'
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class AddUnsubscribeAllChunk
{
public static void Main (string[] args)
{
Console.WriteLine (UnsubscribeFromAll ().Content.ToString ());
}
public static IRestResponse UnsubscribeFromAll ()
{
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 = "{domain}/unsubscribes";
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.AddParameter ("address", "bob@example.com");
request.AddParameter ("tag", "*");
request.Method = Method.POST;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func CreateUnsubscribe(domain, apiKey string) error {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.CreateUnsubscribe(ctx, "bob@example.com", "*")
}
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 createdUnsubscribe = await client.suppressions.create(DOMAIN, 'unsubscribes', { address: 'bob@example.com', tag: '*' });
console.log('createdUnsubscribe', createdUnsubscribe);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"message": "Address has been added to the unsubscribes table",
"address": "bob@example.com"
}
Add multiple unsubscribes¶
POST /<domain>/unsubscribes, Content-Type: application/json
Add multiple unsubscribe records to the unsubscribe list in a single API call.
Request body is expected to be a valid JSON encoded string containing up to 1000 unsubscribe records in the following format.
[
{
"address": "alice@example.com",
"tags": ["some tag"],
"created_at": "Thu, 13 Oct 2011 18:02:00 UTC"
},
{
"address": "bob@example.com",
"tags": ["*"],
},
{
"address": "carol@example.com"
}
]
Fields within each individual unsubscribe record are the same as for the “add a single unsubscribe” API method, with the same defaults and optionality rules.
Note
The current versions of our language libraries do not support adding multiple unsubscribes yet.
Expected response:
200
{
"message": "3 addresses have been added to the unsubscribes table"
}
Import a list of unsubscribes¶
POST /<domain>/unsubscribes/import, Content-Type: multipart/form-data
Import a CSV file containing a list of addresses to add to the unsubscribe list.
CSV file must be 25MB or under and must contain the following column headers: address,tag,created_at
Column Description address Valid email address tags Tag to unsubscribe from, use *
to unsubscribe an address from all domain’s correspondence (optional, default:*
)created_at Timestamp of an unsubscribe event in RFC2822 format (optional, default: current time)
Expected response:
200
{
"message": "file uploaded successfully"
}
Delete a single unsubscribe¶
DELETE /<domain>/unsubscribes/<address>
Remove an address from the unsubscribes list. If tag
parameter is not provided,
completely removes an address from the list.
Parameter | Description |
---|---|
tag | Specific tag to remove (optional) |
Expected response:
200
{
"message": "Unsubscribe event has been removed"
}
Complaints¶
Complaint list stores email addresses of recipients who marked your messages as a spam (for ESPs that support FBL).
The complaint API endpoint is available at:
v3/<domain>/complaints
Mailgun can notify your application every time a recipient flags your message as spam via a complained webhook.
View all complaints¶
GET /<domain>/complaints
Paginate over a list of complaints for a domain.
Note
Via this API method complaints are returned in the alphabetical order. If you wish to poll for the recently occurred complaints, please consider using the Events API.
Parameter | Description |
---|---|
limit | Maximum number of records to return (optional, default: 100, max: 1000) |
Example:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints
import com.mailgun.api.v3.suppression.MailgunSuppressionComplaintsApi;
import com.mailgun.model.suppression.complaints.ComplaintsItemResponse;
// ...
public ComplaintsItemResponse getComplaints() {
MailgunSuppressionComplaintsApi suppressionComplaintsApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionComplaintsApi.class);
return suppressionComplaintsApi.getAllComplaints(YOUR_DOMAIN_NAME, 2);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
# Issue the call to the client.
$result = $mgClient->suppressions()->complaints()->index($domain);
def get_complaints():
return requests.get(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints",
auth=("api", "YOUR_API_KEY"))
def get_complaints
RestClient.get "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetComplaintsChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetComplaints ().Content.ToString ());
}
public static IRestResponse GetComplaints ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/complaints";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func ListComplaints(domain, apiKey string) ([]mailgun.Complaint, error) {
mg := mailgun.NewMailgun(domain, apiKey)
it := mg.ListComplaints(nil)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
var page, result []mailgun.Complaint
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 complaints = await client.suppressions.list(DOMAIN, 'complaints');
console.log('complaints', complaints);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"items":
[
{
"address": "alice@example.com",
"created_at": "Fri, 21 Oct 2011 11:02:55 GMT"
},
...
],
"paging":
{
"first": <first page URL>,
"next": <next page URL>,
"previous": <previous page URL>,
"last": <last page URL>
}
}
View a single complaint¶
GET /<domain>/complaints/<address>
Fetch a single spam complaint by a given email address. This is useful to check if a particular user has complained.
Example:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints/baz@example.com
import com.mailgun.api.v3.suppression.MailgunSuppressionComplaintsApi;
import com.mailgun.model.suppression.complaints.ComplaintsItem;
// ...
public ComplaintsItem getComplaint() {
MailgunSuppressionComplaintsApi suppressionComplaintsApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionComplaintsApi.class);
return suppressionComplaintsApi.getSingleComplaint(YOUR_DOMAIN_NAME, "baz@example.com");
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
$recipient = 'bob@example.com';
# Issue the call to the client.
$result = $mgClient->suppressions()->complaints()->show($domain, $recipient);
def get_complaint():
return requests.get(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints/baz@example.com",
auth=("api", "YOUR_API_KEY"))
def get_complaint
RestClient.get("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints/"\
"baz@example.com"){|response, request, result| response }
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetComplaintChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetComplaint ().Content.ToString ());
}
public static IRestResponse GetComplaint ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/complaints/baz@example.com";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func GetComplaints(domain, apiKey string) (mailgun.Complaint, error) {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.GetComplaint(ctx, "baz@example.com")
}
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 complaintsForAddress = await client.suppressions.get(DOMAIN, 'complaints', 'baz@example.com');
console.log('complaintsForAddress', complaintsForAddress);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"address": "baz@example.com",
"created_at": "Fri, 21 Oct 2011 11:02:55 GMT"
}
404
{
"message": "No spam complaints found for this address"
}
Add a single complaint¶
POST /<domain>/complaints
Add an address to the complaints list.
Parameter | Description |
---|---|
address | Valid email address |
created_at | Timestamp of a complaint event in RFC2822 format (optional, default: current time) |
Example:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints \
-F address='bob@example.com'
import com.mailgun.api.v3.suppression.MailgunSuppressionComplaintsApi;
import com.mailgun.model.suppression.SuppressionResponse;
import com.mailgun.model.suppression.complaints.ComplaintsSingleItemRequest;
import java.time.ZonedDateTime;
// ...
public SuppressionResponse addComplaint() {
MailgunSuppressionComplaintsApi suppressionComplaintsApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionComplaintsApi.class);
ComplaintsSingleItemRequest complaintsSingleItemRequest = ComplaintsSingleItemRequest.builder()
.address( "bob@example.com")
.createdAt(ZonedDateTime.now())
.build();
return suppressionComplaintsApi.addAddressToComplaintsList(YOUR_DOMAIN_NAME, complaintsSingleItemRequest);
}
# Include the Autoloader (see "Libraries" for install instructions)
require 'vendor/autoload.php';
use Mailgun\Mailgun;
# Instantiate the client.
$mgClient = Mailgun::create('PRIVATE_API_KEY', 'https://API_HOSTNAME');
$domain = 'YOUR_DOMAIN_NAME';
$recipient = 'bob@example.com';
# Issue the call to the client.
$result = $mgClient->suppressions()->complaints()->create($domain, $recipient);
def add_complaint():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints",
auth=("api", "YOUR_API_KEY"),
data={'address': 'bob@example.com'})
def add_complaint
RestClient.post "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/complaints",
:address => 'bob@example.com'
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class AddComplaintChunk
{
public static void Main (string[] args)
{
Console.WriteLine (AddComplaint ().Content.ToString ());
}
public static IRestResponse AddComplaint ()
{
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 = "{domain}/complaints";
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.AddParameter ("address", "bob@example.com");
request.Method = Method.POST;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func CreateComplaint(domain, apiKey string) error {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.CreateComplaint(ctx, "bob@example.com")
}
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 createdComplaint = await client.suppressions.create(DOMAIN, 'complaints', { address: 'bob@example.com' });
console.log('createdComplaint', createdComplaint);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"message": "Address has been added to the complaints table",
"address": "bob@example.com"
}
Add multiple complaints¶
POST /<domain>/complaints, Content-Type: application/json
Add multiple complaint records to the complaint list in a single API call.
Request body is expected to be a valid JSON encoded string containing up to 1000 complaint records in the following format.
[
{
"address": "alice@example.com",
"created_at": "Thu, 13 Oct 2011 18:02:00 UTC"
},
{
"address": "bob@example.com"
}
]
Fields within each individual complaint record are the same as for the “add a single unsubscribe” API method, with the same defaults and optionality rules.
Note
The current versions of our language libraries do not support adding multiple complaints yet.
Expected response:
200
{
"message": "2 complaint addresses have been added to the complaints table"
}
Import a list of complaints¶
POST /<domain>/complaints/import, Content-Type: multipart/form-data
Import a CSV file containing a list of addresses to add to the complaint list.
CSV file must be 25MB or under and must contain the following column headers: address,created_at
Column Description address Valid email address created_at Timestamp of a complaint event in RFC2822 format (optional, default: current time)
Expected response:
200
{
"message": "file uploaded successfully"
}
Delete a single complaint¶
DELETE /<domain>/complaints/<address>
Remove a given spam complaint.
Expected response:
200
{
"message": "Spam complaint has been removed"
}
Whitelists¶
The whitelist API provides the ability to whitelist specific addresses from being added to bounce list. You can whitelist by domain name (i.e example.com) or by specific address (i.e. alice@example.com). Mailgun doesn’t add an address to bounce list if the address is whitelisted. This API is very useful if you test against your private services and don’t want to constantly clean up bounce lists.
View all whitelist records¶
GET /<domain>/whitelists
Paginate over a whitelists for a domain.
Parameter | Description |
---|---|
limit | Number of records to return (optional, default: 100, max: 1000) |
Example:
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists
import com.mailgun.api.v3.suppression.MailgunSuppressionWhitelistsApi;
import com.mailgun.model.suppression.whitelists.WhitelistsItemResponse;
// ...
public WhitelistsItemResponse getBounces() {
MailgunSuppressionWhitelistsApi suppressionWhitelistsApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionWhitelistsApi.class);
return suppressionWhitelistsApi.getAllWhitelists(YOUR_DOMAIN_NAME);
}
# Currently, the PHP SDK does not support Suppression Whiteslist endpoint.
# Consider using the following php curl function.
function add_domain_whitelist() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'api:PRIVATE_API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($ch, CURLOPT_URL, 'https://api.mailgun.net/v3/domain.tld/whitelists');
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'address'=> 'bob@example.com')
);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
def get_whitelists():
return requests.get(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists",
auth=("api", "YOUR_API_KEY"))
def get_whitelists
RestClient.get "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetBouncesChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetBounces ().Content.ToString ());
}
public static IRestResponse GetBounces ()
{
RestClient client = new RestClient ();
client.BaseUrl = new Uri ("https://api.mailgun.net/v3");
client.Authenticator =
new HttpBasicAuthenticator ("api",
"YOUR_API_KEY");
RestRequest request = new RestRequest ();
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.Resource = "{domain}/whitelists";
return client.Execute (request);
}
}
// Not supported yet
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 whitelists = await client.suppressions.list(DOMAIN, 'whitelists');
console.log('whitelists', whitelists);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"items":
[
{
"value": "alice@example.com",
"reason": "reason of white listing"
"type": "address",
"createdAt": "Fri, 21 Oct 2011 11:02:55 UTC"
},
{
"value": "test.com",
"reason": "reason of white listing"
"type": "domain",
"createdAt": "Fri, 21 Oct 2012 11:02:56 UTC"
}
...
],
"paging":
{
"first": <first page URL>,
"next": <next page URL>,
"previous": <previous page URL>,
"last": <last page URL>
}
}
View a single whitelist record¶
GET /<domain>/whitelists/<address or domain>
Fetch a single whitelist record. Can be used to check if a given address or domain is present in the whitelist table
Expected responses:
200
{
"value": "alice@example.com",
"reason": "why the record was created"
"type": "address",
"createdAt": "Fri, 21 Oct 2011 11:02:55 GMT"
}
404
{
"message": "Address/Domain not found in whitelists table"
}
Add a single whitelist record¶
POST /<domain>/whitelists
Add an address or domain to the whitelist table.
Parameter | Description |
---|---|
address | Valid email address if you would like to whitelist email address |
domain | Valid domain name if you would like whitelist entire domain name |
Note
The single request accepts either one address or domain parameter
Example:
curl -s --user 'api:YOUR_API_KEY' \
https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists \
-F domain='example.com'
import com.mailgun.api.v3.suppression.MailgunSuppressionWhitelistsApi;
import com.mailgun.model.ResponseWithMessage;
import com.mailgun.model.suppression.whitelists.WhitelistsRequest;
// ...
public ResponseWithMessage addBounce() {
MailgunSuppressionWhitelistsApi suppressionWhitelistsApi = MailgunClient.config(API_KEY)
.createApi(MailgunSuppressionWhitelistsApi.class);
WhitelistsRequest whitelistsRequest = WhitelistsRequest.builder()
.address("bob@example.com")
.reason(REASON)
.build();
return suppressionWhitelistsApi.addSingleWhitelistRecord(YOUR_DOMAIN_NAME, whitelistsRequest);
}
# Currently, the PHP SDK does not support Suppression Whiteslist endpoint.
# Consider using the following php curl function.
function add_domain_whitelist() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, 'api:PRIVATE_API_KEY');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_URL, 'https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists');
curl_setopt($ch, CURLOPT_POSTFIELDS, array(
'address'=> 'bob@example.com')
);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
def add_whitelist():
return requests.post(
"https://api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists",
auth=("api", "YOUR_API_KEY"),
data={'address':'example.com'})
def add_whitelist
RestClient.post("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/YOUR_DOMAIN_NAME/whitelists",
:domain => 'example.com')
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class AddBounceChunk
{
public static void Main (string[] args)
{
Console.WriteLine (AddBounce ().Content.ToString ());
}
public static IRestResponse AddBounce ()
{
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 = "{domain}/whitelists";
request.AddParameter ("domain", "YOUR_DOMAIN_NAME", ParameterType.UrlSegment);
request.AddParameter ("domain", "example.com");
request.Method = Method.POST;
return client.Execute (request);
}
}
// Not implemented
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 createdWhitelist = await client.suppressions.create(DOMAIN, 'whitelists', { domain: 'example.com' });
console.log('createdWhitelist', createdWhitelist);
} catch (error) {
console.error(error);
}
})();
Expected response:
200
{
"message":"Address/Domain has been added to the whitelists table",
"type":"domain",
"value":"example.com"
}
Import a list of addresses and/or domains¶
POST /<domain>/whitelists/import, Content-Type: multipart/form-data
Import a CSV file containing a list of addresses and/or domains to add to the whitelist.
CSV file must be 25MB or under and must contain the following column headers: address,domain
Column Description address Valid email address if you would like to whitelist email address domain Valid domain name if you would like whitelist entire domain name
Expected response:
200
{
"message": "file uploaded successfully"
}
Delete a single record from whitelist table¶
DELETE /<domain>/whitelists/<address or domain>
Remove a given record from whitelist table.
Expected response:
200
{
"message":"Whitelist address/domain has been removed",
"value":"alice@example.com"
}