Internal documentation — not for public distribution
Protocol Health Club © 2026

GoHighLevel API

Contact management, custom fields, tags, and write-back patterns for the GHL integration.

PropertyValue
Base URLhttps://services.leadconnectorhq.com
AuthAuthorization: Bearer <GHL_ACCESS_TOKEN>
Version headerVersion: 2021-07-28
Location IDVXhSATpOGAvRAnd0iu7x
Contacts51 total
Custom fields190 defined

Current Token Scopes

ScopeAccess
Contacts read/write✅ Full
Location custom fields✅ Read
Opportunities / Pipelines❌ Not authorized
Calendars / Conversations❌ Not authorized
Workflows / Campaigns❌ Not authorized

Key Endpoints

GET  /contacts/?locationId={id}&limit=20   List contacts (cursor pagination)
GET  /contacts/{id}                         Single contact full detail
PUT  /contacts/{id}                         Update contact fields
POST /contacts/{id}/tags                    Add tags
DELETE /contacts/{id}/tags                  Remove tags
POST /contacts/{id}/notes                   Create note
GET  /locations/{id}/customFields           List all 190 custom field definitions

Key Custom Fields

Field KeyTypePurpose
contact.user_idTEXTJunction user ID link
contact.membership_statusSINGLE_OPTIONSActive / inactive
contact.call_notesLARGE_TEXTAI summary — written by pipeline
contact.blood_work_purchasedSINGLE_OPTIONSWhether bloodwork ordered
contact.blood_work_purchase_dateDATEWhen bloodwork purchased
contact.select_bloodwork__any_documents__pdf_or_imageFILE_UPLOADUploaded blood PDF

Tag Lifecycle

Write-Back Pattern

headers = {
    "Authorization": f"Bearer {GHL_TOKEN}",
    "Version": "2021-07-28",
    "Content-Type": "application/json",
}

# 1. Update call_notes
requests.put(f"{base}/contacts/{contact_id}", headers=headers, json={
    "customFields": [
        { "key": "contact.call_notes", "field_value": ai_summary }
    ]
})

# 2. Swap tags
requests.post(f"{base}/contacts/{contact_id}/tags", headers=headers,
    json={"tags": ["bloodwork_completed"]})
requests.delete(f"{base}/contacts/{contact_id}/tags", headers=headers,
    json={"tags": ["bloodwork_scheduled"]})

# 3. Create note with full analysis
requests.post(f"{base}/contacts/{contact_id}/notes", headers=headers,
    json={"body": full_analysis_text})