The Tallest Dwarf

RSSEmailMastodonNewsletterTwitterGitHubDribbbleLinkedInFacebookInstagramYouTubePinterestReddit icon

Add subscribers to mailchimp list using PHP

Posted at — Sep 30, 2021 by Abishek Muthian

Static websites require a middleware to add subscribers to the Mailchimp list if we don't want to redirect our visitors to another website.

PHP middleware which uses Mailchimp API 3.0 is useful because there's wide range of inexpensive options to host a PHP web service either in the form of managed hosting providers or self hosted cloud providers.

Below is the script I used for adding subscribers on hitstartup. My subscription form for startup coaching required email address, first name, last name and a problem statement.

I cobbled up this script following a blog, Which I don't remember now for proper attribution.

if (!empty($_POST)) {
    header("access-control-allow-headers:Content-Type, Content-Length, Accept-Encoding, X-CSRF-Token");
    header("access-control-allow-methods:POST, GET, OPTIONS");
    // change to represent your site's protocol, either http or https
    header("Content-Type: application/json");

// put your api key here  note the ending text past the - this is your datacenter 
// the datacenter needs to be added into to the url in the curlopt_url (see below)
$apikey = "[API KEY]"; // e.g. "xxxxx-us11"

// listid goes here - to find this... log into mail chimp go to Lists menu , 
// look to far right of list name for a drop down arrow, select the "Settings" dropdown,
// scroll to bottom and look  for  "Unique id for list"
$list_id = "[LIST ID]"; // web site list

// Check for bot using secret key
if(!empty($_POST['[NOT SO SECRET KEY]'])){
    die(' '); // frees up mem etc..

// the data I used to register (there may be others you can use, check API docs)
$email = isset($_POST['EMAIL']) ? $_POST['EMAIL'] : '';
$fname = isset($_POST['FNAME']) ? $_POST['FNAME'] : '';
$lname = isset($_POST['LNAME']) ? $_POST['LNAME'] : '';
$problem = isset($_POST['PROBLEM']) ? $_POST['PROBLEM'] : '';

$auth = base64_encode( 'user:'.$apikey );

// Notice the value of 'status' is 'pending'  
// I found this via a google search indicating a double opt in subscription process 

$data = array(
'apikey'        => $apikey,
'email_address' => $email,
'status'        => 'subscribed',
'merge_fields'  => array(
'FNAME' => $fname,
'LNAME' => $lname,
'PROBLEM' => $problem
$json_data = json_encode($data);

$ch = curl_init();

// notice datacenter  "us11" comes after the // - make sure you update this to your datacenter (e.g. us2, us7 etc) or you'll get the "wrong datacenter" error.
$curlopt_url = "$list_id/members/";
curl_setopt($ch, CURLOPT_URL, $curlopt_url);

curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json',
    'Authorization: Basic '.$auth));
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP-MCAPI/3.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);
// some debug statements 
print_r ($result);

// here is simple way to determine status of a subscription
// $result is in JSON format
// this following loop is a simple JSON decode loop I found via google

$status = "undefined";
$msg = "unknown error occurred";
$myArray = json_decode($result, true);

foreach($myArray as $key => $value)

    // debug key<<< = >>>$value<<< <br>";

    if( $key == "status" )
        //debug                 echo" status found $status<Br>";
    else if ($key == "title")
        //debug                 echo" title found $msg<Br>";


// create the output that gets displayed or returned if invoked by AJAX method
if( $status == "subscribed" && !isset($_POST['PROBLEM']) )
    $msg = "Success! $email has been subscribed to the hitstartup. Check your inbox for the welcome email to complete your subscription. If you are unable to find the welcome email in the inbox, please check other folders including spam.";
else if( $status == "subscribed" && isset($_POST['PROBLEM']) )
    $msg = "Success! $email has been added to the queue for checking eligiblity. Check your inbox for the welcome email with further instructions. If you are unable to find the welcome email in the inbox, please check other folders including spam.";
    $msg = "Sorry could not add the email id $email, may be already subscribed (or) invalid email id. Please try again later, if the issue persists (or) if you are an existing subscriber try emailing me directly to me.";

$output = ['message' => $msg];
echo json_encode($output); 

die(' '); // frees up mem etc..


On the client side I was using AMP and so it required amp-mustache.js and amp-form.js along with HTML form below.

<!-- Begin Mailchimp Signup Form -->
<div id="mc_embed_signup">
<form action-xhr="" method="post" id="mc-embedded-subscribe-form" name="mc-embedded-subscribe-form" custom-validation-reporting="show-all-on-submit" target="_blank">
    <div id="mc_embed_signup_scroll">
	<h3>Explain the problem you are solving in under 50 characters</h3>
  <p>If you don't have a problem to solve, mention why you need startup coaching in under 50 characters.</p>
<div class="mc-field-group">
	<label for="mce-EMAIL">Email Address</label>
	<input type="email" value="" name="EMAIL" required id="mce-EMAIL">
	<span visible-when-invalid="valueMissing"
	<span visible-when-invalid="typeMismatch"
<div class="mc-field-group">
	<label for="mce-FNAME">First Name </label>
	<input type="text" value="" name="FNAME" required id="mce-FNAME">
	<span visible-when-invalid="valueMissing"
<div class="mc-field-group">
	<label for="mce-LNAME">Last Name </label>
	<input type="text" value="" name="LNAME" required id="mce-LNAME">
	<span visible-when-invalid="valueMissing"
<div class="mc-field-group">
	<label for="mce-PROBLEM">Problem </label>
	<input type="text" value="" name="PROBLEM" maxlength="50" required id="mce-PROBLEM">
	<span visible-when-invalid="valueMissing"
	<div id="mce-responses" class="clear">
	<div submitting>
    <template type="amp-mustache">
      Form submitting... Thank you for waiting {{FNAME}}.
    <div submit-success>
      <template type="amp-mustache">
    <div submit-error>
      <template type="amp-mustache">
	<!-- real people should not fill this in and expect good things - do not remove this or risk form bot signups-->
    <div style="position: absolute; left: -5000px;" aria-hidden="true"><input type="text" name="[NOT SO SECRET KEY]" tabindex="-1" value=""></div>
    <div class="clear"><input type="submit" value="Check Eligibility" name="subscribe" id="mc-embedded-subscribe" class="button"></div>
<!--End mc_embed_signup-->


I strive to write low frequency, High quality content on Health, Product Development, Programming, Software Engineering, DIY, Security, Philosophy and other interests. If you would like to receive them in your email inbox then please consider subscribing to my Newsletter.