# Webhooks Calls

## Introduction

Instead of polling to get data, you can use our [Event API](/docs/email-api/webhooks/webhooks-overview/) for your system to be notified in near real-time when any event you've subscribed to happen.
The Mailjet resource involved here is `eventcallbackurl`, which lets you define a webhook per event type we support (including sent,open,click,bounce,blocked and spam).

## List

Info
Maps to /webhooks/list.json

PHP
```php
<?php
require 'vendor/autoload.php';
use \Mailjet\Resources;
$mj = new \Mailjet\Client(getenv('MJ_APIKEY_PUBLIC'), getenv('MJ_APIKEY_PRIVATE'));
$response = $mj->get(Resources::$Eventcallbackurl);
$response->success() && var_dump($response->getData());
?>
```

Bash
```bash
# View : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
curl -s \
	-X GET \
	--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
	https://api.mailjet.com/v3/REST/eventcallbackurl
```

Node.js
```javascript
/**
 *
 * View : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
 *
 */
var mailjet = require('node-mailjet').connect(
  process.env.MJ_APIKEY_PUBLIC,
  process.env.MJ_APIKEY_PRIVATE
)
var request = mailjet.get('eventcallbackurl').request()
request
  .on('success', function(response, body) {
    console.log(response.statusCode, body)
  })
  .on('error', function(err, response) {
    console.log(response.statusCode, err)
  })
```

Python
```python
"""
View : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
"""
from mailjet_rest import Client
import os
api_key = os.environ['MJ_APIKEY_PUBLIC']
api_secret = os.environ['MJ_APIKEY_PRIVATE']
mailjet = Client(auth=(api_key, api_secret))
result = mailjet.eventcallbackurl.get()
print result.status_code
print result.json()
```

Ruby
```ruby
# View : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
Mailjet.configure do |config|
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
  config.secret_key = ENV['MJ_APIKEY_PRIVATE']
  config.default_from = 'your default sending address'
end
variable = Mailjet::Eventcallbackurl.all()
```

Go
```go
/*
View : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
*/
package main
import (
	"fmt"
	. "github.com/mailjet/mailjet-apiv3-go"
	"github.com/mailjet/mailjet-apiv3-go/resources"
	"os"
)
func main () {
	mailjetClient := NewMailjetClient(os.Getenv("MJ_APIKEY_PUBLIC"), os.Getenv("MJ_APIKEY_PRIVATE"))
	var data []resources.Eventcallbackurl
	_, _, err := mailjetClient.List("eventcallbackurl", &data)
	if err != nil {
	  fmt.Println(err)
	}
	fmt.Printf("Data array: %+v\n", data)
}
```

Java
```java
package com.my.project;
import com.mailjet.client.errors.MailjetException;
import com.mailjet.client.MailjetClient;
import com.mailjet.client.MailjetRequest;
import com.mailjet.client.MailjetResponse;
import com.mailjet.client.resource.Eventcallbackurl;
public class MyClass {
    /**
     * View : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
     */
    public static void main(String[] args) throws MailjetException {
      MailjetClient client;
      MailjetRequest request;
      MailjetResponse response;
      client = new MailjetClient("api key", "api secret");
      request = new MailjetRequest(Eventcallbackurl.resource);
      response = client.get(request);
      System.out.println(response.getStatus());
      System.out.println(response.getData());
    }
}
```

```json
{
  "Count": 1,
  "Data": [
    {
      "APIKeyID": "",
      "EventType": "",
      "ID": "",
      "IsBackup": "false",
      "Status": "",
      "Url": "",
      "Version": ""
    }
  ],
  "Total": 1
}
```

Issue a `GET` request to `eventcallbackurl` to list all the resources for your current API key.

## Add

Info
Maps to /webhooks/add.json

PHP
```php
<?php
require 'vendor/autoload.php';
use \Mailjet\Resources;
$mj = new \Mailjet\Client(getenv('MJ_APIKEY_PUBLIC'), getenv('MJ_APIKEY_PRIVATE'));
$body = [
    'EventType' => "open",
    'Url' => "https://mydomain.com/event_handler"
];
$response = $mj->post(Resources::$Eventcallbackurl, ['body' => $body]);
$response->success() && var_dump($response->getData());
?>
```

Bash
```bash
# Create an handler for the open event
curl -s \
	-X POST \
	--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
	https://api.mailjet.com/v3/REST/eventcallbackurl \
	-H 'Content-Type: application/json' \
	-d '{
		"EventType":"open",
		"Url":"https://mydomain.com/event_handler"
	}'
```

