MailChimp Webhooks API – both PHP and WordPress integrations

Creating a Webhook

How to create a webhook url on your server?

Before creating a webhook, you should know one thing – the URL of the webhook must exist on your server and accept GET parameters.

It could be a separate PHP file or if you’re working with WordPress, you can process webhooks in your functions.php file. Example – if your webhook URL on a WordPress website looks like this: https://your-website.com/?process-webhook=1, you can process it in functions.php with the code below:


add_action( 'init', 'misha_process_webhook');

function misha_process_webhook(){
	if( isset( $_GET['process-webhook'] ) && $_GET['process-webhook'] == 1 ) {
		// do some stuff
		// you can send $_POST params by email to debug it for example
	}
}

If you are not working with WordPress at this moment, just create a custom .php file on your server. Once this step is done, let’s continue to creating a webhook.

There are two ways to do it.

Way 1. Directly from your MailChimp account

The easiest one, but not always convenient. In your MailChimp account go to Lists and select one. Open the Settings dropdown menu and go to Webhooks.

Webhooks settings page in your MailChimp account dashboard
As you can understand by this moment, each email list has its own webhooks.

Click the Create New Webhook button and the following page should appear:

Create a new MailChimp webhook and configure it in dashboard

Way 2. With the API

But when you’re working with the client websites or creating a custom plugin, it is not always convenient to request the MailChimp account access or to ask clients to make all the changes above.

That’s why sometimes you have to create webhooks with the MailChimp API. And you can do it!

In all the code listings below you will need two variables:

[tabs]


$api_key = '';
$list_id = '';

$response = wp_remote_post( 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/', array(
	'method' => 'POST',
	'headers' => array(
		'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
	),
	'body' => json_encode(array(
		'url' => 'https://your-website.com/?process-webhook=1',
		'events' => array(
			'subscribe' => true,  // when someone subscribes to a list
			'unsubscribe' => false, // when someone unsubscribes from a list
			'profile' => true, // subscriber's profile is updated
			'cleaned' => false, // subscriber's status is cleaned
			//'upemail' => false, // subscriber's email address is changed
			//'campaign' => false // campaign is sent or cancelled
		),
		'sources' => array(
			'user' => true, // changes are initiated by subscriber himself
			'admin' => true, // admin-initiated actions in MailChimp dashboard
			'api' => false // changes made via API
		)
	))
));

$response_body = json_decode( wp_remote_retrieve_body( $response ) );

$api_key = '';
$list_id = '';

$connection = curl_init();

curl_setopt_array($connection, array( // PHP 5.1.3+
	CURLOPT_URL => 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/',
	CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: Basic '.base64_encode( 'user:'.$api_key )),
	CURLOPT_RETURNTRANSFER => true,
	CURLOPT_CUSTOMREQUEST => 'POST',
	CURLOPT_POST => true,
	CURLOPT_POSTFIELDS => json_encode(array(
		'url' => 'https://your-website.com/?process-webhook=1',
		'events' => array(
			'subscribe' => true,
			'unsubscribe' => false,
			'profile' => true,
			'cleaned' => false,
			//'upemail' => false,
			//'campaign' => false
		),
		'sources' => array(
			'user' => true,
			'admin' => true,
			'api' => false
		)
	))
));

$response_body = json_decode( curl_exec( $connection ) );

curl_close( $connection );

Response parameters:

id
Webhook ID
url
Webhook URL
events
An object with boolean values for each event, example $response_body->events->subscribe is true.
sources
An object with boolean values for each source, example $response_body->sources->api is false.
list_id
MailChimp list ID the webhook has been created for.

Processing webhooks on your server

As I said before, once a specific action is fired on your MailChimp account (somebody has been subscribed or unsubscribed or changed his email etc), MailChimp will send a POST-request to a webhook URL on your website.

Depending on the event, the $_POST-data will be different, you can print_r( $_POST, true ) the webhook data and send it to yourself by email or store somewhere on your website (like I did) or you can also view the MailChimp documentation, where each event parameter is described, here.

Example


$event_type = $_POST['type'];
switch( $event_type ) :
	case 'subscribe':
		$message = $_POST['data']['email'] . 'is subscribed to the list' . $_POST['data']['list_id'];
	break;
	case 'upemail':
		$message = 'Somebody changed his email from ' . $_POST['data']['old_email'] . ' to ' . $_POST['data']['new_email'];
	break;
endswitch;

I’m gonna publish more specific examples in a separate tutorial within the next week.

Get webhooks

Get all webhooks from a specific email list

