🎁 Get the FREE AI Skills Starter Guide β€” Subscribe β†’
BytesAgainBytesAgain
πŸ¦€ ClawHub

Keap

by @byungkyu

Keap API integration with managed OAuth. Manage contacts, companies, tags, tasks, orders, opportunities, and campaigns for CRM and marketing automation. Use...

Versionv1.0.3
Downloads4,502
Stars⭐ 3
TERMINAL
clawhub install keap

πŸ“– About This Skill


name: keap description: | 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. metadata: author: maton version: "1.0" clawdbot: emoji: 🧠 requires: env: - MATON_API_KEY

Keap

Access the Keap API with managed OAuth authentication. Manage contacts, companies, tags, tasks, orders, opportunities, campaigns, and more for CRM and marketing automation.

Quick Start

# List contacts
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.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

Base URL

https://api.maton.ai/keap/crm/rest/{api-path}

Maton proxies requests to api.infusionsoft.com/crm/rest 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 Keap 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=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

Create Connection

python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'keap'}).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-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.

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 Keap 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/keap/crm/rest/v2/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, companies, tags, tasks, orders, opportunities, and campaigns for CRM and marketing automation within the connected Keap 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.
  • API Reference

    User Info

    #### Get Current User

    GET /keap/crm/rest/v2/oauth/connect/userinfo
    

    Response:

    {
      "email": "user@example.com",
      "sub": "1",
      "id": "4236128",
      "keap_id": "user@example.com",
      "family_name": "Doe",
      "given_name": "John",
      "is_admin": true
    }
    

    Contact Operations

    #### List Contacts

    GET /keap/crm/rest/v2/contacts
    

    Query parameters:

  • page_size - Number of results per page (default 50, max 1000)
  • page_token - Token for next page
  • filter - Filter expression
  • order_by - Sort order
  • fields - Fields to include in response
  • Response:

    {
      "contacts": [
        {
          "id": "9",
          "family_name": "Park",
          "given_name": "John"
        }
      ],
      "next_page_token": ""
    }
    

    #### Get Contact

    GET /keap/crm/rest/v2/contacts/{contact_id}
    

    #### Create Contact

    POST /keap/crm/rest/v2/contacts
    Content-Type: application/json

    { "given_name": "John", "family_name": "Doe", "email_addresses": [ {"email": "john@example.com", "field": "EMAIL1"} ], "phone_numbers": [ {"number": "555-1234", "field": "PHONE1"} ] }

    Response:

    {
      "id": "13",
      "family_name": "Doe",
      "given_name": "John"
    }
    

    #### Update Contact

    PATCH /keap/crm/rest/v2/contacts/{contact_id}
    Content-Type: application/json

    { "given_name": "Jane" }

    #### Delete Contact

    DELETE /keap/crm/rest/v2/contacts/{contact_id}
    

    Returns 204 on success.

    #### Get Contact Notes

    GET /keap/crm/rest/v2/contacts/{contact_id}/notes
    

    #### Create Contact Note

    POST /keap/crm/rest/v2/contacts/{contact_id}/notes
    Content-Type: application/json

    { "body": "Note content here", "title": "Note Title" }

    Company Operations

    #### List Companies

    GET /keap/crm/rest/v2/companies
    

    #### Get Company

    GET /keap/crm/rest/v2/companies/{company_id}
    

    #### Create Company

    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

    PATCH /keap/crm/rest/v2/companies/{company_id}
    Content-Type: application/json

    { "company_name": "Acme Corporation" }

    #### Delete Company

    DELETE /keap/crm/rest/v2/companies/{company_id}
    

    Tag Operations

    #### List Tags

    GET /keap/crm/rest/v2/tags
    

    Response:

    {
      "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

    GET /keap/crm/rest/v2/tags/{tag_id}
    

    #### Create Tag

    POST /keap/crm/rest/v2/tags
    Content-Type: application/json

    { "name": "VIP Customer", "description": "High value customers" }

    #### Update Tag

    PATCH /keap/crm/rest/v2/tags/{tag_id}
    Content-Type: application/json

    { "name": "Premium Customer" }

    #### Delete Tag

    DELETE /keap/crm/rest/v2/tags/{tag_id}
    

    #### List Contacts with Tag

    GET /keap/crm/rest/v2/tags/{tag_id}/contacts
    

    #### Apply Tags to Contacts

    POST /keap/crm/rest/v2/tags/{tag_id}/contacts:applyTags
    Content-Type: application/json

    { "contact_ids": ["1", "2", "3"] }

    #### Remove Tags from Contacts

    POST /keap/crm/rest/v2/tags/{tag_id}/contacts:removeTags
    Content-Type: application/json

    { "contact_ids": ["1", "2", "3"] }

    Tag Category Operations

    #### List Tag Categories

    GET /keap/crm/rest/v2/tags/categories
    

    #### Create Tag Category

    POST /keap/crm/rest/v2/tags/categories
    Content-Type: application/json

    { "name": "Customer Segments" }

    Task Operations

    #### List Tasks

    GET /keap/crm/rest/v2/tasks
    

    #### Get Task

    GET /keap/crm/rest/v2/tasks/{task_id}
    

    #### Create Task

    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

    PATCH /keap/crm/rest/v2/tasks/{task_id}
    Content-Type: application/json

    { "completed": true }

    #### Delete Task

    DELETE /keap/crm/rest/v2/tasks/{task_id}
    

    Opportunity Operations

    #### List Opportunities

    GET /keap/crm/rest/v2/opportunities
    

    #### Get Opportunity

    GET /keap/crm/rest/v2/opportunities/{opportunity_id}
    

    #### Create Opportunity

    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

    PATCH /keap/crm/rest/v2/opportunities/{opportunity_id}
    Content-Type: application/json

    { "stage": {"id": "2"} }

    #### Delete Opportunity

    DELETE /keap/crm/rest/v2/opportunities/{opportunity_id}
    

    #### List Opportunity Stages

    GET /keap/crm/rest/v2/opportunities/stages
    

    Order Operations

    #### List Orders

    GET /keap/crm/rest/v2/orders
    

    #### Get Order

    GET /keap/crm/rest/v2/orders/{order_id}
    

    #### Create Order

    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

    POST /keap/crm/rest/v2/orders/{order_id}/items
    Content-Type: application/json

    { "product": {"id": "1"}, "quantity": 2 }

    Product Operations

    #### List Products

    GET /keap/crm/rest/v2/products
    

    #### Get Product

    GET /keap/crm/rest/v2/products/{product_id}
    

    #### Create Product

    POST /keap/crm/rest/v2/products
    Content-Type: application/json

    { "product_name": "Consulting Package", "product_price": 500.00, "product_short_description": "1 hour consulting" }

    Campaign Operations

    #### List Campaigns

    GET /keap/crm/rest/v2/campaigns
    

    #### Get Campaign

    GET /keap/crm/rest/v2/campaigns/{campaign_id}
    

    #### List Campaign Sequences

    GET /keap/crm/rest/v2/campaigns/{campaign_id}/sequences
    

    #### Add Contacts to Sequence

    POST /keap/crm/rest/v2/campaigns/{campaign_id}/sequences/{sequence_id}:addContacts
    Content-Type: application/json

    { "contact_ids": ["1", "2"] }

    #### Remove Contacts from Sequence

    POST /keap/crm/rest/v2/campaigns/{campaign_id}/sequences/{sequence_id}:removeContacts
    Content-Type: application/json

    { "contact_ids": ["1", "2"] }

    Email Operations

    #### List Emails

    GET /keap/crm/rest/v2/emails
    

    #### Get Email

    GET /keap/crm/rest/v2/emails/{email_id}
    

    #### Send Email

    POST /keap/crm/rest/v2/emails:send
    Content-Type: application/json

    { "contacts": [{"id": "9"}], "subject": "Hello", "html_content": "

    Email body

    " }

    User Operations

    #### List Users

    GET /keap/crm/rest/v2/users
    

    #### Get User

    GET /keap/crm/rest/v2/users/{user_id}
    

    Subscription Operations

    #### List Subscriptions

    GET /keap/crm/rest/v2/subscriptions
    

    #### Get Subscription

    GET /keap/crm/rest/v2/subscriptions/{subscription_id}
    

    Affiliate Operations

    #### List Affiliates

    GET /keap/crm/rest/v2/affiliates
    

    #### Get Affiliate

    GET /keap/crm/rest/v2/affiliates/{affiliate_id}
    

    Automation Operations

    #### List Automations

    GET /keap/crm/rest/v2/automations
    

    #### Get Automation

    GET /keap/crm/rest/v2/automations/{automation_id}
    

    Pagination

    Keap uses token-based pagination:

    GET /keap/crm/rest/v2/contacts?page_size=50
    

    Response:

    {
      "contacts": [...],
      "next_page_token": "abc123"
    }
    

    For subsequent pages, use the page_token parameter:

    GET /keap/crm/rest/v2/contacts?page_size=50&page_token=abc123
    

    When next_page_token is empty, there are no more pages.

    Filtering

    Use the filter parameter for filtering results:

    GET /keap/crm/rest/v2/contacts?filter=given_name==John
    GET /keap/crm/rest/v2/contacts?filter=email_addresses.email==john@example.com
    GET /keap/crm/rest/v2/tasks?filter=completed==false
    

    Code Examples

    JavaScript

    const response = await fetch(
      'https://api.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://api.maton.ai/keap/crm/rest/v2/contacts', headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}, params={'page_size': 10} ) data = response.json()

    Notes

  • All API paths must include /crm/rest prefix (e.g., /keap/crm/rest/v2/contacts)
  • Keap uses v2 REST API (previous v1 API is deprecated)
  • Timestamps are in ISO 8601 format
  • IDs are returned as strings
  • Pagination uses page_size and page_token (not offset-based)
  • Maximum page_size is 1000
  • 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 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 |

    Troubleshooting: API Key Issues

    1. Check that the MATON_API_KEY environment variable is set:

    echo $MATON_API_KEY
    

    2. 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
    

    Troubleshooting: Invalid App Name

    1. Ensure your URL path starts with keap. For example:

  • Correct: https://api.maton.ai/keap/crm/rest/v2/contacts
  • Incorrect: https://api.maton.ai/crm/rest/v2/contacts
  • Resources

  • Keap Developer Portal
  • Keap REST API V2 Documentation
  • Getting Started Guide
  • OAuth 2.0 Authentication
  • Maton Community
  • Maton Support
  • πŸ’‘ Examples

    # List contacts
    python <<'EOF'
    import urllib.request, os, json
    req = urllib.request.Request('https://api.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
    

    πŸ“‹ Tips & Best Practices

  • All API paths must include /crm/rest prefix (e.g., /keap/crm/rest/v2/contacts)
  • Keap uses v2 REST API (previous v1 API is deprecated)
  • Timestamps are in ISO 8601 format
  • IDs are returned as strings
  • Pagination uses page_size and page_token (not offset-based)
  • Maximum page_size is 1000
  • IMPORTANT: When piping curl output to jq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments