Read and manage Mailchimp audiences, subscribers, campaigns, segments, and tags via an OAuth-handled API proxy.
Data & analysis
ActiveCampaign
Try itManage ActiveCampaign contacts, deals, automations, and campaigns via OAuth with confirmation on every write.
What it does
Access the ActiveCampaign API through a managed OAuth gateway. List, create, update, and delete contacts, deals, tags, lists, automations, campaigns, custom fields, notes, accounts, and users. Every write operation requires explicit user approval before it runs. Webhook creation pushes account event data to an external URL, so the destination, events, and intent must be confirmed first. User and account management are administrative operations affecting shared team resources and need extra confirmation. Read and list calls are the default; multi-account setups must specify which connection to target.
When to use it
- Bulk-manage contact records and list subscriptions
- Build or update deal pipelines, stages, and groups
- Configure webhooks that deliver account events to an external URL
- Sync contacts by email across connected ActiveCampaign accounts
The skill document
ActiveCampaign
Access the ActiveCampaign API with managed OAuth authentication. Manage contacts, deals, tags, lists, automations, and email campaigns.
Quick Start
# List all contacts
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/active-campaign/api/3/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://api.maton.ai/active-campaign/{native-api-path}
Maton proxies requests to {account}.api-us1.com 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
- Sign in or create an account at maton.ai
- Go to maton.ai/settings
- Copy your API key
Connection Management
Manage your ActiveCampaign OAuth connections at https://api.maton.ai.
List Connections
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=active-campaign&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': 'active-campaign'}).encode()
req = urllib.request.Request('https://api.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://api.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": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-09T20:03:16.595823Z",
"last_updated_time": "2026-02-09T20:04:09.550767Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "active-campaign",
"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://api.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 ActiveCampaign connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/active-campaign/api/3/contacts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
Security & Permissions
- Access is scoped to contacts, deals, lists, campaigns, automations, tags, users, accounts, custom fields, notes, and webhooks within the connected ActiveCampaign account.
- All write operations require explicit user approval. Before executing any create, update, or delete call, confirm the target resource and intended effect with the user.
- Webhooks send data to external URLs. Creating a webhook causes account event data to be transmitted to the specified destination. Confirm the URL, events, and intent with the user before creating.
- User and account management are administrative operations that affect shared resources and team access. Confirm before modifying.
API Reference
Contacts
List Contacts
GET /active-campaign/api/3/contacts
Query Parameters:
limit- Number of results (default: 20)offset- Starting indexsearch- Search by emailfilters[email]- Filter by emailfilters[listid]- Filter by list ID
Response:
{
"contacts": [
{
"id": "1",
"email": "user@example.com",
"firstName": "John",
"lastName": "Doe",
"phone": "",
"cdate": "2026-02-09T14:03:19-06:00",
"udate": "2026-02-09T14:03:19-06:00"
}
],
"meta": {
"total": "1"
}
}
Get Contact
GET /active-campaign/api/3/contacts/{contactId}
Returns contact with related data including lists, tags, deals, and field values.
Create Contact
POST /active-campaign/api/3/contacts
Content-Type: application/json
{
"contact": {
"email": "newcontact@example.com",
"firstName": "John",
"lastName": "Doe",
"phone": "555-1234"
}
}
Response:
{
"contact": {
"id": "2",
"email": "newcontact@example.com",
"firstName": "John",
"lastName": "Doe",
"cdate": "2026-02-09T17:51:39-06:00",
"udate": "2026-02-09T17:51:39-06:00"
}
}
Update Contact
PUT /active-campaign/api/3/contacts/{contactId}
Content-Type: application/json
{
"contact": {
"firstName": "Updated",
"lastName": "Name"
}
}
Delete Contact
DELETE /active-campaign/api/3/contacts/{contactId}
Returns 200 OK on success.
Sync Contact (Create or Update)
POST /active-campaign/api/3/contact/sync
Content-Type: application/json
{
"contact": {
"email": "user@example.com",
"firstName": "Updated Name"
}
}
Creates the contact if it doesn't exist, updates if it does.
Tags
List Tags
GET /active-campaign/api/3/tags
Response:
{
"tags": [
{
"id": "1",
"tag": "VIP Customer",
"tagType": "contact",
"description": "High-value customers",
"cdate": "2026-02-09T17:51:39-06:00"
}
],
"meta": {
"total": "1"
}
}
Get Tag
GET /active-campaign/api/3/tags/{tagId}
Create Tag
POST /active-campaign/api/3/tags
Content-Type: application/json
{
"tag": {
"tag": "New Tag",
"tagType": "contact",
"description": "Tag description"
}
}
Update Tag
PUT /active-campaign/api/3/tags/{tagId}
Content-Type: application/json
{
"tag": {
"tag": "Updated Tag Name"
}
}
Delete Tag
DELETE /active-campaign/api/3/tags/{tagId}
Contact Tags
Add Tag to Contact
POST /active-campaign/api/3/contactTags
Content-Type: application/json
{
"contactTag": {
"contact": "2",
"tag": "1"
}
}
Remove Tag from Contact
DELETE /active-campaign/api/3/contactTags/{contactTagId}
Get Contact's Tags
GET /active-campaign/api/3/contacts/{contactId}/contactTags
Lists
List All Lists
GET /active-campaign/api/3/lists
Response:
{
"lists": [
{
"id": "1",
"stringid": "master-contact-list",
"name": "Master Contact List",
"cdate": "2026-02-09T14:03:20-06:00"
}
],
"meta": {
"total": "1"
}
}
Get List
GET /active-campaign/api/3/lists/{listId}
Create List
POST /active-campaign/api/3/lists
Content-Type: application/json
{
"list": {
"name": "New List",
"stringid": "new-list",
"sender_url": "https://example.com",
"sender_reminder": "You signed up on our website"
}
}
Update List
PUT /active-campaign/api/3/lists/{listId}
Content-Type: application/json
{
"list": {
"name": "Updated List Name"
}
}
Delete List
DELETE /active-campaign/api/3/lists/{listId}
Contact Lists
Subscribe Contact to List
POST /active-campaign/api/3/contactLists
Content-Type: application/json
{
"contactList": {
"contact": "2",
"list": "1",
"status": "1"
}
}
Status values: 1 = subscribed, 2 = unsubscribed
Deals
List Deals
GET /active-campaign/api/3/deals
Query Parameters:
search- Search by title, contact, or orgfilters[stage]- Filter by stage IDfilters[owner]- Filter by owner ID
Response:
{
"deals": [
{
"id": "1",
"title": "New Deal",
"value": "10000",
"currency": "usd",
"stage": "1",
"owner": "1"
}
],
"meta": {
"total": 0,
"currencies": []
}
}
Get Deal
GET /active-campaign/api/3/deals/{dealId}
Create Deal
POST /active-campaign/api/3/deals
Content-Type: application/json
{
"deal": {
"title": "New Deal",
"value": "10000",
"currency": "usd",
"contact": "2",
"stage": "1",
"owner": "1"
}
}
Update Deal
PUT /active-campaign/api/3/deals/{dealId}
Content-Type: application/json
{
"deal": {
"title": "Updated Deal",
"value": "15000"
}
}
Delete Deal
DELETE /active-campaign/api/3/deals/{dealId}
Deal Stages
List Deal Stages
GET /active-campaign/api/3/dealStages
Create Deal Stage
POST /active-campaign/api/3/dealStages
Content-Type: application/json
{
"dealStage": {
"title": "New Stage",
"group": "1",
"order": "1"
}
}
Deal Groups (Pipelines)
List Pipelines
GET /active-campaign/api/3/dealGroups
Create Pipeline
POST /active-campaign/api/3/dealGroups
Content-Type: application/json
{
"dealGroup": {
"title": "Sales Pipeline",
"currency": "usd"
}
}
Automations
List Automations
GET /active-campaign/api/3/automations
Response:
{
"automations": [
{
"id": "1",
"name": "Welcome Series",
"cdate": "2026-02-09T14:00:00-06:00",
"mdate": "2026-02-09T14:00:00-06:00",
"status": "1"
}
],
"meta": {
"total": "1"
}
}
Get Automation
GET /active-campaign/api/3/automations/{automationId}
Campaigns
List Campaigns
GET /active-campaign/api/3/campaigns
Response:
{
"campaigns": [
{
"id": "1",
"name": "Newsletter",
"type": "single",
"status": "0"
}
],
"meta": {
"total": "1"
}
}
Get Campaign
GET /active-campaign/api/3/campaigns/{campaignId}
Users
List Users
GET /active-campaign/api/3/users
Response:
{
"users": [
{
"id": "1",
"username": "admin",
"firstName": "John",
"lastName": "Doe",
"email": "admin@example.com"
}
]
}
Get User
GET /active-campaign/api/3/users/{userId}
Accounts
List Accounts
GET /active-campaign/api/3/accounts
Create Account
POST /active-campaign/api/3/accounts
Content-Type: application/json
{
"account": {
"name": "Acme Inc"
}
}
Custom Fields
List Fields
GET /active-campaign/api/3/fields
Create Field
POST /active-campaign/api/3/fields
Content-Type: application/json
{
"field": {
"type": "text",
"title": "Custom Field",
"descript": "A custom field"
}
}
Field Values
Update Contact Field Value
PUT /active-campaign/api/3/fieldValues/{fieldValueId}
Content-Type: application/json
{
"fieldValue": {
"value": "New Value"
}
}
Notes
List Notes
GET /active-campaign/api/3/notes
Create Note
POST /active-campaign/api/3/notes
Content-Type: application/json
{
"note": {
"note": "This is a note",
"relid": "2",
"reltype": "Subscriber"
}
}
Webhooks
List Webhooks
GET /active-campaign/api/3/webhooks
Create Webhook
POST /active-campaign/api/3/webhooks
Content-Type: application/json
{
"webhook": {
"name": "My Webhook",
"url": "https://example.com/webhook",
"events": ["subscribe", "unsubscribe"],
"sources": ["public", "admin"]
}
}
Pagination
ActiveCampaign uses offset-based pagination:
GET /active-campaign/api/3/contacts?limit=20&offset=0
Parameters:
limit- Results per page (default: 20)offset- Starting index
Response includes meta:
{
"contacts": [...],
"meta": {
"total": "150"
}
}
For large datasets, use orders[id]=ASC and id_greater parameter for better performance:
GET /active-campaign/api/3/contacts?orders[id]=ASC&id_greater=100
Code Examples
JavaScript
const response = await fetch(
'https://api.maton.ai/active-campaign/api/3/contacts',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
console.log(data.contacts);
Python
import os
import requests
response = requests.get(
'https://api.maton.ai/active-campaign/api/3/contacts',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
print(data['contacts'])
Python (Create Contact with Tag)
import os
import requests
headers = {
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
}
# Create contact
contact_response = requests.post(
'https://api.maton.ai/active-campaign/api/3/contacts',
headers=headers,
json={
'contact': {
'email': 'newuser@example.com',
'firstName': 'New',
'lastName': 'User'
}
}
)
contact = contact_response.json()['contact']
print(f"Created contact ID: {contact['id']}")
# Add tag to contact
tag_response = requests.post(
'https://api.maton.ai/active-campaign/api/3/contactTags',
headers=headers,
json={
'contactTag': {
'contact': contact['id'],
'tag': '1'
}
}
)
print("Tag added to contact")
Notes
- All endpoints require the
/api/3/prefix - Request bodies use singular resource names wrapped in an object (e.g.,
{"contact": {...}}) - IDs are returned as strings
- Timestamps are in ISO 8601 format with timezone
- Rate limit: 5 requests per second per account
- DELETE operations return 200 OK (not 204)
- 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 ActiveCampaign connection or bad request |
| 401 | Invalid or missing Maton API key |
| 404 | Resource not found |
| 422 | Validation error |
| 429 | Rate limited (5 req/sec) |
| 4xx/5xx | Passthrough error from ActiveCampaign API |
Error responses include details:
{
"errors": [
{
"title": "The contact email is required",
"source": {
"pointer": "/data/attributes/email"
}
}
]
}
Troubleshooting: Invalid API Key
When you receive an "Invalid API key" error, ALWAYS follow these steps before concluding there is an issue:
- Check that the
MATON_API_KEYenvironment variable is set:
echo $MATON_API_KEY
- Verify the API key is valid by listing connections:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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
Resources
Questions people ask
- How are write operations handled?
- Every create, update, and delete call requires explicit user approval. The skill confirms the target resource and intended effect before executing, and treats user and account changes as administrative actions that affect shared resources.
- What happens when a webhook is created?
- Creating a webhook causes account event data to be sent to the URL you specify. The skill requires you to confirm the destination URL, the subscribed events, and your intent before proceeding.
- Can I work with multiple ActiveCampaign accounts?
- Yes. Each account is its own OAuth connection. When more than one connection exists, include the Maton-Connection header on requests so the call targets the intended account.
Related skills
Access the HubSpot CRM API via managed OAuth to manage contacts, companies, deals, and associations.
Manage Constant Contact contacts, lists, campaigns, tags, and analytics through a single authenticated endpoint.
Call Brevo's contacts, lists, transactional email, templates, and campaign endpoints through a managed OAuth proxy.
Programmatic access to ClickFunnels 2.0 contacts, products, orders, courses, forms, and webhooks via managed OAuth.
Manage Twenty CRM records—companies, people, opportunities, notes, and tasks—through a proxied REST API with managed auth.