From gohighlevel
This skill manages GoHighLevel (GHL) agency sub-accounts via the API v2 — tags, custom fields/values, calendars, scheduling, products, contacts, and workflows (read/trigger only) with per-client isolation. Use this skill whenever the user mentions "GoHighLevel", "GHL", "HighLevel", "sub-accounts", "client setup in GHL", "create tags for client", "manage calendars in HighLevel", "add products to GHL", "custom fields", "custom values", "GHL API", "client onboarding", "list workflows", "trigger workflow", or any request to read or write data in a GoHighLevel sub-account. Always use this skill for any GHL-related work — do not try to call the GHL API from memory.
How this skill is triggered — by the user, by Claude, or both
Slash command
/gohighlevel:gohighlevelThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
You are helping manage GoHighLevel agency sub-accounts via the GHL API v2. This plugin is built and maintained by Chris Barber at Abiding Agency (abidingagency.com).
You are helping manage GoHighLevel agency sub-accounts via the GHL API v2. This plugin is built and maintained by Chris Barber at Abiding Agency (abidingagency.com).
This skill uses a two-tier token system with per-client isolation:
This separation exists because GHL scopes API permissions differently at the agency vs. sub-account level. Agency tokens can manage locations but cannot access contacts, tags, or calendars. Sub-account tokens have full access to that specific client's data.
Sub-account-only users: If the user does not have agency access (e.g., they only manage a single GHL sub-account), the plugin still works. They skip the agency key, generate a Location-level PIT from their sub-account settings, and configure a single client entry. The only features they lose are agency-level endpoints like /locations/search.
~/.ghl/clients.json to get the client's locationId and tokenVarGHL_AGENCY_API_KEYtokenVar--token flag for client-scoped callsGHL_AGENCY_API_KEY=agency-key-here
# Sub-account tokens (one per client)
GHL_TOKEN_CLIENT_NAME=sub-account-token-here
{
"clients": {
"client-key": {
"name": "Client Display Name",
"locationId": "location-id-from-ghl",
"tokenVar": "GHL_TOKEN_CLIENT_NAME",
"notes": "Optional notes"
}
}
}
If these files don't exist, guide the user through first-time setup (see Setup section below).
Base URL: https://services.leadconnectorhq.com
Required headers on every request:
Authorization: Bearer {token}
Version: 2021-07-28
Content-Type: application/json
Endpoint pattern for sub-account data: GHL's API uses mixed patterns depending on the resource — some use path params, some use query params. This is GHL's design, not a bug:
GET /locations/{locationId}/tags, GET /locations/{locationId}/customFieldsGET /contacts/?locationId={locationId}, GET /workflows?locationId={id}Always check the reference doc for the specific resource to get the correct URL pattern.
Rate limits: 100 requests per 10 seconds, 200,000 per day. Monitor X-RateLimit-Remaining header.
Read references/contacts.md for full endpoint details.
GET /contacts/?locationId={id}&limit=20POST /contacts with locationId in bodyPUT /contacts/{contactId}POST /contacts/{contactId}/tagsRead references/tags.md for full endpoint details.
GET /locations/{locationId}/tagsPOST /locations/{locationId}/tags with name in bodyPOST /contacts/{contactId}/tagsRead references/custom-fields.md for full endpoint details.
GET /locations/{locationId}/customFieldsPOST /locations/{locationId}/customFieldsRead references/workflows.md for full endpoint details.
GET /workflows?locationId={id}GET /workflows/{workflowId}Important: The GHL Workflows API is read and trigger only — you can list workflows and add a contact to a workflow, but you cannot create, edit, or build workflow steps via API. If the user asks to "build an automation" or "create a workflow," direct them to do that in the GHL UI, then you can trigger it or list it here.
Read references/calendars.md for full endpoint details.
GET /calendars?locationId={id}POST /calendarsGET /calendars/{calendarId}/appointmentsRead references/products.md for full endpoint details.
GET /products?locationId={id}POST /productsRead references/locations.md for full endpoint details.
GET /locations/search (agency key, no --token needed)GET /locations/{locationId}Use the helper script for all API calls. For client-scoped calls, always pass --token:
# Agency-level call (uses GHL_AGENCY_API_KEY by default)
bash ${CLAUDE_PLUGIN_ROOT}/skills/gohighlevel/scripts/ghl-api.sh GET "/locations/search"
# Client-scoped call (uses the client's sub-account token)
bash ${CLAUDE_PLUGIN_ROOT}/skills/gohighlevel/scripts/ghl-api.sh GET "/locations/{locationId}/tags" --token GHL_TOKEN_CLIENT_NAME
# POST with body and client token
bash ${CLAUDE_PLUGIN_ROOT}/skills/gohighlevel/scripts/ghl-api.sh POST "/contacts" '{"firstName":"John","locationId":"abc123"}' --token GHL_TOKEN_CLIENT_NAME
# Dry run (preview without sending)
bash ${CLAUDE_PLUGIN_ROOT}/skills/gohighlevel/scripts/ghl-api.sh GET "/locations/{locationId}/tags" --token GHL_TOKEN_CLIENT_NAME --dry-run
# 1. Look up client config
LOCATION_ID=$(jq -r '.clients["client-key"].locationId' ~/.ghl/clients.json)
TOKEN_VAR=$(jq -r '.clients["client-key"].tokenVar' ~/.ghl/clients.json)
# 2. Make the scoped call
bash ${CLAUDE_PLUGIN_ROOT}/skills/gohighlevel/scripts/ghl-api.sh GET "/locations/${LOCATION_ID}/tags" --token "$TOKEN_VAR"
If ~/.ghl/ doesn't exist, walk the user through this:
Create the secure directory:
mkdir -p ~/.ghl && chmod 700 ~/.ghl
Get the Agency API key (agency users): Guide the user to GHL Settings > Business Profile > API Keys. This key manages locations/sub-accounts. Sub-account-only users can skip this step — they won't have agency access and don't need GHL_AGENCY_API_KEY.
Discover sub-accounts: Use the agency key to list all locations.
Create sub-account tokens: For each client, go into that sub-account in GHL > Settings > Integrations > Private Integrations > Create. Enable all scopes. Save the token.
Add tokens to credentials.env — one GHL_TOKEN_ variable per client.
Build clients.json — map each client key to locationId and tokenVar.
Test: Pull tags for a client to verify.
~/.ghl/ directory uses 700 permissions (owner-only access)credentials.env file uses 600 permissions (owner read/write only)clients.json (safe) but NEVER show credentials.env contents/locations/{locationId}/resource pattern.--dry-run to preview any request before sendingGuides creation, editing, and verification of skills for AI coding agents using test-driven development with subagent scenarios. Use when authoring or debugging skills.
npx claudepluginhub ancreon/gohighlevel-plugin --plugin gohighlevel