GoHighLevel API
Contact management, custom fields, tags, and write-back patterns for the GHL integration.
| Property | Value |
|---|
| Base URL | https://services.leadconnectorhq.com |
| Auth | Authorization: Bearer <GHL_ACCESS_TOKEN> |
| Version header | Version: 2021-07-28 |
| Location ID | VXhSATpOGAvRAnd0iu7x |
| Contacts | 51 total |
| Custom fields | 190 defined |
Current Token Scopes
| Scope | Access |
|---|
| 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 definitionsKey Custom Fields
| Field Key | Type | Purpose |
|---|
contact.user_id | TEXT | Junction user ID link |
contact.membership_status | SINGLE_OPTIONS | Active / inactive |
contact.call_notes | LARGE_TEXT | AI summary — written by pipeline |
contact.blood_work_purchased | SINGLE_OPTIONS | Whether bloodwork ordered |
contact.blood_work_purchase_date | DATE | When bloodwork purchased |
contact.select_bloodwork__any_documents__pdf_or_image | FILE_UPLOAD | Uploaded 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})