Constant Contact
name: constant-contact
by byungkyu · published 2026-03-22
$ claw add gh:byungkyu/byungkyu-constant-contact---
name: constant-contact
description: |
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.
metadata:
author: maton
version: "1.0"
clawdbot:
emoji: 🧠
requires:
env:
- MATON_API_KEY
---
# 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))
EOFBase 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))
EOFCreate 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))
EOFGet 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))
EOFSpecifying 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))
EOFIf 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/privilegesContacts
#### List Contacts
GET /constant-contact/v3/contactsQuery parameters:
#### 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/countsContact Lists
#### List Contact Lists
GET /constant-contact/v3/contact_listsQuery parameters:
#### 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/emailsQuery parameters:
#### 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/activitiesReporting
#### Email Campaign Summaries
GET /constant-contact/v3/reports/summary_reports/email_campaign_summariesQuery parameters:
#### 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_summaryPagination
The API uses cursor-based pagination with a `limit` parameter:
GET /constant-contact/v3/contacts?limit=50Response 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=abc123Code 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
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_KEY2. 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))
EOFTroubleshooting: Invalid App Name
1. Ensure your URL path starts with `constant-contact`. For example:
Resources
More tools from the same signal band
Order food/drinks (点餐) on an Android device paired as an OpenClaw node. Uses in-app menu and cart; add goods, view cart, submit order (demo, no real payment).
Sign plugins, rotate agent credentials without losing identity, and publicly attest to plugin behavior with verifiable claims and authenticated transfers.
The philosophical layer for AI agents. Maps behavior to Spinoza's 48 affects, calculates persistence scores, and generates geometric self-reports. Give your...