Design & media

GoHighLevel

Try it

Access GoHighLevel CRM, pipelines, calendars, and locations via Private Integration Token through a managed auth layer.

What it does

GoHighLevel (Private Integration Token) API integration with managed authentication. Exposes contacts, sales pipelines, calendars, conversations, invoices, products, and marketing automation through a proxy that automatically injects your PIT credential. Supports two token scopes: Agency tokens for managing sub-account locations and snapshots, and Sub-Account tokens for location-scoped CRM data such as contacts, pipelines, calendars, custom fields, tags, and workflows. All requests route through a single base URL using a Maton API key, and every write operation requires explicit user confirmation before execution.

When to use it

  • Searching, creating, updating, and tagging contacts within a location
  • Managing sales pipelines, stages, and opportunities
  • Scheduling and reading calendar appointments for a location
  • Using an Agency token to search, create, or delete sub-account locations

The skill document

GoHighLevel (Private Integration Token)

Access the GoHighLevel API with managed Private Integration Token (PIT) authentication. Manage contacts, sales pipelines, calendars, conversations, invoices, products, businesses, and marketing automation.

Important: Two Token Types

GoHighLevel uses two types of Private Integration Tokens with different scopes:

Token TypePurposeKey Capabilities
AgencyManage the agency and its sub-accounts (locations)Search/create/update/delete locations, manage snapshots
Sub-AccountOperate within a specific locationContacts, calendars, pipelines, conversations, payments, custom fields, tags, workflows, campaigns

You will typically need both connections — an agency token for location management and a sub-account token for CRM operations. Use the Maton-Connection header to specify which token to use for each request.

Quick Start

# List contacts (Sub-Account token)
curl -s -X GET "https://api.maton.ai/highlevel-pit/contacts/?locationId={locationId}&limit=10" \
  -H "Authorization: Bearer $MATON_API_KEY"

Base URL

https://api.maton.ai/highlevel-pit/{resource}

Maton proxies requests to services.leadconnectorhq.com and automatically injects your PIT 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 GoHighLevel PIT connections at https://api.maton.ai.

List Connections

curl -s -X GET "https://api.maton.ai/connections?app=highlevel-pit&status=ACTIVE" \
  -H "Authorization: Bearer $MATON_API_KEY"

Create Connection

curl -s -X POST "https://api.maton.ai/connections" \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer $MATON_API_KEY" \
  -d '{"app": "highlevel-pit"}'

Open the returned url in a browser to enter your Private Integration Token.

Get Connection

curl -s -X GET "https://api.maton.ai/connections/{connection_id}" \
  -H "Authorization: Bearer $MATON_API_KEY"

Response:

{
  "connection": {
    "connection_id": "{connection_id}",
    "status": "ACTIVE",
    "app": "highlevel-pit",
    "method": "API_KEY"
  }
}

Delete Connection

curl -s -X DELETE "https://api.maton.ai/connections/{connection_id}" \
  -H "Authorization: Bearer $MATON_API_KEY"

Specifying Connection

Since you will typically have two connections (agency + sub-account), always specify which one to use:

curl -s -X GET "https://api.maton.ai/highlevel-pit/contacts/?locationId={locationId}" \
  -H "Authorization: Bearer $MATON_API_KEY" \
  -H "Maton-Connection: {connection_id}"

If you have multiple connections, always include this header to ensure requests go to the intended account.

Security & Permissions

  • Access is scoped to locations, contacts, opportunities, calendars, conversations, workflows, and CRM data within the connected GoHighLevel account.
  • Two token types with different scopes: Agency tokens manage locations and snapshots. Sub-Account tokens access contacts, calendars, pipelines, and CRM data. Use the correct connection for the intended scope.
  • 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 — Agency Token

These endpoints require an Agency token.

Locations (Sub-Accounts)

Search Locations

GET /highlevel-pit/locations/search?companyId={companyId}

Query parameters:

  • companyId (required) - The agency's company ID
  • limit - Results per page
  • skip - Number to skip (offset)
  • order - Sort order
  • email - Filter by email

Response:

{
  "locations": [
    {
      "id": "abc123",
      "companyId": "xyz789",
      "name": "My Sub-Account",
      "address": "123 Main St",
      "city": "San Francisco",
      "state": "CA",
      "country": "US",
      "postalCode": "94105",
      "timezone": "America/Los_Angeles",
      "email": "admin@example.com",
      "phone": "+15551234567"
    }
  ]
}

Get Location

GET /highlevel-pit/locations/{locationId}

Response:

{
  "location": {
    "id": "abc123",
    "name": "My Sub-Account",
    "address": "123 Main St",
    "city": "San Francisco",
    "state": "CA",
    "settings": {
      "allowDuplicateContact": false,
      "allowDuplicateOpportunity": false
    },
    "social": { ... },
    "permissions": { ... }
  }
}

Create Location

POST /highlevel-pit/locations/
Content-Type: application/json

{
  "companyId": "{companyId}",
  "name": "New Sub-Account",
  "address": "123 Main St",
  "city": "San Francisco",
  "state": "CA",
  "postalCode": "94105",
  "country": "US",
  "timezone": "America/Los_Angeles",
  "email": "admin@example.com",
  "phone": "+15551234567"
}

Update Location

PUT /highlevel-pit/locations/{locationId}
Content-Type: application/json

{
  "name": "Updated Name",
  "city": "Los Angeles"
}

Delete Location

DELETE /highlevel-pit/locations/{locationId}

Snapshots

List Snapshots

GET /highlevel-pit/snapshots/?companyId={companyId}

API Reference — Sub-Account Token

These endpoints require a Sub-Account token. Most endpoints require a locationId query parameter.

Contacts

List Contacts

GET /highlevel-pit/contacts/?locationId={locationId}

Query parameters:

  • locationId (required)
  • limit - Results per page (default 20)
  • query - Search by name, email, or phone
  • startAfter - Cursor for pagination (contact ID)
  • startAfterId - Cursor for pagination

Response:

{
  "contacts": [
    {
      "id": "abc123",
      "locationId": "loc123",
      "firstName": "John",
      "lastName": "Doe",
      "email": "john@example.com",
      "phone": "+15551234567",
      "companyName": "Acme Inc",
      "tags": ["customer", "vip"],
      "type": "lead",
      "dnd": false,
      "dateAdded": "2026-04-28T07:34:32.829Z",
      "customFields": []
    }
  ],
  "meta": {
    "total": 150,
    "startAfter": "abc123",
    "startAfterId": "abc123"
  }
}

Get Contact

GET /highlevel-pit/contacts/{contactId}

Response:

{
  "contact": {
    "id": "abc123",
    "firstName": "John",
    "lastName": "Doe",
    "email": "john@example.com",
    "phone": "+15551234567",
    "tags": ["customer"],
    "type": "lead",
    "companyName": "Acme Inc",
    "customFields": [],
    "additionalEmails": [],
    "additionalPhones": []
  }
}

Create Contact

POST /highlevel-pit/contacts/
Content-Type: application/json

{
  "locationId": "{locationId}",
  "firstName": "John",
  "lastName": "Doe",
  "email": "john@example.com",
  "phone": "+15551234567",
  "companyName": "Acme Inc",
  "tags": ["customer"]
}

Update Contact

PUT /highlevel-pit/contacts/{contactId}
Content-Type: application/json

{
  "firstName": "Jane",
  "companyName": "New Company"
}

Delete Contact

DELETE /highlevel-pit/contacts/{contactId}

Search Contacts by Email/Phone

GET /highlevel-pit/contacts/?locationId={locationId}&query=john@example.com

Contact Tags

Add Tags

POST /highlevel-pit/contacts/{contactId}/tags
Content-Type: application/json

{
  "tags": ["vip", "priority"]
}

Response:

{
  "tags": ["customer", "vip", "priority"],
  "tagsAdded": ["vip", "priority"]
}

Remove Tags

DELETE /highlevel-pit/contacts/{contactId}/tags
Content-Type: application/json

{
  "tags": ["vip"]
}

Response:

{
  "tags": ["customer", "priority"],
  "tagsRemoved": ["vip"]
}

Contact Notes

List Notes

GET /highlevel-pit/contacts/{contactId}/notes

Create Note

POST /highlevel-pit/contacts/{contactId}/notes
Content-Type: application/json

{
  "body": "Spoke with client about renewal"
}

Response:

{
  "note": {
    "id": "note123",
    "body": "Spoke with client about renewal",
    "dateAdded": "2026-04-30T10:22:47.934Z",
    "contactId": "abc123"
  }
}

Update Note

PUT /highlevel-pit/contacts/{contactId}/notes/{noteId}
Content-Type: application/json

{
  "body": "Updated note content"
}

Delete Note

DELETE /highlevel-pit/contacts/{contactId}/notes/{noteId}

Contact Tasks

