Adding subscribers to a list using Mailchimp's API v3
Based on the List Members Instance docs, the easiest way is to use a PUT
request which according to the docs either "adds a new list member or updates the member if the email already exists on the list".
Furthermore apikey
is definitely not part of the json schema and there's no point in including it in your json request.
Also, as noted in @TooMuchPete's comment, you can use CURLOPT_USERPWD
for basic http auth as illustrated in below.
I'm using the following function to add and update list members. You may need to include a slightly different set of merge_fields
depending on your list parameters.
$data = [ 'email' => 'johndoe@example.com', 'status' => 'subscribed', 'firstname' => 'john', 'lastname' => 'doe'];syncMailchimp($data);function syncMailchimp($data) { $apiKey = 'your api key'; $listId = 'your list id'; $memberId = md5(strtolower($data['email'])); $dataCenter = substr($apiKey,strpos($apiKey,'-')+1); $url = 'https://' . $dataCenter . '.api.mailchimp.com/3.0/lists/' . $listId . '/members/' . $memberId; $json = json_encode([ 'email_address' => $data['email'], 'status' => $data['status'], // "subscribed","unsubscribed","cleaned","pending" 'merge_fields' => [ 'FNAME' => $data['firstname'], 'LNAME' => $data['lastname'] ] ]); $ch = curl_init($url); curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $apiKey); curl_setopt($ch, CURLOPT_HTTPHEADER, ['Content-Type: application/json']); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $json); $result = curl_exec($ch); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); curl_close($ch); return $httpCode;}
I got it working. I was adding the authentication to the header incorrectly:
$apikey = '<api_key>'; $auth = base64_encode( 'user:'.$apikey ); $data = array( 'apikey' => $apikey, 'email_address' => $email, 'status' => 'subscribed', 'merge_fields' => array( 'FNAME' => $name ) ); $json_data = json_encode($data); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, 'https://us2.api.mailchimp.com/3.0/lists/<list_id>/members/'); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Basic '.$auth)); curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/2.0'); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_POST, true); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch, CURLOPT_POSTFIELDS, $json_data); $result = curl_exec($ch); var_dump($result); die('Mailchimp executed');
These are good answers but detached from a full answer as to how you would get a form to send data and handle that response. This will demonstrate how to add a member to a list with v3.0 of the API from an HTML page via jquery .ajax()
.
In Mailchimp:
- Acquire your API Key and List ID
- Make sure you setup your list and what custom fields you want to use with it. In this case, I've set up
zipcode
as a custom field in the list BEFORE I did the API call. - Check out the API docs on adding members to lists. We are using the
create
method which requires the use of HTTPPOST
requests. There are other options in here that requirePUT
if you want to be able to modify/delete subs.
HTML:
<form id="pfb-signup-submission" method="post"> <div class="sign-up-group"> <input type="text" name="pfb-signup" id="pfb-signup-box-fname" class="pfb-signup-box" placeholder="First Name"> <input type="text" name="pfb-signup" id="pfb-signup-box-lname" class="pfb-signup-box" placeholder="Last Name"> <input type="email" name="pfb-signup" id="pfb-signup-box-email" class="pfb-signup-box" placeholder="youremail@example.com"> <input type="text" name="pfb-signup" id="pfb-signup-box-zip" class="pfb-signup-box" placeholder="Zip Code"> </div> <input type="submit" class="submit-button" value="Sign-up" id="pfb-signup-button"></a> <div id="pfb-signup-result"></div></form>
Key things:
- Give your
<form>
a unique ID and don't forget themethod="post"
attribute so the form works. - Note the last line
#signup-result
is where you will deposit the feedback from the PHP script.
PHP:
<?php /* * Add a 'member' to a 'list' via mailchimp API v3.x * @ http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#create-post_lists_list_id_members * * ================ * BACKGROUND * Typical use case is that this code would get run by an .ajax() jQuery call or possibly a form action * The live data you need will get transferred via the global $_POST variable * That data must be put into an array with keys that match the mailchimp endpoints, check the above link for those * You also need to include your API key and list ID for this to work. * You'll just have to go get those and type them in here, see README.md * ================ */ // Set API Key and list ID to add a subscriber $api_key = 'your-api-key-here'; $list_id = 'your-list-id-here'; /* ================ * DESTINATION URL * Note: your API URL has a location subdomain at the front of the URL string * It can vary depending on where you are in the world * To determine yours, check the last 3 digits of your API key * ================ */ $url = 'https://us5.api.mailchimp.com/3.0/lists/' . $list_id . '/members/'; /* ================ * DATA SETUP * Encode data into a format that the add subscriber mailchimp end point is looking for * Must include 'email_address' and 'status' * Statuses: pending = they get an email; subscribed = they don't get an email * Custom fields go into the 'merge_fields' as another array * More here: http://developer.mailchimp.com/documentation/mailchimp/reference/lists/members/#create-post_lists_list_id_members * ================ */ $pfb_data = array( 'email_address' => $_POST['emailname'], 'status' => 'pending', 'merge_fields' => array( 'FNAME' => $_POST['firstname'], 'LNAME' => $_POST['lastname'], 'ZIPCODE' => $_POST['zipcode'] ), ); // Encode the data $encoded_pfb_data = json_encode($pfb_data); // Setup cURL sequence $ch = curl_init(); /* ================ * cURL OPTIONS * The tricky one here is the _USERPWD - this is how you transfer the API key over * _RETURNTRANSFER allows us to get the response into a variable which is nice * This example just POSTs, we don't edit/modify - just a simple add to a list * _POSTFIELDS does the heavy lifting * _SSL_VERIFYPEER should probably be set but I didn't do it here * ================ */ curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_USERPWD, 'user:' . $api_key); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json')); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_TIMEOUT, 10); curl_setopt($ch, CURLOPT_POST, 1); curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded_pfb_data); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); $results = curl_exec($ch); // store response $response = curl_getinfo($ch, CURLINFO_HTTP_CODE); // get HTTP CODE $errors = curl_error($ch); // store errors curl_close($ch); // Returns info back to jQuery .ajax or just outputs onto the page $results = array( 'results' => $result_info, 'response' => $response, 'errors' => $errors ); // Sends data back to the page OR the ajax() in your JS echo json_encode($results);?>
Key things:
CURLOPT_USERPWD
handles the API key and Mailchimp doesn't really show you how to do this.CURLOPT_RETURNTRANSFER
gives us the response in such a way that we can send it back into the HTML page with the.ajax()
success
handler.- Use
json_encode
on the data you received.
JS:
// Signup form submission$('#pfb-signup-submission').submit(function(event) { event.preventDefault(); // Get data from form and store it var pfbSignupFNAME = $('#pfb-signup-box-fname').val(); var pfbSignupLNAME = $('#pfb-signup-box-lname').val(); var pfbSignupEMAIL = $('#pfb-signup-box-email').val(); var pfbSignupZIP = $('#pfb-signup-box-zip').val(); // Create JSON variable of retreived data var pfbSignupData = { 'firstname': pfbSignupFNAME, 'lastname': pfbSignupLNAME, 'email': pfbSignupEMAIL, 'zipcode': pfbSignupZIP }; // Send data to PHP script via .ajax() of jQuery $.ajax({ type: 'POST', dataType: 'json', url: 'mailchimp-signup.php', data: pfbSignupData, success: function (results) { $('#pfb-signup-box-fname').hide(); $('#pfb-signup-box-lname').hide(); $('#pfb-signup-box-email').hide(); $('#pfb-signup-box-zip').hide(); $('#pfb-signup-result').text('Thanks for adding yourself to the email list. We will be in touch.'); console.log(results); }, error: function (results) { $('#pfb-signup-result').html('<p>Sorry but we were unable to add you into the email list.</p>'); console.log(results); } });});
Key things:
JSON
data is VERY touchy on transfer. Here, I am putting it into an array and it looks easy. If you are having problems, it is likely because of how your JSON data is structured. Check this out!- The keys for your JSON data will become what you reference in the PHP
_POST
global variable. In this case it will be_POST['email']
,_POST['firstname']
, etc. But you could name them whatever you want - just remember what you name the keys of thedata
part of your JSON transfer is how you access them in PHP. - This obviously requires jQuery ;)