Webhooks¶
This API allows you to create, access, and delete webhooks programmatically.
The webhooks API endpoint is available at:
v3/domains/<domain>/webhooks
Supported webhooks, and their documentation, are listed below:
Webhook Name | Documentation |
---|---|
accepted | Tracking Accepted |
clicked | Tracking Clicks |
complained | Tracking Spam Complaints |
delivered | Tracking Deliveries |
opened | Tracking Opens |
permanent_fail | Tracking Failures |
temporary_fail | Tracking Failures |
unsubscribed | Open and Click Bot Detection |
GET /domains/<domain>/webhooks
Returns a list of webhooks set for the specified domain.
Parameter | Description |
---|---|
domain | Name of the domain |
GET /domains/<domain>/webhooks/<webhookname>
Returns details about a the webhook specified in the URL.
Parameter | Description |
---|---|
domain | Name of the domain |
id | Name of the webhook. (See above for supported webhooks) |
POST /domains/<domain>/webhooks
Creates a new webhook.
Note
When adding a Clicked or Opened webhook, ensure that you also have tracking enabled.
Parameter | Description |
---|---|
domain | Name of the domain |
id | Name of the webhook. (See above for supported webhooks) |
url | URL for the webhook event. May be repeated up to 3 times. |
PUT /domains/<domain>/webhooks/<webhookname>
Updates an existing webhook.
Parameter | Description |
---|---|
domain | Name of the domain |
webhookname | Name of the webhook. (See above for supported webhooks) |
url | URL for the webhook event. May be repeated up to 3 times. |
DELETE /domains/<domain>/webhooks/<webhookname>
Deletes an existing webhook.
Note
Mailgun imposes a rate limit for the Webhook API endpoint. Users may issue no more than 300 requests per minute, per account. See the resultant rate limit response below.
Parameter | Description |
---|---|
domain | Name of the domain |
webhookname | Name of the webhook. (See above for supported webhooks) |
Examples¶
Return a list of webhooks set for the specified domain.
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks
import com.mailgun.api.v3.MailgunWebhooksApi;
import com.mailgun.model.webhooks.WebhookListResult;;
// ...
public WebhookListResult getWebhooks() {
MailgunWebhooksApi mailgunWebhooksApi = MailgunClient.config(API_KEY).createApi(MailgunWebhooksApi.class);
return mailgunWebhooksApi.getAllWebhooks(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->webhooks()->index($domain)
def get_bounces():
return requests.get(
"https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks",
auth=("api", "YOUR_API_KEY"))
def get_webhooks
RestClient.get "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetWebhooksChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetWebhooks ().Content.ToString ());
}
public static IRestResponse GetWebhooks ()
{
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 = "domains/{domain}/webhooks";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func ListWebhooks(domain, apiKey string) (map[string]string, error) {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.ListWebhooks(ctx)
}
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 webhooks = await client.webhooks.list(DOMAIN);
console.log('webhooks', webhooks);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"webhooks": {
"opened": {
"urls": [
"https://your_domain.com/v1/opened",
"https://your_domain.com/v2/opened"
]
},
"clicked": {
"urls": [ "https://your_domain.com/v1/clicked" ]
}
}
}
Return a webhook for a specific event for the defined domain.
curl -s --user 'api:YOUR_API_KEY' -G \
https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked
import com.mailgun.api.v3.MailgunWebhooksApi;
import com.mailgun.enums.WebhookName;
import com.mailgun.model.webhooks.WebhookDetailsResult;
// ...
public WebhookDetailsResult getWebhookEvent() {
MailgunWebhooksApi mailgunWebhooksApi = MailgunClient.config(API_KEY).createApi(MailgunWebhooksApi.class);
return mailgunWebhooksApi.getWebhookDetails(YOUR_DOMAIN_NAME, WebhookName.CLICKED);
}
# 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';
$webhook = 'delivered';
# Issue the call to the client.
$result = $mgClient->webhooks()->show($domain, $webhook)
def get_domain():
return requests.get(
"https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked",
auth=("api", "YOUR_API_KEY"))
def get_domain
RestClient.get("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked"\
{|response, request, result| response }
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class GetWebhookChunk
{
public static void Main (string[] args)
{
Console.WriteLine (GetWebhook ().Content.ToString ());
}
public static IRestResponse GetWebhook ()
{
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 = "/domains/{domain}/webhooks/clicked";
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func GetWebhook(domain, apiKey string) (string, error) {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.GetWebhook(ctx, "clicked")
}
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 webhooks = await client.webhooks.get(DOMAIN,'delivered');
console.log('webhooks', webhooks);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"webhook": {
"urls": [ "https://your_domain.com/v1/clicked" ]
}
}
Create a new webhook.
curl -s --user 'api:YOUR_API_KEY' -X POST \
https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks \
-F id='clicked' \
-F url='https://your_domain.com/v1/clicked' \
-F url='https://your_domain.com/v2/clicked' \
-F url='https://your_partner_domain.com/v1/clicked'
import com.mailgun.api.v3.MailgunWebhooksApi;
import com.mailgun.enums.WebhookName;
import com.mailgun.model.webhooks.WebhookRequest;
import com.mailgun.model.webhooks.WebhookResult;
import java.util.List;
// ...
public WebhookResult addWebhook() {
MailgunWebhooksApi mailgunWebhooksApi = MailgunClient.config(API_KEY).createApi(MailgunWebhooksApi.class);
WebhookRequest request = WebhookRequest.builder()
.webhookName(WebhookName.CLICKED)
.url("https://your_domain.com/v1/clicked")
.urls(List.of("https://your_domain.com/v2/clicked", "https://your_partner_domain.com/v1/clicked"))
.build();
return mailgunWebhooksApi.createNewWebhook(YOUR_DOMAIN_NAME, request);
}
# 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';
$webhook = 'delivered';
$destination_url = 'https://my.webhook.url/delivered'
# Issue the call to the client.
$result = $mgClient->webhooks()->create($domain, $webhook, $destination_url);
def add_webhook():
return requests.post(
"https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks",
auth=("api", "YOUR_API_KEY"),
data={
'id':'clicked',
'url':[ 'https://your_domain.com/v1/clicked',
'https://your_domain.com/v2/clicked',
'https://your_partner_domain.com/v1/clicked'
]
})
def add_webhook
RestClient.post("https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks",
:id => 'clicked',
:url => ['https://your_domain.com/v1/clicked',
'https://your_domain.com/v2/clicked',
'https://your_partner_domain.com/v1/clicked'])
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class AddWebhookChunk
{
public static void Main (string[] args)
{
Console.WriteLine (AddWebhook ().Content.ToString ());
}
public static IRestResponse AddWebhook ()
{
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 = "domains/YOUR_DOMAIN_NAME/webhooks";
request.AddParameter ("id", "clicked");
request.AddParameter ("url", "https://your_domain.com/v1/clicked")
request.AddParameter ("url", "https://your_domain.com/v2/clicked")
request.AddParameter ("url", "https://your_partner_domain.com/v1/clicked")
request.Method = Method.POST;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func CreateWebhook(domain, apiKey string) error {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.CreateWebhook(ctx, "clicked", []string{"https://your_domain.com/v1/clicked"})
}
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 {
// clicked or one of the Supported webhooks
const createdWebhook = await client.webhooks.create(DOMAIN, 'clicked', 'https://your_domain.com/v1/clicked');
console.log('createdWebhook', createdWebhook);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"message": "Webhook has been created",
"webhook": {
"urls": [
"https://your_domain.com/v1/clicked",
"https://your_domain.com/v2/clicked",
"https://your_partner_domain.com/v1/clicked"
]
}
}
Update an existing webhook.
curl -s --user 'api:YOUR_API_KEY' -X PUT \
https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked \
-F url='https://your_domain,com/v1/clicked'
import com.mailgun.api.v3.MailgunWebhooksApi;
import com.mailgun.enums.WebhookName;
import com.mailgun.model.webhooks.WebhookResult;
import com.mailgun.model.webhooks.WebhookUpdateRequest;
// ...
public WebhookResult updateWebhook() {
MailgunWebhooksApi mailgunWebhooksApi = MailgunClient.config(API_KEY)
.createApi(MailgunWebhooksApi.class);
WebhookUpdateRequest request = WebhookUpdateRequest.builder()
.url("https://your_domain.com/clicked")
.build();
return mailgunWebhooksApi.updateWebhook(YOUR_DOMAIN_NAME, WebhookName.CLICKED, request);
}
# 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';
$webhook = 'delivered';
$destination_url = 'https://my.webhook.url/delivered'
# Issue the call to the client.
$result = $mgClient->webhooks()->update($domain, $webhook, $destination_url);
def update_webhook():
return requests.put(
("https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked"),
auth=('api', 'YOUR_API_KEY'),
data={'url': 'https://your_domain.com/clicked'})
def update_webhook
RestClient.put("https://api:YOUR_API_KEY" \
"@api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked",
:url => 'https://your_domain.com/clicked')
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class UpdateWebhookChunk
{
public static void Main (string[] args)
{
Console.WriteLine (UpdateWebhook ().Content.ToString ());
}
public static IRestResponse UpdateWebhook ()
{
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 = "/domains/YOUR_DOMAIN_NAME/webhooks/clicked";
request.AddParameter ("url", "https://your_domain.com/clicked");
request.Method = Method.PUT;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func UpdateWebhook(domain, apiKey string) error {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.UpdateWebhook(ctx, "clicked", []string{"https://your_domain.com/clicked"})
}
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 updatedWebhooks = await client.webhooks.update(DOMAIN, 'clicked', 'https://your_domain.com/v1/clicked');
console.log('updatedWebhooks', updatedWebhooks);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"message": "Webhook has been updated",
"webhook": {
"urls": [ "https://your_domain.com/v1/clicked" ]
}
}
Delete a webhook.
curl -s --user 'api:YOUR_API_KEY' -X DELETE \
https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked
import com.mailgun.api.v3.MailgunWebhooksApi;
import com.mailgun.enums.WebhookName;
import com.mailgun.model.webhooks.WebhookResult;
// ...
public WebhookResult deleteWebhook() {
MailgunWebhooksApi mailgunWebhooksApi = MailgunClient.config(API_KEY).createApi(MailgunWebhooksApi.class);
return mailgunWebhooksApi.deleteWebhook(YOUR_DOMAIN_NAME, WebhookName.CLICKED);
}
# 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';
$webhook = 'delivered';
# Issue the call to the client.
$result = $mgClient->webhooks()->delete($domain, $webhook);
def delete_domain():
return requests.delete(
"https://api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked",
auth=("api", "YOUR_API_KEY"))
def delete_domain
RestClient.delete "https://api:YOUR_API_KEY"\
"@api.mailgun.net/v3/domains/YOUR_DOMAIN_NAME/webhooks/clicked"
end
using System;
using System.IO;
using RestSharp;
using RestSharp.Authenticators;
public class DeleteWebhookChunk
{
public static void Main (string[] args)
{
Console.WriteLine (DeleteWebhook ().Content.ToString ());
}
public static IRestResponse DeleteWebhook ()
{
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 = "/domains/{name}/webhooks/clicked";
request.AddUrlSegment ("name", "YOUR_DOMAIN_NAME");
request.Method = Method.DELETE;
return client.Execute (request);
}
}
import (
"context"
"github.com/mailgun/mailgun-go/v3"
"time"
)
func DeleteWebhook(domain, apiKey string) error {
mg := mailgun.NewMailgun(domain, apiKey)
ctx, cancel := context.WithTimeout(context.Background(), time.Second*30)
defer cancel()
return mg.DeleteWebhook(ctx, "clicked")
}
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 deletedWebhook = await client.webhooks.destroy(DOMAIN, 'clicked');
console.log('deletedWebhook', deletedWebhook);
} catch (error) {
console.error(error);
}
})();
Sample response:
{
"message": "Webhook has been deleted",
"webhook": {
"urls": [
"https://your_domain.com/v1/clicked",
"https://your_domain.com/v2/clicked",
"https://your_partner_domain.com/v1/clicked"
]
}
}
Rate Limit Response:
{
"retry-seconds": 60,
}