List Tasks

GET /highlevel-pit/contacts/{contactId}/tasks

Create Task

IMPORTANT: The completed field is required.

POST /highlevel-pit/contacts/{contactId}/tasks
Content-Type: application/json

{
  "title": "Follow up call",
  "body": "Discuss contract renewal",
  "dueDate": "2026-06-01T10:00:00Z",
  "completed": false
}

Response:

{
  "task": {
    "id": "task123",
    "title": "Follow up call",
    "body": "Discuss contract renewal",
    "dueDate": "2026-06-01T10:00:00.000Z",
    "completed": false,
    "contactId": "abc123"
  }
}

Update Task

PUT /highlevel-pit/contacts/{contactId}/tasks/{taskId}
Content-Type: application/json

{
  "title": "Updated task",
  "completed": true
}

Delete Task

DELETE /highlevel-pit/contacts/{contactId}/tasks/{taskId}

Opportunities (Deals)

Search Opportunities

GET /highlevel-pit/opportunities/search?location_id={locationId}

Query parameters:

  • location_id (required)
  • pipeline_id - Filter by pipeline
  • pipeline_stage_id - Filter by stage
  • status - open, won, lost, abandoned, all
  • contact_id - Filter by contact
  • q - Search query
  • limit - Results per page
  • page - Page number

Response:

{
  "opportunities": [
    {
      "id": "opp123",
      "name": "Enterprise Deal",
      "monetaryValue": 50000,
      "pipelineId": "pipe123",
      "pipelineStageId": "stage123",
      "status": "open",
      "contactId": "abc123",
      "contact": {
        "id": "abc123",
        "name": "John Doe",
        "email": "john@example.com"
      }
    }
  ],
  "meta": {
    "total": 25,
    "currentPage": 1,
    "nextPage": 2,
    "prevPage": null
  }
}

Get Opportunity

GET /highlevel-pit/opportunities/{opportunityId}

Create Opportunity

POST /highlevel-pit/opportunities/
Content-Type: application/json

{
  "pipelineId": "{pipelineId}",
  "locationId": "{locationId}",
  "name": "Enterprise Deal",
  "pipelineStageId": "{stageId}",
  "status": "open",
  "contactId": "{contactId}",
  "monetaryValue": 50000
}

Update Opportunity

IMPORTANT: pipelineId is required even when not changing it.

PUT /highlevel-pit/opportunities/{opportunityId}
Content-Type: application/json

{
  "pipelineId": "{pipelineId}",
  "name": "Updated Deal",
  "monetaryValue": 75000,
  "status": "won"
}

Delete Opportunity

DELETE /highlevel-pit/opportunities/{opportunityId}

Pipelines

List Pipelines

GET /highlevel-pit/opportunities/pipelines?locationId={locationId}

Response:

{
  "pipelines": [
    {
      "id": "pipe123",
      "name": "Sales Pipeline",
      "stages": [
        {
          "id": "stage-uuid",
          "name": "New Lead",
          "position": 0,
          "stageWinProbability": 14.29
        },
        {
          "id": "stage-uuid-2",
          "name": "Contacted",
          "position": 1,
          "stageWinProbability": 28.57
        }
      ]
    }
  ]
}

Calendars

List Calendars

GET /highlevel-pit/calendars/?locationId={locationId}

Response:

{
  "calendars": [
    {
      "id": "cal123",
      "locationId": "loc123",
      "name": "Personal Calendar",
      "calendarType": "personal",
      "eventType": "RoundRobin_OptimizeForAvailability",
      "slotDuration": 30,
      "teamMembers": [
        {
          "userId": "user123",
          "selected": true,
          "priority": 0.5
        }
      ]
    }
  ]
}

Get Calendar

GET /highlevel-pit/calendars/{calendarId}

Create Calendar

POST /highlevel-pit/calendars/
Content-Type: application/json

{
  "locationId": "{locationId}",
  "name": "Team Calendar",
  "calendarType": "personal",
  "eventType": "RoundRobin_OptimizeForAvailability",
  "teamMembers": [
    {
      "userId": "{userId}",
      "priority": 0.5,
      "selected": true
    }
  ]
}

Update Calendar

Note: Do NOT include locationId in the update body.

PUT /highlevel-pit/calendars/{calendarId}
Content-Type: application/json

{
  "name": "Updated Calendar",
  "calendarType": "personal",
  "eventType": "RoundRobin_OptimizeForAvailability",
  "teamMembers": [
    {
      "userId": "{userId}",
      "priority": 0.5,
      "selected": true
    }
  ]
}

