---
swagger: "2.0"
info:
description: "The Constant Contact, Inc. V3 public API, for building integrations\
\ with Constant Contact, the leading small-business email marketing platform."
version: "3.0.149"
title: "AppConnect V3"
contact:
name: "[email protected]"
license:
name: "Private"
url: "https://www.constantcontact.com/legal/terms-of-use"
host: "api.cc.email"
basePath: "/v3"
tags:
- name: "Account Services"
description: "Use the account endpoints and methods to get account information."
- name: "Bulk Activities"
description: "Bulk activities endpoints are used to manage large numbers of contacts,\
\ lists, and tags."
- name: "Contacts"
description: "Endpoints and methods to get, create, delete, and update one or more\
\ contacts."
- name: "Contact Lists"
description: "Endpoints and methods to get, create, delete, and update one or more\
\ contact lists."
- name: "Contact Tags"
description: "Endpoints and methods to get, create, delete, and update one or more\
\ contact tags."
- name: "Contacts Reporting"
description: "Contact reporting endpoints are used to gather activity reports for\
\ campaigns sent to a contact."
- name: "Contacts Custom Fields"
description: "Endpoints and methods to get, create, delete, and update on one or\
\ more custom fields."
- name: "Email Campaigns"
description: "Use email campaign endpoints and methods to get, create, and update\
\ email campaigns."
- name: "Email Campaigns AB Tests"
description: "Use email campaigns A/B Test endpoints and methods to get, create,\
\ delete and update A/B tests."
- name: "Email Reporting"
description: "Use the email reporting endpoints and methods to get reporting data\
\ for email campaigns you sent to contacts."
- name: "Email Scheduling"
description: "Use email scheduling endpoints and methods to schedule an email campaign\
\ activity, unschedule an email campaign activity, and GET schedule information."
- name: "Events"
description: "Endpoints and methods used to create and manage events."
- name: "Segments"
description: "Use segments to target a subset of your contacts that are most likely\
\ to engage with a particular campaign."
- name: "Landing Pages Reporting"
description: "Use landing pages reporting endpoints and methods to get reporting\
\ data about how a contact interacted with a campaign activity."
- name: "SMS Reporting"
description: "Use SMS reporting endpoints and methods to get reporting data about\
\ SMS campaigns."
- name: "Technology Partners"
description: "Use partner endpoints to manage client Constant Contact accounts under\
\ your partner account."
- name: "Technology Partners Webhooks"
description: "Use partner webhooks to subscribe to billing event notifications from\
\ Constant Contact."
schemes:
- "https"
consumes:
- "application/json"
produces:
- "application/json"
paths:
/account/user/privileges:
get:
tags:
- "Account Services"
summary: "GET User Privileges"
description: "Use this method to return the user privileges associated with\
\ your access token as an array of objects. This method returns all user privileges,\
\ including privileges the V3 API does not currently use. Constant Contact\
\ requires specific user privileges to make requests using the V3 API. For\
\ more information, see the [User Privileges and Roles Overview](/api_guide/user_privileges.html)."
operationId: "getUserPrivileges"
produces:
- "application/json"
parameters: []
responses:
"200":
description: "Request successful."
schema:
$ref: "#/definitions/UserPrivilegesResource"
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. Your application is deactivated."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit: []
- oauth2_access_code: []
/account/summary:
get:
tags:
- "Account Services"
summary: "GET a Summary of Account Details"
description: "Get account related details for a Constant Contact user account.\
\ Use the `extra_fields` query parameter to include the `company_logo` and/or\
\ `physical_address` details in the response body. For more details, see [Get\
\ Account Summary Details](/api_guide/account_details_get.html)."
operationId: "getAccountById"
produces:
- "application/json"
parameters:
- name: "extra_fields"
in: "query"
description: "Use the `extra_fields` query parameter to include the `physical_address`\
\ and/or `company_logo` details in the response body. Use a comma separated\
\ list to include both (physical_address, company logo)."
required: false
type: "string"
format: "csv"
enum:
- "physical_address"
- "company_logo"
x-example: "company_logo"
responses:
"200":
description: "Request successful"
schema:
$ref: "#/definitions/Customer"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_read"
- oauth2_access_code:
- "account_read"
x-authorization-privileges:
- "account:read"
x-sdk-methodName: "getAccountDetails"
put:
tags:
- "Account Services"
summary: "PUT (update) Account Details"
description: "Use this method to update account details for a Constant Contact\
\ account, such as the email address or phone number. This PUT method provides\
\ a partial update where only valid properties that you include in the request\
\ body are updated and excluded properties are not overwritten. For more details,\
\ see [Put (update) Account Summary Details](/api_guide/account_details_put.html)."
operationId: "putCustomerById"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "In the request body, specify changes to account details by including\
\ and modifying all or select `CustomerPut` properties. Changes to read-only\
\ fields (`encoded_account_id`) are ignored."
required: true
schema:
$ref: "#/definitions/CustomerPut"
responses:
"200":
description: "Request successful"
schema:
$ref: "#/definitions/CustomerPut"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_update"
- oauth2_access_code:
- "account_update"
x-authorization-privileges:
- "account:update"
x-sdk-methodName: "updateAccount"
/account/summary/physical_address:
get:
tags:
- "Account Services"
summary: "GET the Physical Address for the Account"
description: "Use this method to get the address where the account's organization\
\ physically resides. The physical address is required to send emails and\
\ displays on the footer of every email that is sent from the account."
operationId: "getPhysicalAddress"
produces:
- "application/json"
parameters: []
responses:
"200":
description: "Request successful"
schema:
$ref: "#/definitions/AccountPhysicalAddress"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"415":
description: "Unsupported Media Type."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_read"
- oauth2_access_code:
- "account_read"
x-authorization-privileges:
- "account:read"
x-ctctmcp-allow: true
x-sdk-methodName: "getAccountPhysicalAddress"
post:
tags:
- "Account Services"
summary: "POST the Physical Address for the Account"
description: "Use this method to add the address where the account's organization\
\ physically resides. The physical address is required to send emails and\
\ displays on the footer of every email that is sent from the account. The\
\ country (<code>country_code</code>) where the account organization resides\
\ determines whether you use the <code>state_code</code> to specify United\
\ States (<code>US</code>) and Canada (<code>CA</code>) addresses, or use\
\ the <code>state_name</code> to specify all other countries."
operationId: "addPhysicalAddress"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Include all `AccountPhysicalAddress` properties required for\
\ the specified `country_code`. If a required property is not included or\
\ incorrectly formatted, a 400 error message is returned. If the address\
\ already exists, a 409 error message is returned."
required: true
schema:
$ref: "#/definitions/AccountPhysicalAddress"
responses:
"201":
description: "Request successful"
schema:
$ref: "#/definitions/AccountPhysicalAddress"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"409":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"415":
description: "Unsupported Media Type."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_update"
- oauth2_access_code:
- "account_update"
x-authorization-privileges:
- "account:update"
x-ctctmcp-allow: true
put:
tags:
- "Account Services"
summary: "PUT (update) the Physical Address for an Account"
description: "Use this method to update the organization's physical address\
\ for the Constant Contact user account. The physical address is required\
\ to send emails and displays on the footer of every email that is sent from\
\ the account. To get the current physical address, make a GET call to `/account/summary/physical_address`.\
\ The country (<code>country_code</code>) where the account organization resides\
\ determines whether you use the <code>state_code</code> to specify United\
\ States (<code>US</code>) and Canada (<code>CA</code>) addresses, or use\
\ the <code>state_name</code> to specify all other countries. For more details,\
\ see [Put (update) the Physical Address for the Account](/api_guide/account_address_put.html).\
\ You must have the role of Account Owner assigned to update account level\
\ details. "
operationId: "putPhysicalAddress"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "Include all `AccountPhysicalAddress` properties required for\
\ the specified `country_code` and then update only those properties that\
\ you want to change. Excluding a non-read only field from the request body\
\ removes it from the physical address."
required: true
schema:
$ref: "#/definitions/AccountPhysicalAddress"
responses:
"200":
description: "Request successful"
schema:
$ref: "#/definitions/AccountPhysicalAddress"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"415":
description: "Unsupported Media Type."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_update"
- oauth2_access_code:
- "account_update"
x-authorization-privileges:
- "account:update"
x-ctctmcp-allow: true
x-sdk-methodName: "updateAccountPhysicalAddress"
/account/emails:
get:
tags:
- "Account Services"
summary: "GET a Collection of Account Email Addresses"
description: "Use this method to return a collection of email addresses for\
\ the account associated with your access token. When you <a href=\"https://v3.developer.constantcontact.com/api_reference/index.html#!/Email_Campaigns/createEmailCampaignUsingPOST\"\
\ target=\"_blank\">Create an Email Campaign<a/>, you must use an account\
\ email address with a `CONFIRMED` status in the email campaign `from_email`\
\ and `reply_to_email` headers.\n \n\nUse the query parameters to filter\
\ results. You can filter using `confirm_status`, `role_code`, or `email_address`.\
\ For example, searching with `confirm_status=CONFIRMED` returns all confirmed\
\ email addresses in the account. This method only supports one query parameter\
\ at a time.\n"
operationId: "retrieveEmailAddresses"
produces:
- "application/json"
parameters:
- name: "confirm_status"
in: "query"
description: "Use the `confirm_status` query parameter to search for account\
\ emails using the email status. Possible values are `CONFIRMED` or `UNCONFIRMED`.\
\ You can also abbreviate the values of this query parameter and use `C`\
\ or `U`.\n"
required: false
type: "string"
enum:
- "CONFIRMED"
- "C"
- "UNCONFIRMED"
- "U"
- name: "role_code"
in: "query"
description: "Use the `role_code` query parameter to search for account emails\
\ that have a specific role. Each each email address in an account can have\
\ multiple roles or no role. Possible values are `CONTACT`, `BILLING`, `REPLY_TO`,\
\ `JOURNALING`, or `OTHER`. You can also abbreviate the value of this query\
\ parameter and use `C`,`B`,`R`,`J`, or `O`."
required: false
type: "string"
enum:
- "CONTACT"
- "C"
- "BILLING"
- "B"
- "JOURNALING"
- "J"
- "REPLY_TO"
- "R"
- "OTHER"
- "O"
- name: "email_address"
in: "query"
description: "Use the `email_address` query parameter to search for a specific\
\ account email address."
required: false
type: "string"
responses:
"200":
description: "Request successful."
schema:
$ref: "#/definitions/AccountEmails"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"415":
description: "Unsupported Media Type."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_read"
- oauth2_access_code:
- "account_read"
x-authorization-privileges:
- "account:read"
x-sdk-methodName: "getAllAccountEmailAddresses"
x-ctctmcp-allow: true
post:
tags:
- "Account Services"
summary: "POST Add an Account Email Address"
description: "Use this method to add a new email address to a Constant Contact\
\ account. If the email address you are adding already exists in the account\
\ the API will return a 409 conflict error. \n\nWhen you add a new email address\
\ to an account, Constant Contact automatically sends an email to that address\
\ with a link to confirm it. After a user clicks that link, the account email\
\ status changes from `UNCONFIRMED` to `CONFIRMED`. You can use confirmed\
\ account email addresses in the email campaign `from_email` and `reply_to_email`\
\ headers. For more use case information, see [Add an Account Email Address](/api_guide/account_post_emails.html)\
\ in the API guide. \n"
operationId: "addAccountEmailAddress"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "A JSON request payload containing the new email address you\
\ want to add to the Constant Contact account."
required: true
schema:
$ref: "#/definitions/AccountEmailInput"
responses:
"201":
description: "Request successful."
schema:
$ref: "#/definitions/AccountEmailCreateResponse"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"409":
description: "Conflict. The resource you are creating or updating conflicts\
\ with an existing resource."
"415":
description: "Unsupported Media Type."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "account_update"
- oauth2_access_code:
- "account_update"
x-authorization-privileges:
- "account:update"
x-ctctmcp-allow: true
/activities:
get:
tags:
- "Bulk Activities"
summary: "GET Activity Status Collection"
description: "This endpoint returns a collection of activities. Use the state\
\ query parameter to include only activities with a specific status (processing,\
\ completed, cancelled, failed, or time_out). Use the limit query parameter\
\ to define the number of activities returned per page. Learn [more](/api_guide/activity_status.html)."
operationId: "getActivityStatusCollection"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: "limit"
in: "query"
description: "Specifies the number of results displayed per page of output,\
\ from 1 - 500, default = 50."
required: false
type: "integer"
default: 50
maximum: 500
minimum: 1
x-example: 25
- name: "state"
in: "query"
description: "Use this parameter to filter the response to include only activities\
\ in one of the following states: cancelled, completed, failed, processing,\
\ or timed_out."
required: false
type: "string"
enum:
- "processing"
- "completed"
- "cancelled"
- "failed"
- "timed_out"
x-example: "processing"
responses:
"200":
description: "Request Successful"
schema:
$ref: "#/definitions/Activities"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"404":
description: "The requested resource was not found."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "contact_data"
- oauth2_access_code:
- "contact_data"
x-authorization-privileges:
- "contacts:write"
x-sdk-methodName: "getAllActivities"
/activities/{activity_id}:
get:
tags:
- "Bulk Activities"
summary: "GET an Activity Status"
description: "This endpoint returns an activity status report."
operationId: "getActivity"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- name: "activity_id"
in: "path"
description: "The unique ID of the activity to GET"
required: true
type: "string"
x-example: "04fe9a-a579-43c5-bb1a-58ed29bf0a6a"
responses:
"200":
description: "Request Successful"
schema:
$ref: "#/definitions/Activity"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"404":
description: "Resource not found for the activity_id provided"
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "contact_data"
- oauth2_access_code:
- "contact_data"
x-authorization-privileges:
- "contacts:write"
x-sdk-methodName: "getActivityById"
/activities/contact_exports:
post:
tags:
- "Bulk Activities"
summary: "Export Contacts to a File"
description: "Use this method to create an activity that exports contacts and\
\ contact details to a CSV file. You can choose to export all contacts in\
\ your account (default) or you can use parameters to filter on which contacts\
\ to export. After Constant Contact finishes processing the activity, use\
\ the `results` link in the response body to retrieve the CSV file."
operationId: "postContactsExport"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "A JSON payload that specifies the contacts (rows in the CSV\
\ file) and contact properties (columns in the CSV file) you want to export."
required: true
schema:
$ref: "#/definitions/ContactsExport"
responses:
"201":
description: "Request successful, queued for processing."
schema:
$ref: "#/definitions/ActivityExportStatus"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"404":
description: "The requested resource was not found."
"429":
description: "Too many requests. You exceeded 1,000 queued activities for\
\ this user account."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "contact_data"
- oauth2_access_code:
- "contact_data"
x-authorization-privileges:
- "contacts:write"
x-sdk-methodName: "createExportActivity"
/contact_exports/{file_export_id}:
get:
tags:
- "Bulk Activities"
summary: "Retrieve Exported Contacts File"
description: "Use this endpoint to retrieve (GET) a CSV file containing exported\
\ contacts by providing the `activity_id` of a completed CSV export activity.\
\ \n"
operationId: "getContactsExport"
consumes:
- "application/json"
produces:
- "text/csv"
parameters:
- name: "file_export_id"
in: "path"
description: "The unique ID of the exported file provided in the results:\
\ section of the export contacts activity response."
required: true
type: "string"
x-example: "04fe9a-a579-43c5-bb1a-58ed29bf0a6a"
responses:
"200":
description: "Request Successful"
schema:
$ref: "#/definitions/ActivityGetExport"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"404":
description: "The requested resource was not found."
"429":
description: "Too many requests. You exceeded 1,000 queued activities for\
\ this user account."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "contact_data"
- oauth2_access_code:
- "contact_data"
x-authorization-privileges:
- "contacts:write"
x-sdk-methodName: "getCSVExportFile"
/activities/contact_delete:
post:
tags:
- "Bulk Activities"
summary: "Delete Contacts in Bulk"
description: "Use this endpoint to bulk delete contacts in an account. Contacts\
\ to delete are specified by contact_id (up to 500), or by list_id (up to\
\ 50 lists); all contacts that are members of the list_ids are deleted. Deleted\
\ contacts won’t receive email from you, and they don’t count as active contacts.\
\ Unlike unsubscribed contacts, deleted contacts can be added back to an account.\
\ [Learn how to revive deleted contacts](/api_guide/contacts_delete.html#revive)."
operationId: "postContactDelete"
consumes:
- "application/json"
produces:
- "application/json"
parameters:
- in: "body"
name: "body"
description: "The request body contains an array of contact_ids <em>or</em>\
\ list_ids. All contact_ids provided are deleted, or all members of each\
\ specified list_id are deleted."
required: true
schema:
$ref: "#/definitions/ContactDelete"
responses:
"201":
description: "Request successful. Activity queued for processing."
schema:
$ref: "#/definitions/ActivityDeleteStatus"
"400":
description: "Bad request. Either the JSON was malformed or there was a\
\ data validation error."
"401":
description: "The Access Token used is invalid."
"403":
description: "Forbidden request. You lack the necessary scopes, you lack\
\ the necessary user privileges, or the application is deactivated."
"429":
description: "Too many requests. You exceeded 1,000 queued activities for\
\ this user account."
"500":
description: "There was a problem with our internal service."
"503":
description: "Our internal service is temporarily unavailable."
security:
- oauth2_implicit:
- "contact_data"
- oauth2_access_code:
- "contact_data"
x-authorization-privileges:
- "contacts:write"
x-sdk-methodName: "createDeleteActivity"
/activities/contacts_file_import:
post:
tags:
- "Bulk Activities"
summary: "Import Contacts using a CSV File"
description: "This multipart method creates an asynchronous background job that\
\ adds or updates contacts by importing a CSV file containing contact information.\
\ Do not use a Content-Type header value with this method.\n\nImporting a\
\ new contact email address automatically sets the contact's `permission_to_send`\
\ property as `implicit` and the `opt_in_source` property as `Account`. Importing\
\ an existing contact only updates the contact properties you include in the\
\ request.\nImporting contacts with `sms_number`s requires using the `sms_permission_to_send`\
\ parameter to specify permissions for all contacts being imported. Set to\
\ `explicit` to specify that all contacts either provided explicit permission.\
\ Set to `not_set` if permission was not provided. If `explicit`, you must\
\ also include the `sms_consent_date` as a column header to include the date\
\ the contact consented to receiving SMS messages.\nContacts must have either\
\ an email address or an SMS number defined.\n \nThe CSV file has a maximum\
\ of 40,000 lines including the header row (39,999 contacts) and a maximum\
\ file size of 4 megabytes (MB). Lines above the 40,000 line maximum are\
\ not processed. If the request body exceeds 4 MB, only the contacts contained\
\ in the first 4 MB are imported and the remaining data is dropped."
operationId: "contactsCSVImport"
consumes:
- "multipart/form-data"
produces:
- "application/json"
parameters:
- name: "file"
in: "formData"
description: "The CSV file you are importing must include either `email`\
\ or `sms_number` as a column heading. Other properties you can include
# --- truncated at 32 KB (656 KB total) ---
# Full source: https://raw.githubusercontent.com/api-evangelist/constant-contact/refs/heads/main/openapi/constant-contact-v3-openapi.yml