Just to follow up on Volomike's answer, which should get all the credit here so upvote his, this is my expanded code that covers the conflict error. This is a procedural approach. Feel free to write a better one.
Keep in mind I had to handle this as a crisis last minute hot fix for something. I have no idea what I put in here that may be unnecessary or could be written better. I just had to mash it out fast to get it working. If there is a more complete, cleaner way to do it, feel free to write it as an answer and comment on this answer so I can plus you.
The //REPLACE WITH YOUR OWN segment - see Volomike's answer for the whole dev account process. It is very fast so don't let that discourage you. Just sign up, grab your token and keys and plug this in.
error_reporting(E_ALL);
ini_set('display_errors','On');
header('Content-Type: text/plain');
// REPLACE WITH YOUR OWN
$sAPIKey = 'your-api-key';
$sToken = 'your-token';
$sListID = 11111111; //your list id
$email = 'email-to-be-added@gmail.com';
// END REPLACE BLOCK
$sURL = "https://api.constantcontact.com/v2/contacts?action_by=" .
"ACTION_BY_OWNER&api_key=$sAPIKey";
//DONT INDENT THIS. remember heredoc needs it to be rammed right up against the wall
$sJSON = <<<EOD
{
"lists": [
{
"id": "$sListID"
}
],
"email_addresses": [
{
"email_address": "$email"
}
]
}
EOD;
$sResponse = file_get_contents($sURL,false,stream_context_create(array(
'http'=>array(
'method' => 'POST',
'header' => "Authorization: Bearer $sToken\nContent-Type: application/json",
'content' => $sJSON,
'ignore_errors' => TRUE
),
'ssl'=>array(
'verify_peer'=>false,
'verify_peer_name'=>false,
'allow_self_signed'=>true,
)
)));
if(strpos($sResponse, 'http.status.email_address.conflict') > -1)
{
$sResponse = file_get_contents("https://api.constantcontact.com/v2/contacts?email=$email&status=ALL&limit=1&api_key=$sAPIKey",false,stream_context_create(array(
'http'=>array(
'header' => "Authorization: Bearer $sToken",
'ignore_errors' => TRUE
),
'ssl'=>array(
'verify_peer'=>false,
'verify_peer_name'=>false,
'allow_self_signed'=>true,
)
)));
$res = json_decode($sResponse);
$id = $res->results[0]->id;
$res->results[0]->lists[] = (object) array('id' => ''.$sListID);
$sResponse = file_get_contents("https://api.constantcontact.com/v2/contacts/$id?action_by=ACTION_BY_OWNER&api_key=$sAPIKey",false,stream_context_create(array(
'http'=>array(
'method' => 'PUT',
'header' => "Authorization: Bearer $sToken\nContent-Type: application/json",
'content' => json_encode($res->results[0]),
'ignore_errors' => TRUE
),
'ssl'=>array(
'verify_peer'=>false,
'verify_peer_name'=>false,
'allow_self_signed'=>true,
)
)));
echo $sResponse;
}
else
{
// didnt have a conflict
echo $sResponse;
}
//there was a problem of some kind if it reaches here