← Back to Skills Marketplace
byungkyu

ActiveCampaign

by byungkyu · GitHub ↗ · v1.0.6
cross-platform ✓ Security Clean
3769
Downloads
3
Stars
0
Active Installs
7
Versions
Install in OpenClaw
/install active-campaign
Description
ActiveCampaign API integration with managed OAuth. Marketing automation, CRM, contacts, deals, and email campaigns. Use this skill when users want to manage...
README (SKILL.md)

ActiveCampaign

Access the ActiveCampaign API with managed OAuth authentication. Manage contacts, deals, tags, lists, automations, and email campaigns.

Quick Start

# List all contacts
python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.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://gateway.maton.ai/active-campaign/{native-api-path}

Replace {native-api-path} with the actual ActiveCampaign API endpoint path. The gateway 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

  1. Sign in or create an account at maton.ai
  2. Go to maton.ai/settings
  3. Copy your API key

Connection Management

Manage your ActiveCampaign OAuth connections at https://ctrl.maton.ai.

List Connections

python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.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 \x3C\x3C'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'active-campaign'}).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 \x3C\x3C'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": "9e8ba2aa-25ec-4ba0-8815-3068be304dca",
    "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 \x3C\x3C'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 ActiveCampaign connections, specify which one to use with the Maton-Connection header:

python \x3C\x3C'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/active-campaign/api/3/contacts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '9e8ba2aa-25ec-4ba0-8815-3068be304dca')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF

If omitted, the gateway uses the default (oldest) active connection.

API Reference

Contacts

List Contacts

GET /active-campaign/api/3/contacts

Query Parameters:

  • limit - Number of results (default: 20)
  • offset - Starting index
  • search - Search by email
  • filters[email] - Filter by email
  • filters[listid] - Filter by list ID

Response:

{
  "contacts": [
    {
      "id": "1",
      "email": "[email protected]",
      "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": "[email protected]",
    "firstName": "John",
    "lastName": "Doe",
    "phone": "555-1234"
  }
}

Response:

{
  "contact": {
    "id": "2",
    "email": "[email protected]",
    "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": "[email protected]",
    "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 org
  • filters[stage] - Filter by stage ID
  • filters[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": "[email protected]"
    }
  ]
}

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://gateway.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://gateway.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://gateway.maton.ai/active-campaign/api/3/contacts',
    headers=headers,
    json={
        'contact': {
            'email': '[email protected]',
            '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://gateway.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 jq or other commands, environment variables like $MATON_API_KEY may 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:

  1. Check that the MATON_API_KEY environment variable is set:
echo $MATON_API_KEY
  1. Verify the API key is valid by listing connections:
python \x3C\x3C'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

Resources

Usage Guidance
This skill proxies ActiveCampaign API calls via maton.ai and requires you to set MATON_API_KEY in the environment. Before installing: (1) confirm you trust maton.ai (review their privacy, security practices, and terms), because the gateway will see API requests and tokens; (2) limit where you store MATON_API_KEY (avoid putting it in shared or public environments) and rotate it if compromised; (3) prefer direct ActiveCampaign OAuth if you require minimal third‑party exposure; (4) verify connections and authorizations at https://ctrl.maton.ai and remove unused connections; (5) be aware the agent can invoke the skill autonomously, so review logs and actions performed in your ActiveCampaign account after enabling the skill. If you need higher assurance, request a version that calls ActiveCampaign directly (using official API keys/OAuth) rather than routing via a third party.
Capability Analysis
Type: OpenClaw Skill Name: active-campaign Version: 1.0.6 The skill bundle provides an ActiveCampaign API integration via a Maton gateway. All code examples and instructions in SKILL.md direct network requests to `https://gateway.maton.ai` and `https://ctrl.maton.ai`, using the `MATON_API_KEY` for authentication, which aligns with the stated purpose. There is no evidence of data exfiltration, malicious execution, persistence mechanisms, obfuscation, or prompt injection attempts against the agent. The content is instructional and appears to be a legitimate tool for managing ActiveCampaign resources.
Capability Assessment
Purpose & Capability
Name and description match the behavior in SKILL.md: all API examples call Maton endpoints (gateway.maton.ai and ctrl.maton.ai) to manage ActiveCampaign resources via managed OAuth. Requesting a MATON_API_KEY is coherent with a gateway/proxy design.
Instruction Scope
Instructions are limited to making HTTP requests to Maton endpoints and using the MATON_API_KEY from environment. They do not instruct reading other system files or unrelated env vars. Note: all requests and OAuth flows are routed through maton.ai domains rather than directly to ActiveCampaign; this is expected but worth auditing because data and OAuth tokens transit a third-party service.
Install Mechanism
Instruction-only skill with no install spec or code files; nothing is written to disk by an installer. This is low-risk from an installation perspective.
Credentials
Only one env var (MATON_API_KEY) is required, which is proportional to the gateway-based design. However, that single key grants the Maton gateway the ability to act on your ActiveCampaign account(s), so protecting and limiting this key is important.
Persistence & Privilege
The skill is not always-enabled and does not request special system persistence. Model invocation is allowed (normal default), so the agent can call the skill autonomously — expected behavior for an integration but something to be aware of because actions will be executed via the external gateway.
How to Use
  1. Make sure OpenClaw is installed (local or Docker)
  2. Run the install command in chat: /install active-campaign
  3. After installation, invoke the skill by name or use /active-campaign
  4. Provide required inputs per the skill's parameter spec and get structured output
Version History
v1.0.6
- Fixed documentation typo: the base URL instruction now correctly refers to the "ActiveCampaign API" (not Airtable). - No functional or interface changes; this is a documentation-only update.
v1.0.5
- Added the "homepage" field to the skill metadata, linking to https://maton.ai. - No other functional changes or file updates included in this version.
v1.0.4
- Updated base URL instructions to use `/active-campaign/{native-api-path}` and clarified endpoint substitution. - Added details specifying that the gateway proxies ActiveCampaign endpoints and injects the OAuth token automatically. - Provided example and explanation for replacing `{native-api-path}` with the actual API endpoint. - No changes to functionality or code—documentation improvements only.
v1.0.3
- Added a new metadata section to SKILL.md specifying required environment variable MATON_API_KEY and an emoji identifier. - No changes to functionality or user instructions. - Version and author fields remain unchanged.
v1.0.2
- No file changes detected in this release. - Documentation and functionality remain unchanged from the previous version.
v1.0.1
No changes detected in this release. - Version number updated to 1.0.1. - No differences found between previous and current files.
v1.0.0
Initial release: ActiveCampaign API integration with managed OAuth and Maton API key. - Supports management of contacts, deals, tags, lists, automations, and email campaigns via proxy gateway. - Includes sample code and API endpoint documentation for listing, creating, updating, and deleting key resources. - Secure authentication with Maton API key and managed OAuth connections. - Instructions provided for managing and specifying OAuth connections. - Designed for marketing automation and CRM workflows using ActiveCampaign.
Metadata
Slug active-campaign
Version 1.0.6
License
All-time Installs 0
Active Installs 0
Total Versions 7
Frequently Asked Questions

What is ActiveCampaign?

ActiveCampaign API integration with managed OAuth. Marketing automation, CRM, contacts, deals, and email campaigns. Use this skill when users want to manage... It is an AI Agent Skill for Claude Code / OpenClaw, with 3769 downloads so far.

How do I install ActiveCampaign?

Run "/install active-campaign" in the OpenClaw or Claude Code chat to install it in one step — no extra setup required.

Is ActiveCampaign free?

Yes, ActiveCampaign is completely free (open-source). You can download, install and use it at no cost.

Which platforms does ActiveCampaign support?

ActiveCampaign is cross-platform and runs anywhere OpenClaw / Claude Code is available (cross-platform).

Who created ActiveCampaign?

It is built and maintained by byungkyu (@byungkyu); the current version is v1.0.6.

💬 Comments