Constant Contact API integration with managed OAuth. Manage contacts, email campaigns, lists, segments, and marketing automation. Use this skill when users want to manage email marketing campaigns, contact lists, or analyze campaign performance. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
Install
Documentation
Constant Contact
Access the Constant Contact V3 API with managed OAuth authentication. Manage contacts, email campaigns, contact lists, segments, and marketing analytics.
Quick Start
List contacts
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/constant-contact/v3/contacts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Base URL
https://gateway.maton.ai/constant-contact/v3/{resource}
The gateway proxies requests to api.cc.email/v3 and automatically injects your OAuth token.
Authentication
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Getting Your API Key
1. Sign in or create an account at [maton.ai](https://maton.ai)
2. Go to [maton.ai/settings](https://maton.ai/settings)
3. Copy your API key
Connection Management
Manage your Constant Contact OAuth connections at https://ctrl.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=constant-contact&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Create Connection
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'constant-contact'}).encode()
req = urllib.request.Request('https://ctrl.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Get Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "4314bd0f-fd56-40ab-8c65-2676dd2c23c4",
"status": "ACTIVE",
"creation_time": "2026-02-07T07:41:05.859244Z",
"last_updated_time": "2026-02-07T07:41:32.658230Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "constant-contact",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
Delete Connection
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Specifying Connection
If you have multiple Constant Contact connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/constant-contact/v3/contacts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '4314bd0f-fd56-40ab-8c65-2676dd2c23c4')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If omitted, the gateway uses the default (oldest) active connection.
API Reference
Account
#### Get Account Summary
GET /constant-contact/v3/account/summary
#### Get Account Emails
GET /constant-contact/v3/account/emails
#### Get User Privileges
GET /constant-contact/v3/account/user/privileges
Contacts
#### List Contacts
GET /constant-contact/v3/contacts
Query parameters:
- -
status- Filter by status:all,active,deleted,not_set,pending_confirmation,temp_hold,unsubscribed - -
email- Filter by email address - -
lists- Filter by list ID(s) - -
segment_id- Filter by segment ID - -
tags- Filter by tag ID(s) - -
updated_after- ISO-8601 date filter - -
include- Include subresources:custom_fields,list_memberships,taggings,notes - -
limit- Results per page (default 50, max 500)
#### Get Contact
GET /constant-contact/v3/contacts/{contact_id}
#### Create Contact
POST /constant-contact/v3/contacts
Content-Type: application/json
{
"email_address": {
"address": "john@example.com",
"permission_to_send": "implicit"
},
"first_name": "John",
"last_name": "Doe",
"job_title": "Developer",
"company_name": "Acme Inc",
"list_memberships": ["list-uuid-here"]
}
#### Update Contact
PUT /constant-contact/v3/contacts/{contact_id}
Content-Type: application/json
{
"email_address": {
"address": "john@example.com"
},
"first_name": "John",
"last_name": "Smith"
}
#### Delete Contact
DELETE /constant-contact/v3/contacts/{contact_id}
#### Create or Update Contact (Sign-Up Form)
Use this endpoint to create a new contact or update an existing one without checking if they exist first:
POST /constant-contact/v3/contacts/sign_up_form
Content-Type: application/json
{
"email_address": "john@example.com",
"first_name": "John",
"last_name": "Doe",
"list_memberships": ["list-uuid-here"]
}
#### Get Contact Counts
GET /constant-contact/v3/contacts/counts
Contact Lists
#### List Contact Lists
GET /constant-contact/v3/contact_lists
Query parameters:
- -
include_count- Include contact count per list - -
include_membership_count- Include membership count - -
limit- Results per page
#### Get Contact List
GET /constant-contact/v3/contact_lists/{list_id}
#### Create Contact List
POST /constant-contact/v3/contact_lists
Content-Type: application/json
{
"name": "Newsletter Subscribers",
"description": "Main newsletter list",
"favorite": false
}
#### Update Contact List
PUT /constant-contact/v3/contact_lists/{list_id}
Content-Type: application/json
{
"name": "Updated List Name",
"description": "Updated description",
"favorite": true
}
#### Delete Contact List
DELETE /constant-contact/v3/contact_lists/{list_id}
Tags
#### List Tags
GET /constant-contact/v3/contact_tags
#### Create Tag
POST /constant-contact/v3/contact_tags
Content-Type: application/json
{
"name": "VIP Customer"
}
#### Update Tag
PUT /constant-contact/v3/contact_tags/{tag_id}
Content-Type: application/json
{
"name": "Premium Customer"
}
#### Delete Tag
DELETE /constant-contact/v3/contact_tags/{tag_id}
Custom Fields
#### List Custom Fields
GET /constant-contact/v3/contact_custom_fields
#### Create Custom Field
POST /constant-contact/v3/contact_custom_fields
Content-Type: application/json
{
"label": "Customer ID",
"type": "string"
}
#### Delete Custom Field
DELETE /constant-contact/v3/contact_custom_fields/{custom_field_id}
Email Campaigns
#### List Email Campaigns
GET /constant-contact/v3/emails
Query parameters:
- -
limit- Results per page (default 50)
#### Get Email Campaign
GET /constant-contact/v3/emails/{campaign_id}
#### Create Email Campaign
POST /constant-contact/v3/emails
Content-Type: application/json
{
"name": "March Newsletter",
"email_campaign_activities": [
{
"format_type": 5,
"from_name": "Company Name",
"from_email": "marketing@example.com",
"reply_to_email": "reply@example.com",
"subject": "March Newsletter",
"html_content": "<html><body><h1>Hello!</h1></body></html>"
}
]
}
#### Update Email Campaign Activity
PUT /constant-contact/v3/emails/activities/{campaign_activity_id}
Content-Type: application/json
{
"contact_list_ids": ["list-uuid-here"],
"from_name": "Updated Name",
"subject": "Updated Subject"
}
#### Send Test Email
POST /constant-contact/v3/emails/activities/{campaign_activity_id}/tests
Content-Type: application/json
{
"email_addresses": ["test@example.com"]
}
#### Schedule Email Campaign
POST /constant-contact/v3/emails/activities/{campaign_activity_id}/schedules
Content-Type: application/json
{
"scheduled_date": "2026-03-01T10:00:00Z"
}
Segments
#### List Segments
GET /constant-contact/v3/segments
#### Get Segment
GET /constant-contact/v3/segments/{segment_id}
#### Create Segment
POST /constant-contact/v3/segments
Content-Type: application/json
{
"name": "Engaged Subscribers",
"segment_criteria": "..."
}
#### Delete Segment
DELETE /constant-contact/v3/segments/{segment_id}
Bulk Activities
#### Import Contacts
POST /constant-contact/v3/activities/contacts_file_import
Content-Type: multipart/form-data
{file: contacts.csv, list_ids: ["list-uuid"]}
#### Add Contacts to Lists
POST /constant-contact/v3/activities/add_list_memberships
Content-Type: application/json
{
"source": {
"contact_ids": ["contact-uuid-1", "contact-uuid-2"]
},
"list_ids": ["list-uuid"]
}
#### Remove Contacts from Lists
POST /constant-contact/v3/activities/remove_list_memberships
Content-Type: application/json
{
"source": {
"list_ids": ["source-list-uuid"]
},
"list_ids": ["target-list-uuid"]
}
#### Delete Contacts in Bulk
POST /constant-contact/v3/activities/contact_delete
Content-Type: application/json
{
"contact_ids": ["contact-uuid-1", "contact-uuid-2"]
}
#### Get Activity Status
GET /constant-contact/v3/activities/{activity_id}
#### List Activities
GET /constant-contact/v3/activities
Reporting
#### Email Campaign Summaries
GET /constant-contact/v3/reports/summary_reports/email_campaign_summaries
Query parameters:
- -
start- Start date (ISO-8601) - -
end- End date (ISO-8601)
#### Get Email Campaign Report
GET /constant-contact/v3/reports/email_reports/{campaign_activity_id}
#### Contact Activity Summary
GET /constant-contact/v3/reports/contact_reports/{contact_id}/activity_summary
Pagination
The API uses cursor-based pagination with a limit parameter:
GET /constant-contact/v3/contacts?limit=50
Response includes pagination links:
{
"contacts": [...],
"_links": {
"next": {
"href": "/v3/contacts?cursor=abc123"
}
}
}
Use the cursor from the next link for subsequent pages:
GET /constant-contact/v3/contacts?cursor=abc123
Code Examples
JavaScript
const response = await fetch(
'https://gateway.maton.ai/constant-contact/v3/contacts?limit=50',
{
headers: {
'Authorization': Bearer ${process.env.MATON_API_KEY}
}
}
);
const data = await response.json();
Python
import os
import requests
response = requests.get(
'https://gateway.maton.ai/constant-contact/v3/contacts',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={'limit': 50}
)
data = response.json()
Notes
- -Resource IDs use UUID format (36 characters with hyphens)
- -All dates use ISO-8601 format:
YYYY-MM-DDThh:mm:ss.sZ - -Maximum 1,000 contact lists per account
- -A contact can belong to up to 50 lists
- -Bulk operations are asynchronous - check activity status for completion
- -Email campaigns require verified sender email addresses
- -
format_type: 5for custom HTML emails - -IMPORTANT: When using curl commands, use
curl -gwhen URLs contain brackets to disable glob parsing - -IMPORTANT: When piping curl output to
jqor other commands, environment variables like$MATON_API_KEYmay not expand correctly in some shell environments
Error Handling
| Status | Meaning |
|--------|---------|
| 400 | Missing Constant Contact connection or invalid request |
| 401 | Invalid or missing Maton API key, or OAuth token expired |
| 403 | Insufficient permissions for the requested operation |
| 404 | Resource not found |
| 409 | Conflict (e.g., duplicate email address) |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Constant Contact API |
Error Response Format
{
"error_key": "unauthorized",
"error_message": "Unauthorized"
}
Troubleshooting: API Key Issues
1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
2. Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Troubleshooting: Invalid App Name
1. Ensure your URL path starts with constant-contact. For example:
- -Correct:
https://gateway.maton.ai/constant-contact/v3/contacts - -Incorrect:
https://gateway.maton.ai/v3/contacts
Resources
- -[Constant Contact V3 API Overview](https://developer.constantcontact.com/api_guide/getting_started.html)
- -[API Reference](https://developer.constantcontact.com/api_reference/index.html)
- -[Technical Overview](https://developer.constantcontact.com/api_guide/v3_technical_overview.html)
- -[Contacts Overview](https://developer.constantcontact.com/api_guide/contacts_overview.html)
- -[Email Campaigns Guide](https://developer.constantcontact.com/api_guide/email_campaigns_get_started.html)
- -[Contact Lists Overview](https://v3.developer.constantcontact.com/api_guide/lists_overview.html)
- -[Maton Community](https://discord.com/invite/dBfFAcefs2)
- -[Maton Support](mailto:support@maton.ai)
Launch an agent with Constant Contact on Termo.