Bounces

Bounces

Mailgun automatically handles bounced emails. The bounced addresses, are collected in a bounces list and subsequent delivery attempts are ignored to protect your sending reputation.

Mailgun can notify your application every time a message bounces.

The list of bounced addresses can be accessed programmatically:

GET /<domain>/bounces

Fetches the list of bounces.

Parameter Description
limit Maximum number of records to return. (100 by default)
skip Number of records to skip. (0 by default)
GET /<domain>/bounces/<address>

Fetches a single bounce event by a given email address. This is useful to check if a given email address has bounced before.

DELETE /<domain>/bounces/<address>

“clears” a given bounce event.

POST /<domain>/bounces

Adds a permanent bounce to the bounces table. Updates the existing record if already here.

Parameter Description
address Valid email address
code Error code (default 550)
error Error description, (default is empty)

Examples

Fetch the full list of all recipient addresses that bounced:

def get_bounces
  RestClient.get "https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
  "@api.mailgun.net/v2/samples.mailgun.org/bounces"
end

Response JSON is shown below. Notice the following:

  • There was only one bounce
  • Both SMTP error code and SMTP error message are preserved
{
  "total_count": 4,
  "items": [
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:16:31 GMT",
      "error": "",
      "address": "ev@mgrules.com"
    },
    {
      "code": 550,
      "created_at": "Sun, 05 Feb 2012 21:36:26 GMT",
      "error": "5.1.1 <void@guillaumeleveque.info>: Recipient address rejected: User unknown in virtual mailbox table",
      "address": "void@guillaumeleveque.info"
    },
    {
      "code": 550,
      "created_at": "Mon, 09 Jan 2012 04:29:42 GMT",
      "error": "5.1.1 <mastronardif@gmail.net>: Recipient address rejected: User unknown in virtual alias table",
      "address": "mastronardif@gmail.net"
    },
    {
      "code": 550,
      "created_at": "Fri, 21 Oct 2011 11:02:55 GMT",
      "error": "Message was not accepted -- invalid mailbox.  Local mailbox 'serobnic@mail.ru is unavailable: user not found",
      "address": "'serobnic@mail.ru"
    }
  ]
}

Lets check if any messages sent to foo@bar.com have bounced before:

def check_address_for_bounces
  RestClient.get("https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
                 "@api.mailgun.net/v2/samples.mailgun.org/bounces"\
                 "/foo@bar.com"){|response, request, result| response }
end

Response:

{
  "message": "Address not found in bounces table"
}

Add a bounce to the table:

def add_bounce
  RestClient.post("https://api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0"\
                  "@api.mailgun.net/v2/samples.mailgun.org/bounces",
                  :address => 'ev@mgrules.com')
end

The response:

{
  "message": "Address has been added to the bounces table",
  "address": "ev@mgrules.com"
}

Fetch the full list of all recipient addresses that bounced:

public static ClientResponse GetBounces() {
       Client client = new Client();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org" +
                               "/bounces");
       return webResource.get(ClientResponse.class);
}

Response JSON is shown below. Notice the following:

  • There was only one bounce
  • Both SMTP error code and SMTP error message are preserved
{
  "total_count": 4,
  "items": [
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:29:13 GMT",
      "error": "",
      "address": "ev@mgrules.com"
    },
    {
      "code": 550,
      "created_at": "Sun, 05 Feb 2012 21:36:26 GMT",
      "error": "5.1.1 <void@guillaumeleveque.info>: Recipient address rejected: User unknown in virtual mailbox table",
      "address": "void@guillaumeleveque.info"
    },
    {
      "code": 550,
      "created_at": "Mon, 09 Jan 2012 04:29:42 GMT",
      "error": "5.1.1 <mastronardif@gmail.net>: Recipient address rejected: User unknown in virtual alias table",
      "address": "mastronardif@gmail.net"
    },
    {
      "code": 550,
      "created_at": "Fri, 21 Oct 2011 11:02:55 GMT",
      "error": "Message was not accepted -- invalid mailbox.  Local mailbox 'serobnic@mail.ru is unavailable: user not found",
      "address": "'serobnic@mail.ru"
    }
  ]
}

Lets check if any messages sent to foo@bar.com have bounced before:

public static ClientResponse CheckAddressForBounces() {
       Client client = new Client();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org/" +
                               "bounces/foo@bar.com");
       return webResource.get(ClientResponse.class);
}

Response:

{
  "message": "Address not found in bounces table"
}

Add a bounce to the table:

public static ClientResponse AddBounce() {
       Client client = new Client();
       client.addFilter(new HTTPBasicAuthFilter("api",
                       "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"));
       WebResource webResource =
               client.resource("https://api.mailgun.net/v2/samples.mailgun.org/" +
                               "bounces");
       MultivaluedMapImpl formData = new MultivaluedMapImpl();
       formData.add("address", "ev@mailgun.net");
       return webResource.type(MediaType.APPLICATION_FORM_URLENCODED).
               post(ClientResponse.class, formData);
}