[tabs]


$api_key = '';
$list_id = '';

$response = wp_remote_get( 'https://'.substr($api_key,strpos($api_key,'-')+1).'.api.mailchimp.com/3.0/lists/'.$list_id.'/webhooks/', array(
 	'headers' => array(
		'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
	)
) );

$response_body = json_decode( wp_remote_retrieve_body( $response ) );

$api_key = '';
$list_id = '';

$connection = curl_init();

curl_setopt_array($connection, array(
	CURLOPT_URL => 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/',
	CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: Basic '.base64_encode( 'user:'.$api_key )),
	CURLOPT_RETURNTRANSFER => true
));

$response_body = json_decode( curl_exec( $connection ) );

Response parameters:

webhooks
Array of webhook objects. Usage example – print the webhooks URLs:


foreach( $response_body->webhooks as $webhook ) {
	echo $webhook->url . '
'; }

Objects have the same id, url, events, sources and list_id properties.

list_id
The list ID we are getting the webhooks from.
total_items
Total number of webhooks in this list.

Get a specific webhook

It is super similar to the previous part, when we get all webhooks from the list. I do not want to duplicate nearly the same code, because here is just two things that differ:

Add a webhook ID to the end of the API endpoint (API URL) , example:

[tabs]


$response = wp_remote_get( 'https://'.substr($api_key,strpos($api_key,'-')+1).'.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/' . $webhook_id, array(
CURLOPT_URL => 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/' . $webhook_id,

Response parameters will be just like for a certain webhook, not wrapped in an array.

Change a webhook

Sometimes it could happen like a website domain has been changed and you’re a developer of a custom WordPress plugin and your plugin have to change the MailChimp webhook automatically.

And yes, it is also possible with the API. But you have to know your webhook ID.

[tabs]


$api_key = '';
$list_id = '';
$webhook_id = '';

$response = wp_remote_post( 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/' . $webhook_id, array(
	'method' => 'PATCH',
	'headers' => array(
		'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
	),
	'body' => json_encode(array(
		'url' => 'https://your-new-website.com/?process-webhook=1'
	))
));

$response_body = json_decode( wp_remote_retrieve_body( $response ) );

$api_key = '';
$list_id = '';
$webhook_id = '';

$connection = curl_init();

curl_setopt_array($connection, array( // PHP 5.1.3+
	CURLOPT_URL => 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/' . $webhook_id,
	CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: Basic '.base64_encode( 'user:'.$api_key )),
	CURLOPT_RETURNTRANSFER => true,
	CURLOPT_CUSTOMREQUEST => 'PATCH',
	CURLOPT_POST => true,
	CURLOPT_POSTFIELDS => json_encode(array(
		'url' => 'https://your-new-website.com/?process-webhook=1'
	))
));

$response_body = json_decode( curl_exec( $connection ) );

curl_close( $connection );

Delete a webhook

The last API request I’m gonna show you in this tutorial is deleting webhooks. As you can see MailChimp API provides everything you need to manage webhooks from your website / plugin etc.

[tabs]


$api_key = '';
$list_id = '';
$webhook_id = '';

$response = wp_remote_post( 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/' . $webhook_id, array(
	'method' => 'DELETE',
 	'headers' => array(
		'Authorization' => 'Basic ' . base64_encode( 'user:'. $api_key )
	)
) );

$response_body = json_decode( wp_remote_retrieve_body( $response ) );

$api_key = '';
$list_id = '';
$webhook_id = '';

$connection = curl_init();

curl_setopt_array($connection, array( // PHP 5.1.3+
	CURLOPT_URL => 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/webhooks/' . $webhook_id,
	CURLOPT_HTTPHEADER => array('Content-Type: application/json', 'Authorization: Basic '.base64_encode( 'user:'.$api_key )),
	CURLOPT_RETURNTRANSFER => true,
	CURLOPT_CUSTOMREQUEST => 'DELETE'
));

$response_body = json_decode( curl_exec( $connection ) );

curl_close( $connection );

This request returns nothing, but in case there were some problems with deleting a webhook, it returns an error, which you can handle this way:


if( $response_body->status == 404 ) {
	echo 'No webhooks with this ID';
} else {
	echo 'Webhook has been removed successfully.';
}
Misha Rudrastyh

Misha Rudrastyh

I develop websites since 2008, so it is total of 13 years of experience, oh my gosh. Most of all I love love love to create websites with WordPress and Gutenberg, some ideas and thoughts I share throughout my blog.

Need some developer help? Contact me

Follow me on Twitter