Delete Calendar

DELETE /highlevel-pit/calendars/{calendarId}

Get Calendar Events

Requires at least one of calendarId, userId, or groupId.

GET /highlevel-pit/calendars/events?locationId={locationId}&calendarId={calendarId}&startTime={epochMs}&endTime={epochMs}

Query parameters:

  • locationId (required)
  • calendarId, userId, or groupId (at least one required)
  • startTime - Start of range (epoch milliseconds)
  • endTime - End of range (epoch milliseconds)

Get Free Slots

GET /highlevel-pit/calendars/{calendarId}/free-slots?startDate={epochMs}&endDate={epochMs}&timezone={timezone}

Calendar Groups

GET /highlevel-pit/calendars/groups?locationId={locationId}

Conversations

Search Conversations

GET /highlevel-pit/conversations/search?locationId={locationId}

Query parameters:

  • locationId (required)
  • limit - Results per page
  • contactId - Filter by contact
  • assignedTo - Filter by assigned user
  • status - Filter by status

Response:

{
  "conversations": [
    {
      "id": "conv123",
      "locationId": "loc123",
      "contactId": "abc123",
      "fullName": "John Doe",
      "type": "TYPE_PHONE",
      "lastMessageDate": 1777361673411,
      "lastMessageType": "TYPE_NO_SHOW",
      "unreadCount": 0
    }
  ],
  "total": 5
}

Get Conversation

GET /highlevel-pit/conversations/{conversationId}

Get Conversation Messages

GET /highlevel-pit/conversations/{conversationId}/messages

Create Conversation

POST /highlevel-pit/conversations/
Content-Type: application/json

{
  "locationId": "{locationId}",
  "contactId": "{contactId}"
}

Users

List Users

GET /highlevel-pit/users/?locationId={locationId}

Response:

{
  "users": [
    {
      "id": "user123",
      "name": "Admin User",
      "firstName": "Admin",
      "lastName": "User",
      "email": "admin@example.com",
      "phone": "+15551234567",
      "roles": {
        "type": "admin",
        "role": "admin",
        "locationIds": ["loc123"]
      }
    }
  ]
}

Location Tags

List Tags

GET /highlevel-pit/locations/{locationId}/tags

Response:

{
  "tags": [
    {
      "id": "tag123",
      "name": "VIP Customer",
      "locationId": "loc123"
    }
  ]
}

Create Tag

POST /highlevel-pit/locations/{locationId}/tags
Content-Type: application/json

{
  "name": "New Tag"
}

Get Tag

GET /highlevel-pit/locations/{locationId}/tags/{tagId}

Update Tag

PUT /highlevel-pit/locations/{locationId}/tags/{tagId}
Content-Type: application/json

{
  "name": "Updated Tag"
}

Delete Tag

DELETE /highlevel-pit/locations/{locationId}/tags/{tagId}

Custom Fields

List Custom Fields

GET /highlevel-pit/locations/{locationId}/customFields

Response:

{
  "customFields": [
    {
      "id": "cf123",
      "name": "Customer ID",
      "fieldKey": "contact.customer_id",
      "dataType": "TEXT",
      "model": "contact",
      "position": 50
    }
  ]
}

Create Custom Field

POST /highlevel-pit/locations/{locationId}/customFields
Content-Type: application/json

{
  "name": "Customer ID",
  "dataType": "TEXT",
  "model": "contact"
}

Valid dataType values: TEXT, LARGE_TEXT, NUMERICAL, PHONE, MONETORY, CHECKBOX, SINGLE_OPTIONS, MULTIPLE_OPTIONS, FLOAT, DATE, TEXTBOX_LIST, FILE_UPLOAD, SIGNATURE

Valid model values: contact, opportunity

Get Custom Field

GET /highlevel-pit/locations/{locationId}/customFields/{customFieldId}

Update Custom Field

PUT /highlevel-pit/locations/{locationId}/customFields/{customFieldId}
Content-Type: application/json

{
  "name": "Updated Field Name"
}

Delete Custom Field

DELETE /highlevel-pit/locations/{locationId}/customFields/{customFieldId}

Custom Values

List Custom Values

GET /highlevel-pit/locations/{locationId}/customValues

Response:

{
  "customValues": [
    {
      "id": "cv123",
      "name": "Company Tagline",
      "fieldKey": "{{ custom_values.company_tagline }}",
      "value": "We build great things",
      "locationId": "loc123"
    }
  ]
}