Node.js
```javascript
/**
 *
 * Create an handler for the open event
 *
 */
var mailjet = require('node-mailjet').connect(
  process.env.MJ_APIKEY_PUBLIC,
  process.env.MJ_APIKEY_PRIVATE
)
var request = mailjet.post('eventcallbackurl').request({
  EventType: 'open',
  Url: 'https://mydomain.com/event_handler',
})
request
  .on('success', function(response, body) {
    console.log(response.statusCode, body)
  })
  .on('error', function(err, response) {
    console.log(response.statusCode, err)
  })
```

Ruby
```ruby
# Create an handler for the open event
Mailjet.configure do |config|
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
  config.secret_key = ENV['MJ_APIKEY_PRIVATE']
  config.default_from = 'your default sending address'
end
variable = Mailjet::Eventcallbackurl.create(event_type: "open",url: "https://mydomain.com/event_handler")
```

Python
```python
"""
Create an handler for the open event
"""
from mailjet_rest import Client
import os
api_key = os.environ['MJ_APIKEY_PUBLIC']
api_secret = os.environ['MJ_APIKEY_PRIVATE']
mailjet = Client(auth=(api_key, api_secret))
data = {
  'EventType': 'open',
  'Url': 'https://mydomain.com/event_handler'
}
result = mailjet.eventcallbackurl.create(data=data)
print result.status_code
print result.json()
```

Go
```go
/*
Create an handler for the open event
*/
package main
import (
	"fmt"
	. "github.com/mailjet/mailjet-apiv3-go"
	"github.com/mailjet/mailjet-apiv3-go/resources"
	"os"
)
func main () {
	mailjetClient := NewMailjetClient(os.Getenv("MJ_APIKEY_PUBLIC"), os.Getenv("MJ_APIKEY_PRIVATE"))
	var data []resources.Eventcallbackurl
	mr := &MailjetRequest{
	  Resource: "eventcallbackurl",
	}
	fmr := &FullMailjetRequest{
	  Info: mr,
	  Payload: &resources.Eventcallbackurl {
      EventType: "open",
      Url: "https://mydomain.com/event_handler",
    },
	}
	err := mailjetClient.Post(fmr, &data)
	if err != nil {
	  fmt.Println(err)
	}
	fmt.Printf("Data array: %+v\n", data)
}
```

Java
```java
package com.my.project;
import com.mailjet.client.errors.MailjetException;
import com.mailjet.client.MailjetClient;
import com.mailjet.client.MailjetRequest;
import com.mailjet.client.MailjetResponse;
import com.mailjet.client.resource.Eventcallbackurl;
public class MyClass {
    /**
     * Create an handler for the open event
     */
    public static void main(String[] args) throws MailjetException {
      MailjetClient client;
      MailjetRequest request;
      MailjetResponse response;
      client = new MailjetClient("api key", "api secret");
      request = new MailjetRequest(Eventcallbackurl.resource)
						.property(Eventcallbackurl.EVENTTYPE, "open")
						.property(Eventcallbackurl.URL, "https://mydomain.com/event_handler");
      response = client.post(request);
      System.out.println(response.getStatus());
      System.out.println(response.getData());
    }
}
```

```json
{
  "Count": 1,
  "Data": [
    {
      "APIKey": "",
      "EventType": "",
      "ID": "",
      "IsBackup": "false",
      "Status": "",
      "Url": "",
      "Version": ""
    }
  ],
  "Total": 1
}
```

Issue a `POST` request to `eventcallbackurl` to create a new event subscriber.

## Info

Info
Maps to /webhooks/add.json

Issue a `GET` request to `eventcallbackurl` with the ID or the event type to list it. See #List above.

## Update

Info
Maps to /webhooks/update.json

PHP
```php
<?php
require 'vendor/autoload.php';
use \Mailjet\Resources;
$mj = new \Mailjet\Client(getenv('MJ_APIKEY_PUBLIC'), getenv('MJ_APIKEY_PRIVATE'));
$body = [
    'APIKeyID' => "",
    'IsBackup' => "false",
    'Status' => "",
    'Url' => "",
    'Version' => ""
];
$response = $mj->put(Resources::$Eventcallbackurl, ['id' => $id, 'body' => $body]);
$response->success() && var_dump($response->getData());
?>
```

