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

User privileges: contacts:read

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

User privileges: contacts:write

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

Contacts can choose to resubscribe to a contact list:

  • Directly, the contact uses your sign-up tool, such as clicking a subscribe sign-up link on a previously sent email or from a landing page. After confirmation is received, update_source changes to contact and the contact is resubscribed.

  • Indirectly, the contact contacts you and requests to resubscribe. After you make a call to the resubscribe endpoint, Constant Contact sends a resubscribe email to the contact’s email address. After confirmation is received, update_source changes to contact and the contact is resubscribed. You can only send a resubscribe email to an unsubscribed contact once, or a 400 response is returned indicating that the contact is not unsubscribed (pending confirmation).

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 Requests

Contact Resubscribes directly

To re-subscribe a contact to one or more contact lists, make a PUT call to the https://api.cc.email/v3/contacts/{contact_id} endpoint and 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

User privileges: contacts:write

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"
    }
}

Contact Resubscribes Indirectly

To send a resubscribe email request to a contact and specify the contact lists to which the contact is to be added, make a PUT call to the https://api.cc.email/v3/contacts/resubscribe/{contact_id} endpoint. Include the contact_id as a path parameter. In the request body, specify the list_ids in which to add the contact. A successful requests returns a 200 response.

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

Endpoint Requirements

User privileges: contacts:write

Authorization scopes: contact_data

<?php

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.cc.email/v3/contacts/resubscribe/{contact_id}',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'PUT',
  CURLOPT_POSTFIELDS =>'{
  "list_ids": [
    "{list_id1}"
  ]
}',
  CURLOPT_HTTPHEADER => array(
    'Accept: */*',
    'Content-Type: application/json',
    'Authorization: Bearer {access_token}'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;


curl --location --request PUT 'https://api.cc.email/v3/contacts/resubscribe/{contact_id}' \
--header 'Accept: */*' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {access_token}' \
--data '{
  "list_ids": [
    "{list_id1}"
  ]
}'
OkHttpClient client = new OkHttpClient().newBuilder()
        .build();
MediaType mediaType = MediaType.parse("application/json");
RequestBody body = RequestBody.create(mediaType, "{\n  \"list_ids\": [\n    \"{list_id}\"\n  ]\n}");
Request request = new Request.Builder()
        .url("https://api.cc.email/v3/contacts/resubscribe/{contact_id}")
        .method("PUT", body)
        .addHeader("Accept", "*/*")
        .addHeader("Content-Type", "application/json")
        .addHeader("Authorization", "Bearer {access_token}")
        .build();
Response response = client.newCall(request).execute();