Mailchimp API 3.0 – PHP and AJAX subscription / unsubscription
Ok, if you are reading this post, you already know something about mailchimp and use default Mailchimp sign up forms maybe.
But what if you want your forms to be more customizable for your website purposes, such as:
- original form design,
- mailchimp subscription built-in another form (sign up checkbox in custom form — look at my comment form),
- no confirmation emails,
- subscribe or unsubscribe users via your website administration area etc.
First of all insert this function into your website code. If you use WordPress, it can be functions.php
file.
function rudr_mailchimp_subscriber_status( $email, $status, $list_id, $api_key, $merge_fields = array('FNAME' => '','LNAME' => '') ){
$data = array(
'apikey' => $api_key,
'email_address' => $email,
'status' => $status,
'merge_fields' => $merge_fields
);
$mch_api = curl_init(); // initialize cURL connection
curl_setopt($mch_api, CURLOPT_URL, 'https://' . substr($api_key,strpos($api_key,'-')+1) . '.api.mailchimp.com/3.0/lists/' . $list_id . '/members/' . md5(strtolower($data['email_address'])));
curl_setopt($mch_api, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Basic '.base64_encode( 'user:'.$api_key )));
curl_setopt($mch_api, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0');
curl_setopt($mch_api, CURLOPT_RETURNTRANSFER, true); // return the API response
curl_setopt($mch_api, CURLOPT_CUSTOMREQUEST, 'PUT'); // method PUT
curl_setopt($mch_api, CURLOPT_TIMEOUT, 10);
curl_setopt($mch_api, CURLOPT_POST, true);
curl_setopt($mch_api, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($mch_api, CURLOPT_POSTFIELDS, json_encode($data) ); // send data in json
$result = curl_exec($mch_api);
return $result;
}
Ok, now let me show what each parameter means.
- (string) I hope it is clear for you.
- $status
- (string) Subscriber status to set:
subscribed
unsubscribed
cleaned
pending
(confirmation email will be sent)
- $list_id
- (string) Mailchimp list ID you want to add subscribers to. How to obtain it?
- $api_key
- (string) API key.
- $merge_fields
- (array) Subscriber fields, can be configured in a list settings. By default each mailchimp list has two merge fields (except email) — subscriber first name
$merge_fields['FNAME']
and last name$merge_fields['LNAME']
.
How to get Mailchimp list ID?
Login to Mailchimp, go to Lists then click on the list title, then in list menu Settings > List name and defaults.

How to get Mailchimp API keys?
1. In main Mailchimp menu click on your picture and go to Account.

2. Then choose Extras > API keys.

3. That’s it. Click on Create A Key and your new API key will appear.

PHP Subscription example
Do not forget to copy the rudr_mailchimp_subscriber_status()
function to your website code (you can find it at the beginning of the post).
$email = 'johndoe@rudrastyh.com';
$status = 'subscribed'; // "subscribed" or "unsubscribed" or "cleaned" or "pending"
$list_id = 'YOUR LIST ID HERE'; // where to get it read above
$api_key = 'YOUR MAILCHIMP API KEY HERE'; // where to get it read above
$merge_fields = array('FNAME' => 'Misha','LNAME' => 'Rudrastyh');
rudr_mailchimp_subscriber_status($email, $status, $list_id, $api_key, $merge_fields );
The very simple example. Do you think so?
AJAX Subscription example (WordPress-friendly)
Actually my blog is about WordPress, so the AJAX example will be adapted for WordPress.
Step 1. Sign Up form HTML
This form will work properly only if the JavaScript is enabled in user browser. You can also upgrade it to work both with JavaScript and without it.
<form action="<?php echo site_url() ?>/wp-admin/admin-ajax.php" id="mailchimp">
<!-- for my website the site_url() function returns https://rudrastyh.com -->
<input type="text" name="fname" placeholder="First name" />
<input type="text" name="lname" placeholder="Last name" />
<input type="email" name="email" placeholder="Email *" required />
<input type="hidden" name="action" value="mailchimpsubscribe" />
<!-- we need action parameter to receive ajax request in WordPress -->
<button>Subscribe</button>
</form>
Step 2. jQuery code to send asynchronous request
Make sure that jQuery library is included to your website pages.
jQuery(function($){
$('#mailchimp').submit(function(){
var mailchimpform = $(this);
$.ajax({
url:mailchimpform.attr('action'),
type:'POST',
data:mailchimpform.serialize(),
success:function(data){
alert(data);
}
});
return false;
});
});
Step 3. PHP code for your functions.php file. Errors Handling
function rudr_mch_subscribe(){
$list_id = 'YOUR LIST ID HERE';
$api_key = 'YOUR MAILCHIMP API KEY HERE';
$result = json_decode( rudr_mailchimp_subscriber_status($_POST['email'], 'subscribed', $list_id, $api_key, array('FNAME' => $_POST['fname'],'LNAME' => $_POST['lname']) ) );
// print_r( $result );
if( $result->status == 400 ){
foreach( $result->errors as $error ) {
echo '<p>Error: ' . $error->message . '</p>';
}
} elseif( $result->status == 'subscribed' ){
echo 'Thank you, ' . $result->merge_fields->FNAME . '. You have subscribed successfully';
}
// $result['id'] - Subscription ID
// $result['ip_opt'] - Subscriber IP address
die;
}
add_action('wp_ajax_mailchimpsubscribe','rudr_mch_subscribe');
add_action('wp_ajax_nopriv_mailchimpsubscribe','rudr_mch_subscribe');

Misha Rudrastyh
Hey guys and welcome to my website. For more than 10 years I've been doing my best to share with you some superb WordPress guides and tips for free.
Need some developer help? Contact me
Hii,
I tried your code on my site but it’s not working for me.
by the way should not this line be 3.0? curl_setopt($mch_api, CURLOPT_USERAGENT, ‘PHP-MCAPI/2.0’);
Hi,
hmm, everything works for me. Can you give me FTP access to your website (by email)?
Now it’s working. Actually it was my browser issue. thanks for this awesome help.
:)
Ok, great :)
Hi, grate code :)
Do you have an AJAX example not connected to WordPress?
Hi, thank you :)
All you need is to change form action to a file where you would like to place mailchimp subscription code.
Hi, I used the code in my site as neccessary – but I am not sure what to put as the
form action
. Do I set it as functions.php?Hi,
form action attribute contains the URL of WordPress AJAX handler.
Hi, Thanks !!
Saved lot of time
Thanks, this was helpful when other tutorials were not.
Hi ,
i need your help. I need the disable the double optin in mailchimp for my shopify. can you please what are all the steps i need to do for disable the double optin?
Hi,
Is MailChimp functionality integrated into your shopify theme? If yes, I recommend to perform a search through your theme files for a keyword
pending
. And when you find it, replace tosubscribed
.Hi,
Thanks for your reply.
Actually i have a newsletter sign up form in my shopify site. So after i have created the signup form in my mailchimp account, i took the form action url alone and used in the shopify.Thats all.
so i think mailchimp functionality is integrated with shopify like you are asking. but i have checked all the files. there is no keyword pending. I have a two shopify sites which one i am using “brooklyn” theme and another one is “Launch-pad star” theme. I am using the mailchimp sign up form integrated with the two sites of nesletter sign up form. But i can’t disable the double optin in those two sites.
Can you please provide any other solution for this??? I really need your help.
Thanks in Advance!!!
I think it is because you are using HTML sign-up form — it doesn’t allow to disable double optin.
If you want to subscribe users without confirmation, you have to use MailChimp API for these purposes. All the examples are above. Or you can try to look for an extension.
OH! Is it the whole thing?!
Not 100% whole, but… yes :) If you need more help, contact me via email, I could write all the code for you.
Can you give an example of this working? I am totally lost.
The example is above :) How can I help you?
Thank you for answering. I have so many questions – like:
Where do I put the API?
How do I make the API add new users based on a custom form?
I’m sorry, Sean, but answers to your questions are very clear in the post.
So, I do not want just to duplicate the text and code from the post here, so I recommend you to read the post once again or ask me the other questions.
Hi Misha,
first of all thank you for this!
I used your WP example and adding users to a mailchimp list with the form works fine, but after user submission of the email a the browser popup dialog opens on the frontend and after closing this the user is redirected to
http://mywebsite.com/admin-ajax.php?fname=Peter&lname=Piper&email=testmail%40testwebsite.com&action=mailchimpsubscribe
My questions:
How can i prevent the browser popup, and redirect to another link without displaying the user information in the browser adress bar? I am using the Foundation framework and would ideally like to open up a modal dialog (http://foundation.zurb.com/sites/docs/reveal.html) upon successful subscription.
And is it possible to just have one field on the frontend for the user’s email adress instead of first & last name + email adress?
Thank you for your time!
Hi Josh,
of course user shouldn’t be redirected to admin-ajax.php. Oh, sorry, I forgot to add
return false;
in my jQuery code – plese try now.Yes, it is possible to have just email address field on the frontend.
Thanks!
Is it possible to retrive the number of subscribers displayed before the form? Like “Join the 456 others”
Hello,
yes, and this post can help you.
Thanks, this code is brilliant! I have it working without being connected to WordPress so thanks! I was just wondering if there is a way to add groupings to the submission through multiple checkboxes? Thanks in advance!
Yes,
I think you can find more info in this post.
Unfortunately that code only work with WordPress and I am working outside of WP. I cannot find the translation for functions like ‘wp_remote_get’… any ideas?
You could try to use the same parameters from
wp_remote_get()
for your cURL request.Hello, whenever I try to submit the form I get the error:
POST http://newage.dev/wp-admin/admin-ajax.php 500 (Internal Server Error) jquery.min.js:4
In the console.
Do you know how to fix this?
Never mind, I got it to work, but it keeps showing the annoying alert box. How do I turn it off?
Hello,
just remove this line of code
alert(data);
or replace it withconsole.log(data);
.I have the same error. How did you solve it?
The error could be in two cases:
1) you forgot to insert
rudr_mailchimp_subscriber_status()
function,2) syntax error somewhere in your code (maybe you forgot about
;
or so ).Hi Valentin,
1) You can use GET
/lists/{list_id}/members/{subscriber_hash}
method where subscriber_hash ismd5( $email )
.2) You should pull out the add_action() lines, and the rudr_ functions outside the WP_Widget class first of all :)
I’m looking for a way to trigger the subscribe action when a checkbox is check, as also call the unsubscribe function when the checkbox is uncheck.
Does anyone have already achieved something like that?
It’d be a really useful minimal UI enabling the user to easily to opt-in a newsletter subscription, perfect for scenarios such as user’s account settings.
Hello Adriano,
just in the PHP code use the following:
Hey Misha, thanks for the tip! That seems promising, I’ll give it a try.
Is there any way to add a a subscriber even if it is missing some ‘required’ merge fields?
You can use dummy data for a required merge field I suppose.
Hi Sean,
try to add
timestamp_signup
parameter to the$data
array :)Hi Misha!
Just this?:
Dang that wasn’t it.
I do not believe that worked. The Date Added in the list is still 12/31/1969
I know that you are a very busy guy – so I wanted to add this comment as I figured it out.
If you add this line:
The MC API will record the date in date added correctly. Thank you so much!
Great, I’m glad that everything works finally. I think your comment will be helpful for other users. Thanks.
HI Misha
This a great tutorials i want to add location of submitted user form how can i add in this
Hi,
I recommend you to consider using HTML5 geolocation.
Can you show me in your current example you created as might help to other as well
Hope :)
I have no ready code for this task :)
Hi,
it seems like javascript error, please check your browser console.
Hi,
I have tried your code.But it is not working for me.For AJAX which code should I use?Please tell me the steps.
Hi,
just read the post carefully – all the info is in it. I really have nothing to say, everything is in the post content, I do not want just to duplicate it here.
Hey Sean,
Have you already read it in official API reference? https://developer.mailchimp.com/documentation/mailchimp/reference/automations/emails/queue/
If this link doesn’t help, I can create a tutorial about it, but the tutorial will be published only on July 4th.
Hi Misha!
Yes I have, but I am a bit lost on how to send this via the cURL. Any help would be great. Thank you!
Hi Sean!
One question – do you use WordPress or not? Because if yes, you can simplify your MailChimp connection.
Yes sir I do. Here is what I am trying to do:
usX
should not be on this line. Read the article carefully. The answer is there.Are you saying that the ‘USX’ should not be there? My datacenter us ‘us10’ so I changed it.
Hi Misha,
I’ve been using this code for a month and it works great. I want to add a thank you page, though. Is there a way to do that on top of this code?
So basically the user would be taken to a /thank-you page after submitting the email address.
Thanks!
Hi Alex,
you can redirect your subscribers easily to any page after they submitted their email addresses. If you use PHP example, do it with
header('Location: http://thank.you')
or if you use jQuery example, you can implement it withwindow.location.href = 'http://thank.you'
.Thanks! I placed the jQuery redirect and it’s just what I wanted. Error messages don’t show anymore though, but it’s quite alright.
Hello,
I need to get record from Mailchimp with my certain condition on date.I am fetching all subscriber and perform some operation on it.But as my subscriber list is to long server will not response and give me error “Excessive resource usage”.
SO I think if I can take only some specific subscriber then the server load is reduced.
I have to validate by “JOIN_DATE”.
Hello Ritesh,
You can do it this way:
Hi Misha,
Thanks for replay.But I am not using Wp I wrote code in core php and try to implement your code in it but not getting favorable response,getting all records.One more thing I want to tell you that
I am implementing my condition in LAST_PUR i.e., last purchase date.
Sorry, I’ve removed your code because you inserted it incorrectly. You must use the buttons under the comment field.
You filter the results after the response is received – it is incorrect. You should pass
since_timestamp_opt
parameter in your request!Great!
Thank you!
Its work.
It gives me an error :(
“title”:”API Key Missing”,”status”:401,”detail”:”Your request did not include an API key.”
Include API key :)
No worries. I found the problem :)
sorry for last message
i am using same code but not give any response.
any PHP notice?
Hello, I am getting 404 error when trying to integrate in my wp plugin.
Got the error, I paste wrong list ID. anyway thanks for your tutorial :)
Hello,
Ok, I’m glad you’ve figured it out 🙃
hello
how can i make 2 form with Different list ID in one page
sorry for my bad english.
my problem fixed thanks for your tutorial :D
Hey, thanks so much for this! I can’t seem to figure out how to do two lists with separate IDs. Is there a way to do that with this code?
Hey Joel,
Do you mean to subscribe for two lists at once?
If yes, this should help.
Oh no, I’m sorry. I have a page with two different sign up forms for different lists and I’d like to use this method. However, I can’t figure out how to get the two forms to go to the correct lists.
Thanks so much for your response!
I think you can even use the same code, just add input hidden fields with different list IDs to each form.
Oh perfect, that makes sense. Thank you so much for your help!
Spotted a wee typo :)
if( $resul->status == 400 ){
Thank you, fixed 🙃
Hi
Thanks a lot for this! One question, is there any possibility to add tags during the subscription as well?
Hi,
Yes, it is possible, you can use
merge_tags
parameter, example:Thank you so much for this great script, it helped me a lot! :)
Hi Misha,
Great tutorial, thanks a lot for spending time to help me/us.
I can’t get it to work, do I need a SSL certificate to make it work … currently my domain is on HTTP.
Thanks for this. I need to display error message if user is already subscribed. Did not find any key in API return to achieve this. I am using simple PHP. Can you guide?
Thank u
Hi there, great article BTW, has been of immense help to me so thank you.
Do you know how to tag a subscriber whilst adding them to an audience?
cheers chris
It’s working for me, lots of Thanks