Skip to main content

GoHighLevel (GHL) Overview

GoHighLevel is the execution layer for all outbound calling in Client Portal. It manages phone dialing, call recording, transcript generation, and BDR workflow automation. Client Portal integrates bidirectionally: pushing prospects into GHL for calling, and pulling call data back via webhooks and API.

API Configuration

SettingValue
API Base URLhttps://services.leadconnectorhq.com
API Version2021-07-28
AuthBearer token (per-location)
Version HeaderVersion: 2021-07-28
const headers = {
Authorization: `Bearer ${apiToken}`,
Version: "2021-07-28",
Accept: "application/json",
};

Architecture

GHL operates on a location-based model. Each GHL "location" represents an isolated account with its own contacts, workflows, and API token. Client Portal maps these locations to either internal sales operations or client campaigns via the ghl_integrations table.

ghl_integrations Table

ColumnTypeDescription
idUUIDPrimary key
location_idTEXTGHL location ID (unique)
api_tokenTEXTBearer token for this location
integration_typeTEXTinternal or client
client_idUUIDFK to clients (null for internal)
custom_field_mappingJSONBMaps our fields to GHL custom field IDs
is_activeBOOLEANWhether this integration is live
last_synced_atTIMESTAMPTZLast successful sync timestamp
last_sync_statusTEXTsuccess, partial, or failed
last_sync_errorTEXTError details from last sync

Integration Types

TypePurposeDestination Tables
internal1HR's own sales prospectingsales_prospects, sales_calls
clientClient campaign callingcontacts, calls

Integration Flow

Bidirectional Data Flow

Outbound: Client Portal to GHL

  1. Prospect Sync (sync-prospects-to-ghl): Pushes unsynced sales_prospects to GHL as contacts. Maps custom fields (LinkedIn, job title, market name, cadence tracking). Stores ghl_contact_id back on the prospect.

  2. Custom Field Mapping: Each GHL location has its own custom field IDs. The custom_field_mapping JSONB column on ghl_integrations maps logical field names to GHL field IDs:

{
"linkedin_url": "GHL_FIELD_ID_1",
"job_title": "GHL_FIELD_ID_2",
"market_name": "GHL_FIELD_ID_3",
"cadence_stage": "GHL_FIELD_ID_4",
"dial_attempts": "GHL_FIELD_ID_5",
"no_answer_count": "GHL_FIELD_ID_6",
"voicemail_count": "GHL_FIELD_ID_7",
"callback_attempts": "GHL_FIELD_ID_8"
}

Inbound: GHL to Client Portal

  1. Webhooks (ghl-call-webhook): GHL workflows fire webhook payloads on call completion and BDR disposition selection. The webhook handler normalizes the payload, identifies the integration type, enriches via GHL API, and routes to the correct table.

  2. Batch Import (pull-from-ghl): Paginates through all contacts in a GHL location, stages them in ghl_import_staging, fetches call history via the Conversations API, runs duplicate detection, and presents for review.

GHL API Endpoints Used

EndpointMethodPurpose
/contacts/POSTCreate new contact
/contacts/?locationId=...GETList contacts (paginated)
/conversations/search?contactId=...GETFind conversations for a contact
/conversations/{id}/messagesGETGet messages in a conversation
/conversations/locations/{id}/messages/{id}/transcription/downloadGETDownload call transcript

Environment Secrets

SecretDescription
SUPABASE_URLSupabase project URL
SUPABASE_SERVICE_ROLE_KEYService role key for DB access
ANTHROPIC_API_KEYFor AI call summarization (auto-triggered)
API Token Security

GHL API tokens are stored in ghl_integrations.api_token. These are sensitive credentials -- never expose them in client-side code. All GHL API calls happen exclusively in Supabase edge functions using the service role key.