Create Custom Value

POST /highlevel-pit/locations/{locationId}/customValues
Content-Type: application/json

{
  "name": "Company Tagline",
  "value": "We build great things"
}

Get Custom Value

GET /highlevel-pit/locations/{locationId}/customValues/{customValueId}

Update Custom Value

PUT /highlevel-pit/locations/{locationId}/customValues/{customValueId}
Content-Type: application/json

{
  "name": "Updated Name",
  "value": "Updated value"
}

Delete Custom Value

DELETE /highlevel-pit/locations/{locationId}/customValues/{customValueId}

Businesses

List Businesses

GET /highlevel-pit/businesses/?locationId={locationId}

Response:

{
  "success": true,
  "businesses": [
    {
      "id": "biz123",
      "name": "Acme Inc",
      "locationId": "loc123",
      "city": "Los Angeles",
      "website": "www.acme.com",
      "phone": "+15551234567",
      "email": "info@acme.com"
    }
  ]
}

Get Business

GET /highlevel-pit/businesses/{businessId}

Create Business

POST /highlevel-pit/businesses/
Content-Type: application/json

{
  "locationId": "{locationId}",
  "name": "New Business",
  "city": "San Francisco",
  "phone": "+15551234567",
  "email": "info@newbiz.com",
  "website": "www.newbiz.com"
}

Update Business

PUT /highlevel-pit/businesses/{businessId}
Content-Type: application/json

{
  "name": "Updated Business",
  "city": "Los Angeles"
}

Delete Business

DELETE /highlevel-pit/businesses/{businessId}

Products

List Products

GET /highlevel-pit/products/?locationId={locationId}

Get Product

GET /highlevel-pit/products/{productId}?locationId={locationId}

Note: locationId query parameter is required even for single product retrieval.

Create Product

POST /highlevel-pit/products/
Content-Type: application/json

{
  "locationId": "{locationId}",
  "name": "Digital Course",
  "description": "Online training program",
  "productType": "DIGITAL"
}

Delete Product

DELETE /highlevel-pit/products/{productId}?locationId={locationId}

Invoices

List Invoices

IMPORTANT: Both offset and altId/altType are required.

GET /highlevel-pit/invoices/?altId={locationId}&altType=location&limit=20&offset=0

Get Invoice

GET /highlevel-pit/invoices/{invoiceId}?altId={locationId}&altType=location

Payments

List Orders

GET /highlevel-pit/payments/orders?altId={locationId}&altType=location&limit=20

List Transactions

GET /highlevel-pit/payments/transactions?altId={locationId}&altType=location&limit=20

List Subscriptions

GET /highlevel-pit/payments/subscriptions?altId={locationId}&altType=location&limit=20
GET /highlevel-pit/links/?locationId={locationId}
POST /highlevel-pit/links/
Content-Type: application/json

{
  "locationId": "{locationId}",
  "name": "Survey Link",
  "redirectTo": "https://example.com/survey"
}

Response:

{
  "link": {
    "id": "link123",
    "name": "Survey Link",
    "redirectTo": "https://example.com/survey",
    "fieldKey": "{{trigger_link.link123}}"
  }
}
PUT /highlevel-pit/links/{linkId}
Content-Type: application/json

{
  "name": "Updated Link",
  "redirectTo": "https://updated.com"
}
DELETE /highlevel-pit/links/{linkId}

Workflows

List Workflows

GET /highlevel-pit/workflows/?locationId={locationId}

Campaigns

List Campaigns

GET /highlevel-pit/campaigns/?locationId={locationId}

Forms

List Forms

GET /highlevel-pit/forms/?locationId={locationId}

Surveys

List Surveys

GET /highlevel-pit/surveys/?locationId={locationId}

Funnels

List Funnels

GET /highlevel-pit/funnels/funnel/list?locationId={locationId}

Response:

{
  "funnels": [...],
  "count": 5
}

Social Media

List Accounts

GET /highlevel-pit/social-media-posting/{locationId}/accounts

Response:

{
  "success": true,
  "results": {
    "accounts": [...],
    "groups": [...]
  }
}

List Categories

GET /highlevel-pit/social-media-posting/{locationId}/categories

Media Files

List Files

IMPORTANT: The type parameter is required.

GET /highlevel-pit/medias/files?altId={locationId}&altType=location&type=file&limit=20

Valid type values: file, image, video, audio

Pagination

