Keap API integration with managed OAuth. Manage contacts, companies, tags, tasks, orders, opportunities, and campaigns for CRM and marketing automation. Use this skill when users want to create and manage contacts, apply tags, track opportunities, or automate marketing workflows in Keap. For other third party apps, use the api-gateway skill (https://clawhub.ai/byungkyu/api-gateway). Requires network access and valid Maton API key.
Access the Keap API with managed OAuth authentication. Manage contacts, companies, tags, tasks, orders, opportunities, campaigns, and more for CRM and marketing automation.
```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/keap/crm/rest/v2/contacts?page_size=10')
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/keap/crm/rest/{api-path}
```
The gateway proxies requests to `api.infusionsoft.com/crm/rest` and automatically injects your OAuth token.
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`:
```bash
export MATON_API_KEY="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
Manage your Keap OAuth connections at `https://ctrl.maton.ai`.
```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://ctrl.maton.ai/connections?app=keap&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
```
```bash
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'keap'}).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
```
```bash
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:**
```json
{
"connection": {
"connection_id": "d5242090-02ae-4195-83e3-8deca823eb9a",
"status": "ACTIVE",
"creation_time": "2026-02-08T01:34:44.738374Z",
"last_updated_time": "2026-02-08T01:35:20.106942Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "keap",
"metadata": {}
}
}
```
Open the returned `url` in a browser to complete OAuth authorization.
```bash
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
```
If you have multiple Keap connections, specify which one to use with the `Maton-Connection` header:
```bash
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://gateway.maton.ai/keap/crm/rest/v2/contacts')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', 'd5242090-02ae-4195-83e3-8deca823eb9a')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
```
If omitted, the gateway uses the default (oldest) active connection.
#### Get Current User
```bash
GET /keap/crm/rest/v2/oauth/connect/userinfo
```
**Response:**
```json
{
"email": "[email protected]",
"sub": "1",
"id": "4236128",
"keap_id": "[email protected]",
"family_name": "Doe",
"given_name": "John",
"is_admin": true
}
```
#### List Contacts
```bash
GET /keap/crm/rest/v2/contacts
```
Query parameters:
**Response:**
```json
{
"contacts": [
{
"id": "9",
"family_name": "Park",
"given_name": "John"
}
],
"next_page_token": ""
}
```
#### Get Contact
```bash
GET /keap/crm/rest/v2/contacts/{contact_id}
```
#### Create Contact
```bash
POST /keap/crm/rest/v2/contacts
Content-Type: application/json
{
"given_name": "John",
"family_name": "Doe",
"email_addresses": [
{"email": "[email protected]", "field": "EMAIL1"}
],
"phone_numbers": [
{"number": "555-1234", "field": "PHONE1"}
]
}
```
**Response:**
```json
{
"id": "13",
"family_name": "Doe",
"given_name": "John"
}
```
#### Update Contact
```bash
PATCH /keap/crm/rest/v2/contacts/{contact_id}
Content-Type: application/json
{
"given_name": "Jane"
}
```
#### Delete Contact
```bash
DELETE /keap/crm/rest/v2/contacts/{contact_id}
```
Returns 204 on success.
#### Get Contact Notes
```bash
GET /keap/crm/rest/v2/contacts/{contact_id}/notes
```
#### Create Contact Note
```bash
POST /keap/crm/rest/v2/contacts/{contact_id}/notes
Content-Type: application/json
{
"body": "Note content here",
"title": "Note Title"
}
```
#### List Companies
```bash
GET /keap/crm/rest/v2/companies
```
#### Get Company
```bash
GET /keap/crm/rest/v2/companies/{company_id}
```
#### Create Company
```bash
POST /keap/crm/rest/v2/companies
Content-Type: application/json
{
"company_name": "Acme Corp",
"phone_number": {"number": "555-1234", "type": "MAIN"},
"website": "https://acme.com"
}
```
#### Update Company
```bash
PATCH /keap/crm/rest/v2/companies/{company_id}
Content-Type: application/json
{
"company_name": "Acme Corporation"
}
```
#### Delete Company
```bash
DELETE /keap/crm/rest/v2/companies/{company_id}
```
#### List Tags
```bash
GET /keap/crm/rest/v2/tags
```
**Response:**
```json
{
"tags": [
{
"id": "91",
"name": "Nurture Subscriber",
"description": "",
"category": {"id": "10"},
"create_time": "2017-04-24T17:26:26Z",
"update_time": "2017-04-24T17:26:26Z"
}
],
"next_page_token": ""
}
```
#### Get Tag
```bash
GET /keap/crm/rest/v2/tags/{tag_id}
```
#### Create Tag
```bash
POST /keap/crm/rest/v2/tags
Content-Type: application/json
{
"name": "VIP Customer",
"description": "High value customers"
}
```
#### Update Tag
```bash
PATCH /keap/crm/rest/v2/tags/{tag_id}
Content-Type: application/json
{
"name": "Premium Customer"
}
```
#### Delete Tag
```bash
DELETE /keap/crm/rest/v2/tags/{tag_id}
```
#### List Contacts with Tag
```bash
GET /keap/crm/rest/v2/tags/{tag_id}/contacts
```
#### Apply Tags to Contacts
```bash
POST /keap/crm/rest/v2/tags/{tag_id}/contacts:applyTags
Content-Type: application/json
{
"contact_ids": ["1", "2", "3"]
}
```
#### Remove Tags from Contacts
```bash
POST /keap/crm/rest/v2/tags/{tag_id}/contacts:removeTags
Content-Type: application/json
{
"contact_ids": ["1", "2", "3"]
}
```
#### List Tag Categories
```bash
GET /keap/crm/rest/v2/tags/categories
```
#### Create Tag Category
```bash
POST /keap/crm/rest/v2/tags/categories
Content-Type: application/json
{
"name": "Customer Segments"
}
```
#### List Tasks
```bash
GET /keap/crm/rest/v2/tasks
```
#### Get Task
```bash
GET /keap/crm/rest/v2/tasks/{task_id}
```
#### Create Task
```bash
POST /keap/crm/rest/v2/tasks
Content-Type: application/json
{
"title": "Follow up call",
"description": "Call to discuss proposal",
"due_date": "2026-02-15T10:00:00Z",
"contact": {"id": "9"}
}
```
#### Update Task
```bash
PATCH /keap/crm/rest/v2/tasks/{task_id}
Content-Type: application/json
{
"completed": true
}
```
#### Delete Task
```bash
DELETE /keap/crm/rest/v2/tasks/{task_id}
```
#### List Opportunities
```bash
GET /keap/crm/rest/v2/opportunities
```
#### Get Opportunity
```bash
GET /keap/crm/rest/v2/opportunities/{opportunity_id}
```
#### Create Opportunity
```bash
POST /keap/crm/rest/v2/opportunities
Content-Type: application/json
{
"opportunity_title": "New Deal",
"contact": {"id": "9"},
"stage": {"id": "1"},
"estimated_close_date": "2026-03-01"
}
```
#### Update Opportunity
```bash
PATCH /keap/crm/rest/v2/opportunities/{opportunity_id}
Content-Type: application/json
{
"stage": {"id": "2"}
}
```
#### Delete Opportunity
```bash
DELETE /keap/crm/rest/v2/opportunities/{opportunity_id}
```
#### List Opportunity Stages
```bash
GET /keap/crm/rest/v2/opportunities/stages
```
#### List Orders
```bash
GET /keap/crm/rest/v2/orders
```
#### Get Order
```bash
GET /keap/crm/rest/v2/orders/{order_id}
```
#### Create Order
```bash
POST /keap/crm/rest/v2/orders
Content-Type: application/json
{
"contact": {"id": "9"},
"order_date": "2026-02-08",
"order_title": "Product Order"
}
```
#### Add Order Item
```bash
POST /keap/crm/rest/v2/orders/{order_id}/items
Content-Type: application/json
{
"product": {"id": "1"},
"quantity": 2
}
```
#### List Products
```bash
GET /keap/crm/rest/v2/products
```
#### Get Product
```bash
GET /keap/crm/rest/v2/products/{product_id}
```
#### Create Product
```bash
POST /keap/crm/rest/v2/products
Content-Type: application/json
{
"product_name": "Consulting Package",
"product_price": 500.00,
"product_short_description": "1 hour consulting"
}
```
#### List Campaigns
```bash
GET /keap/crm/rest/v2/campaigns
```
#### Get Campaign
```bash
GET /keap/crm/rest/v2/campaigns/{campaign_id}
```
#### List Campaign Sequences
```bash
GET /keap/crm/rest/v2/campaigns/{campaign_id}/sequences
```
#### Add Contacts to Sequence
```bash
POST /keap/crm/rest/v2/campaigns/{campaign_id}/sequences/{sequence_id}:addContacts
Content-Type: application/json
{
"contact_ids": ["1", "2"]
}
```
#### Remove Contacts from Sequence
```bash
POST /keap/crm/rest/v2/campaigns/{campaign_id}/sequences/{sequence_id}:removeContacts
Content-Type: application/json
{
"contact_ids": ["1", "2"]
}
```
#### List Emails
```bash
GET /keap/crm/rest/v2/emails
```
#### Get Email
```bash
GET /keap/crm/rest/v2/emails/{email_id}
```
#### Send Email
```bash
POST /keap/crm/rest/v2/emails:send
Content-Type: application/json
{
"contacts": [{"id": "9"}],
"subject": "Hello",
"html_content": "<p>Email body</p>"
}
```
#### List Users
```bash
GET /keap/crm/rest/v2/users
```
#### Get User
```bash
GET /keap/crm/rest/v2/users/{user_id}
```
#### List Subscriptions
```bash
GET /keap/crm/rest/v2/subscriptions
```
#### Get Subscription
```bash
GET /keap/crm/rest/v2/subscriptions/{subscription_id}
```
#### List Affiliates
```bash
GET /keap/crm/rest/v2/affiliates
```
#### Get Affiliate
```bash
GET /keap/crm/rest/v2/affiliates/{affiliate_id}
```
#### List Automations
```bash
GET /keap/crm/rest/v2/automations
```
#### Get Automation
```bash
GET /keap/crm/rest/v2/automations/{automation_id}
```
Keap uses token-based pagination:
```bash
GET /keap/crm/rest/v2/contacts?page_size=50
```
**Response:**
```json
{
"contacts": [...],
"next_page_token": "abc123"
}
```
For subsequent pages, use the `page_token` parameter:
```bash
GET /keap/crm/rest/v2/contacts?page_size=50&page_token=abc123
```
When `next_page_token` is empty, there are no more pages.
Use the `filter` parameter for filtering results:
```bash
GET /keap/crm/rest/v2/contacts?filter=given_name==John
GET /keap/crm/rest/v2/[email protected]
GET /keap/crm/rest/v2/tasks?filter=completed==false
```
```javascript
const response = await fetch(
'https://gateway.maton.ai/keap/crm/rest/v2/contacts?page_size=10',
{
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/keap/crm/rest/v2/contacts',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'},
params={'page_size': 10}
)
data = response.json()
```
| Status | Meaning |
|--------|---------|
| 400 | Missing Keap connection or invalid request |
| 401 | Invalid or missing Maton API key |
| 403 | Not authorized (check OAuth scopes) |
| 404 | Resource not found |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from Keap API |
**When you receive a "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:
```bash
echo $MATON_API_KEY
```
2. Verify the API key is valid by listing connections:
```bash
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
```
Leave a review
No reviews yet. Be the first to review this skill!