The response:

{
  "message": "Address has been added to the bounces table",
  "address": "ev@mailgun.net"
}

Fetch the full list of all recipient addresses that bounced:

function get_bounces() {
  $request =
    new HttpRequest('https://api.mailgun.net/v2/samples.mailgun.org/bounces',
                    HttpRequest::METH_GET);
  $auth = base64_encode('api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
  $request->setHeaders(array('Authorization' => 'Basic '.$auth));
  $request->send();
  return $request;
}

Response JSON is shown below. Notice the following:

  • There was only one bounce
  • Both SMTP error code and SMTP error message are preserved
{
  "total_count": 5,
  "items": [
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:43:09 GMT",
      "error": "",
      "address": "ev@mailgun.net"
    },
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:29:13 GMT",
      "error": "",
      "address": "ev@mgrules.com"
    },
    {
      "code": 550,
      "created_at": "Sun, 05 Feb 2012 21:36:26 GMT",
      "error": "5.1.1 <void@guillaumeleveque.info>: Recipient address rejected: User unknown in virtual mailbox table",
      "address": "void@guillaumeleveque.info"
    },
    {
      "code": 550,
      "created_at": "Mon, 09 Jan 2012 04:29:42 GMT",
      "error": "5.1.1 <mastronardif@gmail.net>: Recipient address rejected: User unknown in virtual alias table",
      "address": "mastronardif@gmail.net"
    },
    {
      "code": 550,
      "created_at": "Fri, 21 Oct 2011 11:02:55 GMT",
      "error": "Message was not accepted -- invalid mailbox.  Local mailbox 'serobnic@mail.ru is unavailable: user not found",
      "address": "'serobnic@mail.ru"
    }
  ]
}

Lets check if any messages sent to foo@bar.com have bounced before:

function check_address_for_bounces() {
  $request =
    new HttpRequest('https://api.mailgun.net/v2/samples.mailgun.org/'
                    .'bounces/foo@bar.com',
                    HttpRequest::METH_GET);
  $auth = base64_encode('api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
  $request->setHeaders(array('Authorization' => 'Basic '.$auth));
  $request->send();
  return $request;
}

Response:

{
  "message": "Address not found in bounces table"
}

Add a bounce to the table:

function add_bounce() {
  $request =
    new HttpRequest('https://api.mailgun.net/v2/samples.mailgun.org/'
                    .'bounces',
                    HttpRequest::METH_POST);
  $auth = base64_encode('api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0');
  $request->setHeaders(array('Authorization' => 'Basic '.$auth));
  $request->setPostFields(array('address' => 'ev@mailgun.net'));
  $request->send();
  return $request;
}

The response:

{
  "message": "Address has been added to the bounces table",
  "address": "ev@mailgun.net"
}

Fetch the full list of all recipient addresses that bounced:

def get_bounces():
    r = requests.\
        get(("https://api.mailgun.net/v2/samples.mailgun.org/"
             "bounces"),
            auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"))
    return r

Response JSON is shown below. Notice the following:

  • There was only one bounce
  • Both SMTP error code and SMTP error message are preserved
{
  "total_count": 4,
  "items": [
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:13:39 GMT",
      "error": "",
      "address": "ev@mgrules.com"
    },
    {
      "code": 550,
      "created_at": "Sun, 05 Feb 2012 21:36:26 GMT",
      "error": "5.1.1 <void@guillaumeleveque.info>: Recipient address rejected: User unknown in virtual mailbox table",
      "address": "void@guillaumeleveque.info"
    },
    {
      "code": 550,
      "created_at": "Mon, 09 Jan 2012 04:29:42 GMT",
      "error": "5.1.1 <mastronardif@gmail.net>: Recipient address rejected: User unknown in virtual alias table",
      "address": "mastronardif@gmail.net"
    },
    {
      "code": 550,
      "created_at": "Fri, 21 Oct 2011 11:02:55 GMT",
      "error": "Message was not accepted -- invalid mailbox.  Local mailbox 'serobnic@mail.ru is unavailable: user not found",
      "address": "'serobnic@mail.ru"
    }
  ]
}

Lets check if any messages sent to foo@bar.com have bounced before:

def check_address_for_bounces():
    r = requests.\
        get(("https://api.mailgun.net/v2/samples.mailgun.org/"
             "bounces/foo@bar.com"),
            auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"))
    return r

Response:

{
  "message": "Address not found in bounces table"
}

Add a bounce to the table:

def add_bounce():
    r = requests.\
        post(("https://api.mailgun.net/v2/samples.mailgun.org/"
              "bounces"),
             auth=("api", "key-3ax6xnjp29jd6fds4gc373sgvjxteol0"),
             data={'address':'ev@mgrules.com'})
    return r

The response:

{
  "message": "Address has been added to the bounces table",
  "address": "ev@mgrules.com"
}

Fetch the full list of all recipient addresses that bounced:

public static RestResponse GetBounces() {

       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/bounces";
       return client.Execute(request);
}

Response JSON is shown below. Notice the following:

  • There was only one bounce
  • Both SMTP error code and SMTP error message are preserved
{
  "total_count": 5,
  "items": [
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:35:43 GMT",
      "error": "",
      "address": "ev@mailgun.net"
    },
    {
      "code": "550",
      "created_at": "Wed, 15 Feb 2012 11:29:13 GMT",
      "error": "",
      "address": "ev@mgrules.com"
    },
    {
      "code": 550,
      "created_at": "Sun, 05 Feb 2012 21:36:26 GMT",
      "error": "5.1.1 <void@guillaumeleveque.info>: Recipient address rejected: User unknown in virtual mailbox table",
      "address": "void@guillaumeleveque.info"
    },
    {
      "code": 550,
      "created_at": "Mon, 09 Jan 2012 04:29:42 GMT",
      "error": "5.1.1 <mastronardif@gmail.net>: Recipient address rejected: User unknown in virtual alias table",
      "address": "mastronardif@gmail.net"
    },
    {
      "code": 550,
      "created_at": "Fri, 21 Oct 2011 11:02:55 GMT",
      "error": "Message was not accepted -- invalid mailbox.  Local mailbox 'serobnic@mail.ru is unavailable: user not found",
      "address": "'serobnic@mail.ru"
    }
  ]
}

Lets check if any messages sent to foo@bar.com have bounced before:

public static RestResponse CheckAddressForBounces() {

       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.Resource = "{domain}/bounces/foo@bar.com";
       return client.Execute(request);
}

Response:

{
  "message": "Address not found in bounces table"
}

Add a bounce to the table:

public static RestResponse AddBounce() {

       RestClient client = new RestClient();
       client.BaseUrl = "https://api.mailgun.net/v2";
       client.Authenticator =
               new HttpBasicAuthenticator("api",
                                          "key-3ax6xnjp29jd6fds4gc373sgvjxteol0");
       RestRequest request = new RestRequest();
       request.Resource = "{domain}/bounces";
       request.AddParameter("domain",
                            "samples.mailgun.org", ParameterType.UrlSegment);
       request.AddParameter("address", "ev@mailgun.net");
       request.Method = Method.POST;
       return client.Execute(request);
}

The response:

{
  "message": "Address has been added to the bounces table",
  "address": "ev@mailgun.net"
}

Fetch the full list of all recipient addresses that bounced:

curl -s -k --user api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0 -G \
    https://api.mailgun.net/v2/samples.mailgun.org/bounces

Response JSON is shown below. Notice the following:

  • There was only one bounce
  • Both SMTP error code and SMTP error message are preserved
{
  "total_count": 5,
  "items": [
      {
          "created_at": "Wed, 15 Feb 2012 12:35:56 GMT",
          "code": "550",
          "address": "ev@mgrules.com",
          "error": ""
      },
      {
          "created_at": "Wed, 15 Feb 2012 12:30:17 GMT",
          "code": "550",
          "address": "ev@mailgun.net",
          "error": ""
      },
      {
          "created_at": "Sun, 05 Feb 2012 21:36:26 GMT",
          "code": 550,
          "address": "void@guillaumeleveque.info",
          "error": "5.1.1 <void@guillaumeleveque.info>: Recipient address rejected: User unknown in virtual mailbox table"
      },
      {
          "created_at": "Mon, 09 Jan 2012 04:29:42 GMT",
          "code": 550,
          "address": "mastronardif@gmail.net",
          "error": "5.1.1 <mastronardif@gmail.net>: Recipient address rejected: User unknown in virtual alias table"
      },
      {
          "created_at": "Fri, 21 Oct 2011 11:02:55 GMT",
          "code": 550,
          "address": "'serobnic@mail.ru",
          "error": "Message was not accepted -- invalid mailbox.  Local mailbox 'serobnic@mail.ru is unavailable: user not found"
      }
  ]
}

Lets check if any messages sent to foo@bar.com have bounced before:

curl -s -k --user api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0 -G \
    https://api.mailgun.net/v2/samples.mailgun.org/bounces/foo@bar.com

Response:

{
  "message": "Address not found in bounces table"
}

Add a bounce to the table:

curl -s -k --user api:key-3ax6xnjp29jd6fds4gc373sgvjxteol0 \
    https://api.mailgun.net/v2/samples.mailgun.org/bounces \
    -F address='ev@mgrules.com'

The response:

{
  "message": "Address has been added to the bounces table",
  "address": "ev@mgrules.com"
}