Skip to content

GHL API Basics

GHL API allows developers connect external systems, automate advanced workflows, build custom integrations.

Co to jest API?

API (Application Programming Interface): Way για software systems να communicate.

Example:

Your app → GHL API → Create contact IN GHL CRM

You send request, GHL responds με data OR confirmation.

Use Cases

1. Custom Integrations: Connect GHL με systems NOT natively integrated:

  • Custom CRM
  • Proprietary tools
  • Industry-specific software

2. Bulk Operations: Programmatically:

  • Import 10,000+ contacts
  • Update custom fields
  • Manage hundreds OF workflows

3. External Dashboards: Pull GHL data INTO custom reporting tools.

4. Webhook Receivers: Build external apps THAT react να GHL events (form submit, opportunity won).

5. White-Label Apps: Agencies build custom client-facing portals using GHL backend.

Prerequisites

1. Developer Knowledge:

  • REST APIs
  • JSON
  • HTTP requests (GET, POST, PUT, DELETE)
  • Programming (Python, JavaScript, PHP, etc.)

NOT developer? Use Zapier/Make.com instead.

2. GHL Account: Agency account (sub-accounts accessible via API).

3. API Key: Authentication token.

Getting API Key

Settings → Integrations → API Key → Generate

Copy + Store Securely:

  • NEJ share publicly
  • NOT commit TO GitHub
  • Treat AS password

Regenerate IF compromised.

Authentication

Method: Bearer Token

In HTTP Headers:

http
Authorization: Bearer YOUR_API_KEY_HERE
Content-Type: application/json

Example (curl):

bash
curl -X GET "https://rest.gohighlevel.com/v1/contacts/" \
  -H "Authorization: Bearer YOUR_API_KEY"

Key Endpoints

Contacts

Get All Contacts:

http
GET /v1/contacts/

Get Specific Contact:

http
GET /v1/contacts/{contactId}

Create Contact:

http
POST /v1/contacts/

Body (JSON):
{
  "firstName": "Jan",
  "lastName": "Kowalski",
  "email": "jan@example.com",
  "phone": "+48123456789",
  "tags": ["api-import", "demo"]
}

Update Contact:

http
PUT /v1/contacts/{contactId}

Body:
{
  "customFields": {
    "budget": "10000"
  }
}

Delete Contact:

http
DELETE /v1/contacts/{contactId}

Opportunities

Create Opportunity:

http
POST /v1/opportunities/

Body:
{
  "contactId": "abc123",
  "pipelineId": "xyz789",
  "pipelineStageId": "stage1",
  "name": "Deal - Jan Kowalski",
  "monetaryValue": 5000,
  "status": "open"
}

Update Opportunity:

http
PUT /v1/opportunities/{opportunityId}

Calendars

Get Appointments:

http
GET /v1/appointments/

Create Appointment:

http
POST /v1/appointments/

Body:
{
  "calendarId": "cal123",
  "contactId": "contact456",
  "startTime": "2026-03-15T10:00:00Z",
  "endTime": "2026-03-15T11:00:00Z",
  "title": "Consultation Call"
}

Workflows

Add Contact να Workflow:

http
POST /v1/workflows/{workflowId}/subscribers

Body:
{
  "contactId": "contact123"
}

Custom Fields

Get Custom Fields:

http
GET /v1/custom-fields/

Update Custom Field:

http
PUT /v1/contacts/{contactId}/customFields

Body:
{
  "budget": "15000",
  "industry": "Real Estate"
}

Webhooks (GHL → Your App)

Reverse flow: GHL sends data TO your application WHEN events happen.

Setting Up Webhook

Settings → Integrations → Webhooks → Add Webhook

Configure:

URL: Your server endpoint:

https://your-app.com/ghl-webhook

Events: Select triggers:

  • Contact created
  • Opportunity updated
  • Form submitted
  • Appointment booked

Secret Key: Verify requests actually FROM GHL (security).