GoHighLevel uses different pagination styles depending on the endpoint:

Cursor-Based (Contacts)

GET /highlevel-pit/contacts/?locationId={locationId}&limit=20&startAfterId={lastContactId}

Response includes meta.startAfterId for the next page cursor.

Offset-Based (Opportunities, Invoices)

GET /highlevel-pit/opportunities/search?location_id={locationId}&limit=20&page=2
GET /highlevel-pit/invoices/?altId={locationId}&altType=location&limit=20&offset=20

Skip-Based (Locations)

GET /highlevel-pit/locations/search?companyId={companyId}&limit=20&skip=20

Code Examples

JavaScript

const response = await fetch(
  'https://api.maton.ai/highlevel-pit/contacts/?locationId={locationId}&limit=20',
  {
    headers: {
      'Authorization': `Bearer ${process.env.MATON_API_KEY}`,
      'Maton-Connection': '{sub-account-connection-id}'
    }
  }
);
const data = await response.json();

Python

import os
import requests

response = requests.get(
    'https://api.maton.ai/highlevel-pit/contacts/',
    headers={
        'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
        'Maton-Connection': '{sub-account-connection-id}'
    },
    params={'locationId': '{locationId}', 'limit': 20}
)
data = response.json()

Notes

  • Two token types: Agency tokens manage locations; Sub-Account tokens access CRM data within a location. Use the Maton-Connection header to pick the right one.
  • Most Sub-Account endpoints require a locationId query parameter
  • Payment/invoice endpoints use altId and altType=location instead of locationId
  • Social media endpoints put locationId in the URL path, not as a query param
  • Calendar events require startTime/endTime as epoch milliseconds, not ISO-8601
  • Calendar event queries require at least one of calendarId, userId, or groupId
  • Calendar update does NOT accept locationId in the body (returns 422)
  • Product GET requires locationId as a query parameter
  • Contact task creation requires the completed field (boolean)
  • Opportunity update requires pipelineId even when not changing it
  • Invoice list requires offset parameter (use 0 for first page)
  • Media file list requires the type parameter
  • All delete operations return HTTP 200 (not 204)
  • IMPORTANT: When using curl commands, use curl -g when URLs contain brackets to disable glob parsing
  • 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

StatusMeaning
400Bad request or invalid parameters
401Invalid/missing Maton API key, token not authorized for scope, or user type mismatch
403Token does not have access to this location
404Resource not found
422Validation error — check required fields
429Rate limited
4xx/5xxPassthrough error from GoHighLevel API

Common Errors

"The token does not have access to this location" (403): You're using an Agency token for an endpoint that requires a Sub-Account token, or vice versa.

"The token is not authorized for this scope" (401): The token doesn't have the required scope. Agency tokens can't access CRM data; Sub-Account tokens can't manage locations.

"Token's user type mismatch" (401): You're using the wrong token type for this endpoint (e.g., Agency token on a Sub-Account-only endpoint).

"LocationId can't be undefined" (422): You forgot the locationId query parameter.

Resources

Questions people ask

What is the difference between Agency and Sub-Account tokens?
Agency tokens are scoped to managing sub-account locations and snapshots at the agency level. Sub-Account tokens are scoped to a single location and access CRM data such as contacts, pipelines, calendars, conversations, custom fields, tags, and workflows.
How is authentication handled?
Requests authenticate with a Maton API key in the Authorization header; the proxy then injects the stored Private Integration Token, so the PIT itself never appears in calls. When multiple connections exist, the Maton-Connection header selects which PIT to use.
Are write operations allowed without confirmation?
No. The documentation states that all create, update, and delete calls require explicit user approval, with the target resource and intended effect confirmed beforehand.

Related skills

HighLevel (gohighlevel.com). Use this skill for ANY HighLevel request — reading, creating, updating, and deleting data. Whenever a task involves HighLevel, u...

Access the HubSpot CRM API via managed OAuth to manage contacts, companies, deals, and associations.

187 installs5 stars

Manage ActiveCampaign contacts, deals, automations, and campaigns via OAuth with confirmation on every write.

149 installs4 stars

Manage Twenty CRM records—companies, people, opportunities, notes, and tasks—through a proxied REST API with managed auth.

23 installs

Read and write Zoho CRM records through a Maton-managed OAuth proxy, with user confirmation on every create, update, and delete.

463 installs6 stars

Call Brevo's contacts, lists, transactional email, templates, and campaign endpoints through a managed OAuth proxy.

152 installs3 stars