Bash
```bash
# Modify : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
curl -s \
	-X PUT \
	--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
	https://api.mailjet.com/v3/REST/eventcallbackurl/$ID \
	-H 'Content-Type: application/json' \
	-d '{
		"APIKeyID":"",
		"IsBackup":"false",
		"Status":"",
		"Url":"",
		"Version":""
	}'
```

Node.js
```javascript
/**
 *
 * Modify : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
 *
 */
var mailjet = require('node-mailjet').connect(
  process.env.MJ_APIKEY_PUBLIC,
  process.env.MJ_APIKEY_PRIVATE
)
var request = mailjet
  .put('eventcallbackurl')
  .id($ID)
  .request({
    APIKeyID: '',
    IsBackup: 'false',
    Status: '',
    Url: '',
    Version: '',
  })
request
  .on('success', function(response, body) {
    console.log(response.statusCode, body)
  })
  .on('error', function(err, response) {
    console.log(response.statusCode, err)
  })
```

Ruby
```ruby
# Modify : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
Mailjet.configure do |config|
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
  config.secret_key = ENV['MJ_APIKEY_PRIVATE']
  config.default_from = 'your default sending address'
end
target = Mailjet::Eventcallbackurl.find($ID)
target.update_attributes(apikey_id: "",is_backup: "false",status: "",url: "",version: "")
```

Python
```python
"""
Modify : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
"""
from mailjet_rest import Client
import os
api_key = os.environ['MJ_APIKEY_PUBLIC']
api_secret = os.environ['MJ_APIKEY_PRIVATE']
mailjet = Client(auth=(api_key, api_secret))
id = '$ID'
data = {
  'APIKeyID': '',
  'IsBackup': 'false',
  'Status': '',
  'Url': '',
  'Version': ''
}
result = mailjet.eventcallbackurl.update(id=id, data=data)
print result.status_code
print result.json()
```

Go
```go
/*
Modify : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
*/
package main
import (
	"fmt"
	. "github.com/mailjet/mailjet-apiv3-go"
	"github.com/mailjet/mailjet-apiv3-go/resources"
	"os"
)
func main () {
	mailjetClient := NewMailjetClient(os.Getenv("MJ_APIKEY_PUBLIC"), os.Getenv("MJ_APIKEY_PRIVATE"))
	mr := &MailjetRequest{
	  Resource: "eventcallbackurl",
	  ID: RESOURCE_ID,
	}
	fmr := &FullMailjetRequest{
	  Info: mr,
	  Payload: &resources.Eventcallbackurl {
      APIKeyID: ,
      IsBackup: "false",
      Status: ,
      Url: ,
      Version: ,
    },
	}
	err := mailjetClient.Put(fmr)
	if err != nil {
	  fmt.Println(err)
	}
}
```

Java
```java
package com.my.project;
import com.mailjet.client.errors.MailjetException;
import com.mailjet.client.MailjetClient;
import com.mailjet.client.MailjetRequest;
import com.mailjet.client.MailjetResponse;
import com.mailjet.client.resource.Eventcallbackurl;
public class MyClass {
    /**
     * Modify : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
     */
    public static void main(String[] args) throws MailjetException {
      MailjetClient client;
      MailjetRequest request;
      MailjetResponse response;
      client = new MailjetClient("api key", "api secret");
      request = new MailjetRequest(Eventcallbackurl.resource, ID)
						.property(Eventcallbackurl.APIKEYID, )
						.property(Eventcallbackurl.ISBACKUP, "false")
						.property(Eventcallbackurl.STATUS, )
						.property(Eventcallbackurl.URL, )
						.property(Eventcallbackurl.VERSION, );
      response = client.put(request);
      System.out.println(response.getStatus());
      System.out.println(response.getData());
    }
}
```

```json
{
  "Count": 1,
  "Data": [
    {
      "APIKeyID": "",
      "EventType": "",
      "ID": "",
      "IsBackup": "false",
      "Status": "",
      "Url": "",
      "Version": ""
    }
  ],
  "Total": 1
}
```

Issue a `PUT` request to `eventcallbackurl` with the ID to update

## Delete

Info
Maps to /webhooks/delete.json

PHP
```php
<?php
require 'vendor/autoload.php';
use \Mailjet\Resources;
$mj = new \Mailjet\Client(getenv('MJ_APIKEY_PUBLIC'), getenv('MJ_APIKEY_PRIVATE'));
$response = $mj->delete(Resources::$Eventcallbackurl, ['id' => $id]);
$response->success() && var_dump($response->getData());
?>
```