Receiving Webhooks

Example (Node.js/Express):

javascript
app.post('/ghl-webhook', (req, res) => {
  const event = req.body;
  
  console.log('Event type:', event.type);
  console.log('Data:', event.data);
  
  // Process event (save TO DB, trigger action, etc.)
  
  res.sendStatus(200); // Acknowledge receipt
});

GHL expects 200 response within 30 seconds (OR retries).

Rate Limits

GHL API limits requests:

  • Agency Level: ~10,000 requests/hour
  • Sub-Account Level: ~1,000 requests/hour

Exceeding limit = 429 error (Too Many Requests).

Best practice:

  • Cache data locally
  • Batch requests WHERE possible
  • Implement retry logic με exponential backoff

Error Handling

HTTP Status Codes:

  • 200 OK: Success
  • 201 Created: Resource created
  • 400 Bad Request: Invalid data sent
  • 401 Unauthorized: Invalid API key
  • 404 Not Found: Resource doesn't exist
  • 429 Too Many Requests: Rate limit exceeded
  • 500 Internal Server Error: GHL issue (retry later)

Example Error Response:

json
{
  "error": "Contact με email already exists",
  "code": "DUPLICATE_EMAIL"
}

Example Use Case: Sync External CRM

Scenario: Every hour, sync contacts FROM external CRM να GHL.

Steps:

  1. Fetch contacts FROM external CRM (their API)
  2. For EACH contact:
    • Check IF exists IN GHL (search БИ email)
    • IF exists → Update (PUT /v1/contacts/{id})
    • IF NOT → Create (POST /v1/contacts/)
  3. Log results (success, errors)

Pseudo-code:

python
import requests

GHL_API_KEY = "your_api_key"
GHL_BASE_URL = "https://rest.gohighlevel.com/v1"

headers = {
    "Authorization": f"Bearer {GHL_API_KEY}",
    "Content-Type": "application/json"
}

# Fetch contacts FROM external CRM
external_contacts = fetch_from_external_crm()

for contact IN external_contacts:
    # Check IF contact exists
    search_url = f"{GHL_BASE_URL}/contacts/search?email={contact['email']}"
    response = requests.get(search_url, headers=headers)
    
    IF response.status_code == 200 AND response.json()['contacts']:
        # Update existing
        contact_id = response.json()['contacts'][0]['id']
        update_url = f"{GHL_BASE_URL}/contacts/{contact_id}"
        requests.put(update_url, headers=headers, json=contact)
    ELSE:
        # Create new
        create_url = f"{GHL_BASE_URL}/contacts/"
        requests.post(create_url, headers=headers, json=contact)

Resources

Official API Docs:https://highlevel.stoplight.io/

Community: GHL Facebook Groups, forums.

Tools:

  • Postman (test API requests)
  • Insomnia (alternative)
  • GHL API Playground (IF available)

Best Practices

Test IN Sandbox: Use test sub-account (NOT production).

Error Logging: Log ALL API responses FOR debugging.

Retry Logic: Implement retries FOR 5xx errors.

Secure Keys: Environment variables, NOT hardcoded.

Polling Excessively: Use webhooks instead OF constant polling.

Troubleshooting

Problem: 401 Unauthorized

  • API key correct?
  • Key regenerated recently? (old key invalid)
  • Authorization header formatted correctly?

Problem: 400 Bad Request

  • Check request body (JSON valid?)
  • Required fields missing?
  • Data types correct? (string vs number)

Problem: 429 Rate Limit

  • Too many requests
  • Implement delays between calls
  • Cache data locally

Podsumowanie

GHL API = programmatic access να ALL platform features. Developers unlock endless customization + automation.

Key points:

  • REST API με Bearer token authentication
  • Endpoints FOR contacts, opportunities, appointments, workflows
  • Webhooks FOR real-time event notifications
  • Rate limits exist (respect them)
  • Test thoroughly before production

Next tutorial (#97): Zapier integration basics.