How to programmatically unsubscribe & resubscribe unsubscribed contacts.

Unsubscribed Contacts

Unsubscribed contacts are those who have decided not to receive any email from a Constant Contact account and have clicked the SafeUnsubscribe button in an email. Unsubscribed contacts cannot be sent mail through Constant Contact unless they re-subscribe to the account owner’s email lists. Unsubscribed contacts can resubscribe themselves by clicking a link in any Constant Contact emails they’ve retained, or by using the account owners sign-up form.

View Unsubscribed Contacts in an Account

In the API, unsubscribed contacts have status=unsubscribed. To find all unsubscribed contacts in an account, make the following call the contacts collection:

GET /contacts?status=unsubscribed

Endpoint Requirements

Authorization scopes: contact_data

It is a violation of Constant Contact's Email Policy to resubscribe a contact if the contact did not initiate the action, even if the account accidentally deleted the contact.

How to Unsubscribe a Contact

Make a PUT /contacts/<contact_id> call and set the email permission_to_send property to unsubscribed, and include an opt_out_reason (value can be null if no reason provided).

Example Unsubscribe Request

PUT https://api.cc.email/v3/contacts/{contact_id}

Endpoint Requirements

Authorization scopes: contact_data

<?php

$request = new HttpRequest();
$request->setUrl('https://api.cc.email/v3/contacts/{contact_id}');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Cache-Control' => 'no-cache',
  'Authorization' => 'Bearer {access_token}',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
));

$request->setBody('{
   
    "first_name": "John",
    "last_name": "Byrd",
    "create_source": "Account",
    "email_address": {
        "address": "example@example.com",
        "permission_to_send": "unsubscribed",
    "opt_out_reason":"No longer interested"
      },
    "update_source": "Contact"
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

curl -X PUT \
  https://api.cc.email/v3/contacts/{contact_id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
   
    "first_name": "John",
    "last_name": "Byrd",
    "create_source": "Account",
    "email_address": {
        "address": "example@example.com",
        "permission_to_send": "unsubscribed",
    "opt_out_reason":"No longer interested"
      },
    "update_source": "Contact"
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n   \n    \"first_name\": \"John\",\n    \"last_name\": \"Byrd\",\n    \"create_source\": \"Account\",\n    \"email_address\": {\n        \"address\": \"example@example.com\",\n        \"permission_to_send\": \"unsubscribed\",\n\t\"opt_out_reason\":\"No longer interested\"\n      },\n    \"update_source\": \"Contact\"\n}");
Request request = new Request.Builder()
  .url("https://api.cc.email/v3/contacts/{contact_id}")
  .put(body)
  .addHeader("Accept", "application/json")
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer {access_token}")
  .addHeader("Cache-Control", "no-cache")
  .build();

Response response = client.newCall(request).execute();

Response

{
    "contact_id": "{contact_id}",
    "first_name": "John",
    "last_name": "Byrd",
    "update_source": "Contact",
    "create_source": "Account",
    "created_at": "2013-11-26T15:45:52-05:00",
    "updated_at": "2018-02-16T15:56:41-05:00",
    "email_address": {
        "address": "example@example.com",
        "permission_to_send": "unsubscribed",
        "created_at": "2018-02-16T15:49:30-05:00",
        "updated_at": "2018-02-16T15:56:41-05:00",
        "opt_out_source": "Contact",
        "opt_out_date": "2018-02-16T15:56:41-05:00",
        "opt_out_reason": "No longer interested",
        "confirm_status": "off"
    }
}

Using the update_source Property

The update_source property identifies who initiated a contact update (PUT), Account or Contact. It is a violation of US and Canadian anti-spam laws, as well as a serious violation of the Constant Contact Terms of Service to use the API to re-subscribe a contact without his or her own action and consent.

A contact is not re-subscribed when update_source=Account on a PUT /contacts/{contact_id} call.

If an unsubscribed contact is added to a user’s list and update_source=Account, the contact is sent a confirmation message from Constant Contact asking them to confirm their subscription. Since the contact did not initiate this action, this will likely cause a negative user experience.

Re-subscribing Contacts

When an unsubscribed contact re-subscribes to a contact list, the PUT call that updates their record must include the property update_source=Contact.

It is a violation of US and Canadian anti-spam laws, as well as a serious violation of the Constant Contact Terms of Service to use the Opt-in features of the API to opt a contact back in without his or her own action and consent.

Unsubscribed contacts cannot be re-subscribed by a Constant Contact account owner (update_source=Account), EVEN IF the account owner unsubscribed the contact (accidentally or purposefully). The contact must re-subscribe themselves to a contact list in order to be removed from the Unsubscribed category.

Example Re-subscribe Request

To re-subscribe a contact, set update_source=Contact, permission_to_send=<explicit or implicit>, and assign a list_membership:

PUT https://api.cc.email/v3/contacts/{contact_id}

Endpoint Requirements

Authorization scopes: contact_data

<?php

$request = new HttpRequest();
$request->setUrl('https://api.cc.email/v3/contacts/{contact_id}');
$request->setMethod(HTTP_METH_PUT);

$request->setHeaders(array(
  'Cache-Control' => 'no-cache',
  'Authorization' => 'Bearer {access_token}',
  'Content-Type' => 'application/json',
  'Accept' => 'application/json'
));

$request->setBody('{
    "first_name": "John",
    "last_name": "Byrd",
    "email_address": {
        "address": "example@example.com",
        "permission_to_send": "explicit",
      },
    "update_source": "Contact",
    "lists":["{list_id1}","{list_id2}"]
}');

try {
  $response = $request->send();

  echo $response->getBody();
} catch (HttpException $ex) {
  echo $ex;
}

curl -X PUT \
  https://api.cc.email/v3/contacts/{contact_id} \
  -H 'Accept: application/json' \
  -H 'Authorization: Bearer {access_token}' \
  -H 'Cache-Control: no-cache' \
  -H 'Content-Type: application/json' \
  -d '{
   
  -d '{
    "first_name": "John",
    "last_name": "Byrd",
    "email_address": {
        "address": "example@example.com",
        "permission_to_send": "explicit",
      },
    "update_source": "Contact",
    "lists":["{list_id1}","{list_id2}"]
}'
OkHttpClient client = new OkHttpClient();

MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n    \"first_name\": \"John\",\n    \"last_name\": \"Byrd\",\n    \"email_address\": {\n        \"address\": \"example@example.com\",\n        \"permission_to_send\": \"explicit\",\n      },\n    \"update_source\": \"Contact\",\n    \"lists\":[\"{list_id2}\",\"{list_id2}\"]\n}");
Request request = new Request.Builder()
  .url("https://api.cc.email/v3/contacts/{contact_id}")
  .put(body)
  .addHeader("Accept", "application/json")
  .addHeader("Content-Type", "application/json")
  .addHeader("Authorization", "Bearer {access_token}")
  .addHeader("Cache-Control", "no-cache")
  .build();

Response response = client.newCall(request).execute();

Response

{
    "contact_id": "{contact_id}",
    "first_name": "John",
    "last_name": "Byrd",
    "update_source": "Contact",
    "create_source": "Account",
    "created_at": "2013-11-26T15:45:52-05:00",
    "updated_at": "2018-02-16T15:56:41-05:00",
    "email_address": {
        "address": "example@example.com",
        "permission_to_send": "explicit",
        "created_at": "2018-02-16T15:49:30-05:00",
        "updated_at": "2018-02-16T16:21:41-05:00",
        "opt_in_source": "Contact",
        "opt_in_date": "2018-02-16T16:21:42-05:00",
        "confirm_status": "off"
    }
}