Bash
```bash
# Delete : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
curl -s \
	-X DELETE \
	--user "$MJ_APIKEY_PUBLIC:$MJ_APIKEY_PRIVATE" \
	https://api.mailjet.com/v3/REST/eventcallbackurl/$ID \
	-H 'Content-Type: application/json' \
	-d '{
	}'
```

Node.js
```javascript
/**
 *
 * Delete : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
 *
 */
var mailjet = require('node-mailjet').connect(
  process.env.MJ_APIKEY_PUBLIC,
  process.env.MJ_APIKEY_PRIVATE
)
var request = mailjet
  .delete('eventcallbackurl')
  .id($ID)
  .request()
request
  .on('success', function(response, body) {
    console.log(response.statusCode, body)
  })
  .on('error', function(err, response) {
    console.log(response.statusCode, err)
  })
```

Ruby
```ruby
# Delete : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
Mailjet.configure do |config|
  config.api_key = ENV['MJ_APIKEY_PUBLIC']
  config.secret_key = ENV['MJ_APIKEY_PRIVATE']
  config.default_from = 'your default sending address'
end
target = Mailjet::Eventcallbackurl.find($ID)
target.delete()
```

Python
```python
"""
Delete : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
"""
from mailjet_rest import Client
import os
api_key = os.environ['MJ_APIKEY_PUBLIC']
api_secret = os.environ['MJ_APIKEY_PRIVATE']
mailjet = Client(auth=(api_key, api_secret))
id = '$ID'
result = mailjet.eventcallbackurl.delete(id=id)
print result.status_code
print result.json()
```

Go
```go
/*
Delete : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
*/
package main
import (
	"fmt"
	. "github.com/mailjet/mailjet-apiv3-go"
	"github.com/mailjet/mailjet-apiv3-go/resources"
	"os"
)
func main () {
	mailjetClient := NewMailjetClient(os.Getenv("MJ_APIKEY_PUBLIC"), os.Getenv("MJ_APIKEY_PRIVATE"))
	mr := &MailjetRequest{
	  Resource: "eventcallbackurl",
	  ID: RESOURCE_ID,
	}
	err := mailjetClient.Delete(mr)
	if err != nil {
	  fmt.Println(err)
	}
}
```

Java
```java
package com.my.project;
import com.mailjet.client.errors.MailjetException;
import com.mailjet.client.MailjetClient;
import com.mailjet.client.MailjetRequest;
import com.mailjet.client.MailjetResponse;
import com.mailjet.client.resource.Eventcallbackurl;
public class MyClass {
    /**
     * Delete : Manage event-driven callback URLs, also called webhooks, used by the Mailjet platform when a specific action is triggered
     */
    public static void main(String[] args) throws MailjetException {
      MailjetClient client;
      MailjetRequest request;
      MailjetResponse response;
      client = new MailjetClient("api key", "api secret");
      request = new MailjetRequest(Eventcallbackurl.resource, ID);
      response = client.delete(request);
      System.out.println(response.getStatus());
      System.out.println(response.getData());
    }
}
```

```json
{
  "Count": 1,
  "Data": [
    {
      "APIKeyID": "",
      "EventType": "",
      "ID": "",
      "IsBackup": "false",
      "Status": "",
      "Url": "",
      "Version": ""
    }
  ],
  "Total": 1
}
```

Issue a `PUT` request to `eventcallbackurl` with the ID to delete

## Events content sample

All JSON event objects contain the following properties:

- event : the event type
- time : unix timestamp of event
- email : email address of recipient triggering the event
- mj_campaign_id : internal Mailjet campaign ID associated to the message
- mj_contact_id : internal Mailjet contact ID
- customcampaign : value of the X-Mailjet-Campaign header when provided
- MessageID : The unique message ID
- CustomID: the custom ID, when provided at send time
- Payload: the event payload, when provided at send time


###Sent event

**Sample sent event**

```json
{
  "event": "sent",
  "time": 1433333949,
  "MessageID": 19421777835146490,
  "email": "api@mailjet.com",
  "mj_campaign_id": 7257,
  "mj_contact_id": 4,
  "customcampaign": "",
  "mj_message_id": "19421777835146490",
  "smtp_reply": "sent (250 2.0.0 OK 1433333948 fa5si855896wjc.199 - gsmtp)",
  "CustomID": "helloworld",
  "Payload": ""
}
```

