Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Access the Mailchimp Marketing API with managed OAuth authentication. Manage audiences, campaigns, templates, automations, reports, and subscribers for email marketing.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-02 | ✗→✓ | ▲ Improved | — | — |
| case-01 | ✗→✓ | ▲ Improved | — | — |
| case-24 | ✗→✓ | ▲ Improved | — | — |
| case-15 | ✗→✓ | ▲ Improved | — | — |
| case-06 | ✗→✓ | ▲ Improved | — | — |
Access the Mailchimp Marketing API with managed OAuth authentication. Manage audiences, campaigns, templates, automations, reports, and subscribers for email marketing.
bash# List all audiences python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
https://gateway.maton.ai/mailchimp/{native-api-path}Replace {native-api-path} with the actual Mailchimp API endpoint path (e.g., 3.0/lists). The gateway proxies requests to your Mailchimp data center and automatically injects your OAuth token.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEYEnvironment Variable: Set your API key as MATON_API_KEY:
bashexport MATON_API_KEY="YOUR_API_KEY"
Manage your Mailchimp OAuth connections at https://ctrl.maton.ai.
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://ctrl.maton.ai/connections?app=mailchimp&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
bashpython <<'EOF' import urllib.request, os, json data = json.dumps({'app': 'mailchimp'}).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
bashpython <<'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:
json{ "connection": { "connection_id": "21fd90f9-5935-43cd-b6c8-bde9d915ca80", "status": "ACTIVE", "creation_time": "2025-12-08T07:20:53.488460Z", "last_updated_time": "2026-01-31T20:03:32.593153Z", "url": "https://connect.maton.ai/?session_token=...", "app": "mailchimp", "metadata": {} } }
Open the returned url in a browser to complete OAuth authorization.
bashpython <<'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
If you have multiple Mailchimp connections, specify which one to use with the Maton-Connection header:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') req.add_header('Maton-Connection', '21fd90f9-5935-43cd-b6c8-bde9d915ca80') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
If omitted, the gateway uses the default (oldest) active connection.
Within the Mailchimp app, "audience" is the common term, but the API uses "lists" for endpoints.
bashGET /mailchimp/3.0/lists
Query parameters:
count - Number of records to return (default 10, max 1000)offset - Number of records to skip (for pagination)fields - Comma-separated list of fields to includeexclude_fields - Comma-separated list of fields to excludeExample:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists?count=10') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
json{ "lists": [ { "id": "abc123def4", "name": "Newsletter Subscribers", "contact": { "company": "Acme Corp", "address1": "123 Main St" }, "stats": { "member_count": 5000, "unsubscribe_count": 100, "open_rate": 0.25 } } ], "total_items": 1 }
bashGET /mailchimp/3.0/lists/{list_id}
Example:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists/abc123def4') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
bashPOST /mailchimp/3.0/lists Content-Type: application/json { "name": "Newsletter", "contact": { "company": "Acme Corp", "address1": "123 Main St", "city": "New York", "state": "NY", "zip": "10001", "country": "US" }, "permission_reminder": "You signed up for our newsletter", "campaign_defaults": { "from_name": "Acme Corp", "from_email": "newsletter@acme.com", "subject": "", "language": "en" }, "email_type_option": true }
bashPATCH /mailchimp/3.0/lists/{list_id}
bashDELETE /mailchimp/3.0/lists/{list_id}
Members are contacts within an audience. The API uses MD5 hash of the lowercase email address as the subscriber identifier.
bashGET /mailchimp/3.0/lists/{list_id}/members
Query parameters:
status - Filter by subscription status (subscribed, unsubscribed, cleaned, pending, transactional)count - Number of records to returnoffset - Number of records to skipExample:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists/abc123def4/members?status=subscribed&count=50') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
json{ "members": [ { "id": "f4b7c8d9e0", "email_address": "john@example.com", "status": "subscribed", "merge_fields": { "FNAME": "John", "LNAME": "Doe" }, "tags": [ {"id": 1, "name": "VIP"} ] } ], "total_items": 500 }
bashGET /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash}
The subscriber_hash is the MD5 hash of the lowercase email address.
Example:
bash# For email "john@example.com", subscriber_hash = md5("john@example.com") python <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists/abc123def4/members/b4c9a0d1e2f3g4h5') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
bashPOST /mailchimp/3.0/lists/{list_id}/members Content-Type: application/json { "email_address": "newuser@example.com", "status": "subscribed", "merge_fields": { "FNAME": "Jane", "LNAME": "Smith" }, "tags": ["Newsletter", "Premium"] }
Example:
bashpython <<'EOF' import urllib.request, os, json data = json.dumps({'email_address': 'newuser@example.com', 'status': 'subscribed', 'merge_fields': {'FNAME': 'Jane', 'LNAME': 'Smith'}}).encode() req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists/abc123def4/members', 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
bashPATCH /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash}
Example:
bashpython <<'EOF' import urllib.request, os, json data = json.dumps({'merge_fields': {'FNAME': 'Jane', 'LNAME': 'Doe'}}).encode() req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists/abc123def4/members/b4c9a0d1e2f3g4h5', data=data, method='PATCH') 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
bashPUT /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash} Content-Type: application/json { "email_address": "user@example.com", "status_if_new": "subscribed", "merge_fields": { "FNAME": "Jane", "LNAME": "Smith" } }
Creates a new member or updates an existing one based on the email hash. Use status_if_new to set the status when creating a new member.
Archives a member (can be re-added later):
bashDELETE /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash}
Returns 204 No Content on success.
To permanently delete (GDPR compliant):
bashPOST /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash}/actions/delete-permanent
bashGET /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash}/tags
bashPOST /mailchimp/3.0/lists/{list_id}/members/{subscriber_hash}/tags Content-Type: application/json { "tags": [ {"name": "VIP", "status": "active"}, {"name": "Old Tag", "status": "inactive"} ] }
Returns 204 No Content on success.
bashGET /mailchimp/3.0/lists/{list_id}/segments
Example:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists/abc123def4/segments') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
bashPOST /mailchimp/3.0/lists/{list_id}/segments Content-Type: application/json { "name": "Active Subscribers", "options": { "match": "all", "conditions": [ { "condition_type": "EmailActivity", "field": "opened", "op": "date_within", "value": "30" } ] } }
bashPATCH /mailchimp/3.0/lists/{list_id}/segments/{segment_id}
bashGET /mailchimp/3.0/lists/{list_id}/segments/{segment_id}/members
bashDELETE /mailchimp/3.0/lists/{list_id}/segments/{segment_id}
Returns 204 No Content on success.
bashGET /mailchimp/3.0/campaigns
Query parameters:
type - Campaign type (regular, plaintext, absplit, rss, variate)status - Campaign status (save, paused, schedule, sending, sent)list_id - Filter by list IDcount - Number of records to returnoffset - Number of records to skipExample:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/campaigns?status=sent&count=20') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
json{ "campaigns": [ { "id": "campaign123", "type": "regular", "status": "sent", "settings": { "subject_line": "Monthly Newsletter", "from_name": "Acme Corp" }, "send_time": "2025-02-01T10:00:00Z", "report_summary": { "opens": 1500, "clicks": 300, "open_rate": 0.30, "click_rate": 0.06 } } ], "total_items": 50 }
bashGET /mailchimp/3.0/campaigns/{campaign_id}
bashPOST /mailchimp/3.0/campaigns Content-Type: application/json { "type": "regular", "recipients": { "list_id": "abc123def4" }, "settings": { "subject_line": "Your Monthly Update", "from_name": "Acme Corp", "reply_to": "hello@acme.com" } }
Example:
bashpython <<'EOF' import urllib.request, os, json data = json.dumps({'type': 'regular', 'recipients': {'list_id': 'abc123def4'}, 'settings': {'subject_line': 'February Newsletter', 'from_name': 'Acme Corp', 'reply_to': 'newsletter@acme.com'}}).encode() req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/campaigns', 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
bashPATCH /mailchimp/3.0/campaigns/{campaign_id}
bashDELETE /mailchimp/3.0/campaigns/{campaign_id}
Returns 204 No Content on success.
bashGET /mailchimp/3.0/campaigns/{campaign_id}/content
bashPUT /mailchimp/3.0/campaigns/{campaign_id}/content Content-Type: application/json { "html": "<html><body><h1>Hello!</h1><p>Newsletter content here.</p></body></html>", "plain_text": "Hello! Newsletter content here." }
Or use a template:
bashPUT /mailchimp/3.0/campaigns/{campaign_id}/content Content-Type: application/json { "template": { "id": 12345, "sections": { "body": "<p>Custom content for the template section</p>" } } }
Check if a campaign is ready to send:
bashGET /mailchimp/3.0/campaigns/{campaign_id}/send-checklist
bashPOST /mailchimp/3.0/campaigns/{campaign_id}/actions/send
bashPOST /mailchimp/3.0/campaigns/{campaign_id}/actions/schedule Content-Type: application/json { "schedule_time": "2025-03-01T10:00:00+00:00" }
bashPOST /mailchimp/3.0/campaigns/{campaign_id}/actions/cancel-send
bashGET /mailchimp/3.0/templates
Query parameters:
type - Template type (user, base, gallery)count - Number of records to returnoffset - Number of records to skipExample:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/templates?type=user') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
bashGET /mailchimp/3.0/templates/{template_id}
bashGET /mailchimp/3.0/templates/{template_id}/default-content
bashPOST /mailchimp/3.0/templates Content-Type: application/json { "name": "Newsletter Template", "html": "<html><body mc:edit=\"body\"><h1>Title</h1><p>Content here</p></body></html>" }
bashPATCH /mailchimp/3.0/templates/{template_id}
bashDELETE /mailchimp/3.0/templates/{template_id}
Returns 204 No Content on success.
Mailchimp's classic automations let you build email series triggered by dates, activities, or events.
bashGET /mailchimp/3.0/automations
Example:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/automations') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
bashGET /mailchimp/3.0/automations/{workflow_id}
bashPOST /mailchimp/3.0/automations/{workflow_id}/actions/start-all-emails
bashPOST /mailchimp/3.0/automations/{workflow_id}/actions/pause-all-emails
bashGET /mailchimp/3.0/automations/{workflow_id}/emails
Manually add a subscriber to an automation workflow:
bashPOST /mailchimp/3.0/automations/{workflow_id}/emails/{workflow_email_id}/queue Content-Type: application/json { "email_address": "subscriber@example.com" }
bashGET /mailchimp/3.0/reports
Query parameters:
count - Number of records to returnoffset - Number of records to skiptype - Campaign typeExample:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/reports?count=20') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response:
json{ "reports": [ { "id": "campaign123", "campaign_title": "Monthly Newsletter", "emails_sent": 5000, "opens": { "opens_total": 1500, "unique_opens": 1200, "open_rate": 0.24 }, "clicks": { "clicks_total": 450, "unique_clicks": 300, "click_rate": 0.06 }, "unsubscribed": 10, "bounce_rate": 0.02 } ] }
bashGET /mailchimp/3.0/reports/{campaign_id}
bashGET /mailchimp/3.0/reports/{campaign_id}/open-details
bashGET /mailchimp/3.0/reports/{campaign_id}/click-details
bashGET /mailchimp/3.0/lists/{list_id}/activity
Returns recent daily aggregated activity stats (unsubscribes, signups, opens, clicks) for up to 180 days.
Process multiple operations in a single call.
bashPOST /mailchimp/3.0/batches Content-Type: application/json { "operations": [ { "method": "POST", "path": "/lists/abc123def4/members", "body": "{\"email_address\":\"user1@example.com\",\"status\":\"subscribed\"}" }, { "method": "POST", "path": "/lists/abc123def4/members", "body": "{\"email_address\":\"user2@example.com\",\"status\":\"subscribed\"}" } ] }
bashGET /mailchimp/3.0/batches/{batch_id}
bashGET /mailchimp/3.0/batches
bashDELETE /mailchimp/3.0/batches/{batch_id}
Returns 204 No Content on success.
Mailchimp uses offset-based pagination:
bashpython <<'EOF' import urllib.request, os, json req = urllib.request.Request('https://gateway.maton.ai/mailchimp/3.0/lists?count=50&offset=100') req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}') print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2)) EOF
Response includes total_items for calculating total pages:
json{ "lists": [...], "total_items": 250 }
javascriptconst response = await fetch( 'https://gateway.maton.ai/mailchimp/3.0/lists', { headers: { 'Authorization': `Bearer ${process.env.MATON_API_KEY}` } } ); const data = await response.json();
pythonimport os import requests import hashlib # Get lists response = requests.get( 'https://gateway.maton.ai/mailchimp/3.0/lists', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'} ) data = response.json() # Add a subscriber list_id = 'abc123def4' email = 'newuser@example.com' response = requests.post( f'https://gateway.maton.ai/mailchimp/3.0/lists/{list_id}/members', headers={ 'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}', 'Content-Type': 'application/json' }, json={ 'email_address': email, 'status': 'subscribed' } ) # Get subscriber hash for updates subscriber_hash = hashlib.md5(email.lower().encode()).hexdigest()
curl -g when URLs contain brackets (fields[], sort[], records[]) to disable glob parsingjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. You may get "Invalid API key" errors when piping.| Status | Meaning | |--------|---------| | 200 | Success with response body | | 204 | Success with no content (DELETE, some POST operations) | | 400 | Bad request or missing Mailchimp connection | | 401 | Invalid or missing Maton API key | | 403 | Forbidden - insufficient permissions | | 404 | Resource not found | | 405 | Method not allowed | | 429 | Rate limited | | 4xx/5xx | Passthrough error from Mailchimp API |
Mailchimp error responses include detailed information:
json{ "type": "https://mailchimp.com/developer/marketing/docs/errors/", "title": "Invalid Resource", "status": 400, "detail": "The resource submitted could not be validated.", "instance": "abc123-def456", "errors": [ { "field": "email_address", "message": "This value should be a valid email." } ] }
MATON_API_KEY environment variable is set:bashecho $MATON_API_KEY
bashpython <<'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
mailchimp. For example:https://gateway.maton.ai/mailchimp/3.0/listshttps://gateway.maton.ai/3.0/lists| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-02 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-24 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-11 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-23 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 24 cases were attempted. The headline lift of +50 percentage points is the difference between those two pass rates over the 24 comparable cases.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.