Dispatched when the destination SMTP server (gmail, hotmail, yahoo, etc) has accepted the message. Depending on your volume, it could dispatch a lot of events to your system. Please make sure you have checked the Group Events Checkbox in the [Event API user interface](https://app.mailjet.com/account/triggers) or that the [`/eventcallbackurl`](/docs/api-reference/email-api/categories/webhook/) `Version` property is set to `2`.

Sent event additional properties:

- mj_message_id : The unique message ID as a string (deprecated, see MessageID)
- smtp_reply: The raw SMTP response message


###Open event

**Sample open event**

```json
{
  "event": "open",
  "time": 1433103519,
  "MessageID": 19421777396190490,
  "email": "api@mailjet.com",
  "mj_campaign_id": 7173,
  "mj_contact_id": 320,
  "customcampaign": "",
  "CustomID": "helloworld",
  "Payload": "",
  "ip": "127.0.0.1",
  "geo": "US",
  "agent": "Mozilla/5.0 (Windows NT 5.1; rv:11.0) Gecko Firefox/11.0"
}
```

Open event additional properties:

- ip : IP address (can be IPv4 or IPv6) that triggered the event
- geo : country code of IP address (see [list](http://www.maxmind.com/app/iso3166))
- agent : User-Agent


###Click event

**Sample click event**

```json
{
  "event": "click",
  "time": 1433334653,
  "MessageID": 19421777836302490,
  "email": "api@mailjet.com",
  "mj_campaign_id": 7272,
  "mj_contact_id": 4,
  "customcampaign": "",
  "CustomID": "helloworld",
  "Payload": "",
  "url": "https://mailjet.com",
  "ip": "127.0.0.1",
  "geo": "FR",
  "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36"
}
```

Click event additional properties:

- url : the link that was clicked


###Bounce event

**Sample bounce event**

```json
{
  "event": "bounce",
  "time": 1430812195,
  "MessageID": 13792286917004336,
  "email": "bounce@mailjet.com",
  "mj_campaign_id": 0,
  "mj_contact_id": 0,
  "customcampaign": "",
  "CustomID": "helloworld",
  "Payload": "",
  "blocked": true,
  "hard_bounce": true,
  "error_related_to": "recipient",
  "error": "user unknown"
}
```

Bounce event additional properties:

- blocked : true if this bounce leads to the recipient being blocked
- hard_bounce : true if error was permanent
- error_related_to : see error table
- error : see [error table](/docs/email-api/webhooks/webhooks-overview/#possible-values-for-errors)


###Blocked event

**Sample blocked event**

```json
{
  "event": "blocked",
  "time": 1430812195,
  "MessageID": 13792286917004336,
  "email": "bounce@mailjet.com",
  "mj_campaign_id": 0,
  "mj_contact_id": 0,
  "customcampaign": "",
  "CustomID": "helloworld",
  "Payload": "",
  "error_related_to": "recipient",
  "error": "user unknown"
}
```

Blocked event additional properties:

- error_related_to : see error table
- error : see [error table](/docs/email-api/webhooks/webhooks-overview/#possible-values-for-errors)


###Spam event

**Sample spam event**

```json
{
  "event": "spam",
  "time": 1430812195,
  "MessageID": 13792286917004336,
  "email": "bounce@mailjet.com",
  "mj_campaign_id": 0,
  "mj_contact_id": 0,
  "customcampaign": "",
  "CustomID": "helloworld",
  "Payload": "",
  "source": "JMRPP"
}
```

Spam event additional properties:

- source : indicates which feedback loop program reported this complaint


###Unsub event

**Sample unsub event**

```json
{
  "event": "unsub",
  "time": 1433334941,
  "MessageID": 20547674933128000,
  "email": "api@mailjet.com",
  "mj_campaign_id": 7276,
  "mj_contact_id": 126,
  "customcampaign": "",
  "CustomID": "helloworld",
  "Payload": "",
  "mj_list_id": 1,
  "ip": "127.0.0.1",
  "geo": "FR",
  "agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/42.0.2311.135 Safari/537.36"
}
```

Unsub event additional properties:

- mj_list_id : internal Mailjet List id for REST API access to lists management
- ip : IP address (can be IPv4 or IPv6) that triggered the event
- geo : country code of IP address (see [list](http://www.maxmind.com/app/iso3166))
- agent : User-Agent